from flask import Blueprint, request, jsonify
from src.models.user import db, User
from src.utils.user_ref import resolve_user_ref
from src.models.chat import ChatRoom, ChatMessage, ChatParticipant
from datetime import datetime

chat_bp = Blueprint('chat', __name__)

@chat_bp.route('/chat/rooms', methods=['GET'])
def get_chat_rooms():
    """채팅방 목록 조회"""
    try:
        user_id = request.args.get('user_id', type=str)
        if not user_id:
            return jsonify({'error': 'user_id is required'}), 400
        
        # 사용자가 참여한 채팅방 목록
        participations = ChatParticipant.query.filter_by(user_id=user_id).all()
        rooms = []
        
        for participation in participations:
            room_data = participation.room.to_dict()
            # 1:1 채팅방인 경우 상대방 정보 추가
            if participation.room.is_private:
                other_participant = ChatParticipant.query.filter(
                    ChatParticipant.room_id == participation.room_id,
                    ChatParticipant.user_id != user_id
                ).first()
                if other_participant:
                    room_data['other_user'] = other_participant.user.username
            rooms.append(room_data)
        
        return jsonify(rooms)
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@chat_bp.route('/chat/rooms', methods=['POST'])
def create_chat_room():
    """채팅방 생성"""
    try:
        data = request.get_json()
        
        # 필수 필드 검증
        if 'participants' not in data or len(data['participants']) < 2:
            return jsonify({'error': 'At least 2 participants required'}), 400

        participant_ids = []
        for rid in data['participants']:
            u = resolve_user_ref(rid)
            if not u:
                return jsonify({'error': f'User {rid} not found'}), 404
            participant_ids.append(u.user_id)
        
        # 1:1 채팅방인지 확인
        is_private = len(participant_ids) == 2
        
        # 1:1 채팅방이 이미 존재하는지 확인
        if is_private:
            existing_room = db.session.query(ChatRoom).join(ChatParticipant).filter(
                ChatRoom.is_private == True,
                ChatParticipant.user_id.in_(participant_ids)
            ).group_by(ChatRoom.id).having(
                db.func.count(ChatParticipant.user_id) == 2
            ).first()
            
            if existing_room:
                return jsonify(existing_room.to_dict())
        
        # 새 채팅방 생성
        room = ChatRoom(
            name=data.get('name'),
            is_private=is_private
        )
        db.session.add(room)
        db.session.flush()  # ID 생성을 위해
        
        # 참여자 추가
        for pid in participant_ids:
            participant = ChatParticipant(
                room_id=room.id,
                user_id=pid,
            )
            db.session.add(participant)
        
        db.session.commit()
        return jsonify(room.to_dict()), 201
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500

@chat_bp.route('/chat/rooms/<int:room_id>/messages', methods=['GET'])
def get_messages(room_id):
    """채팅방 메시지 조회"""
    try:
        room = ChatRoom.query.get_or_404(room_id)
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 50, type=int)
        
        messages = ChatMessage.query.filter_by(room_id=room_id).order_by(
            ChatMessage.created_at.desc()
        ).paginate(page=page, per_page=per_page, error_out=False)
        
        return jsonify({
            'messages': [msg.to_dict() for msg in reversed(messages.items)],
            'total': messages.total,
            'pages': messages.pages,
            'current_page': page
        })
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@chat_bp.route('/chat/rooms/<int:room_id>/messages', methods=['POST'])
def send_message(room_id):
    """메시지 전송"""
    try:
        room = ChatRoom.query.get_or_404(room_id)
        data = request.get_json()
        
        # 필수 필드 검증
        required_fields = ['sender_id', 'content']
        for field in required_fields:
            if field not in data:
                return jsonify({'error': f'{field} is required'}), 400
        
        sender = resolve_user_ref(data['sender_id'])
        if not sender:
            return jsonify({'error': 'Sender not found'}), 404
        sid = sender.user_id
        # 참여자 확인
        participant = ChatParticipant.query.filter_by(
            room_id=room_id,
            user_id=sid,
        ).first()
        if not participant:
            return jsonify({'error': 'User is not a participant of this room'}), 403
        
        message = ChatMessage(
            room_id=room_id,
            sender_id=sid,
            content=data['content'],
            message_type=data.get('message_type', 'text'),
            file_url=data.get('file_url')
        )
        
        db.session.add(message)
        db.session.commit()
        
        return jsonify(message.to_dict()), 201
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500

@chat_bp.route('/chat/public-rooms', methods=['GET'])
def get_public_rooms():
    """공개 채팅방 목록"""
    try:
        rooms = ChatRoom.query.filter_by(is_private=False).order_by(
            ChatRoom.created_at.desc()
        ).all()
        
        return jsonify([room.to_dict() for room in rooms])
    except Exception as e:
        return jsonify({'error': str(e)}), 500

@chat_bp.route('/chat/rooms/<int:room_id>/join', methods=['POST'])
def join_room(room_id):
    """채팅방 참여"""
    try:
        room = ChatRoom.query.get_or_404(room_id)
        data = request.get_json()
        
        if 'user_id' not in data:
            return jsonify({'error': 'user_id is required'}), 400
        
        join_user = resolve_user_ref(data['user_id'])
        if not join_user:
            return jsonify({'error': 'User not found'}), 404
        jid = join_user.user_id

        # 이미 참여 중인지 확인
        existing = ChatParticipant.query.filter_by(
            room_id=room_id,
            user_id=jid,
        ).first()
        if existing:
            return jsonify({'message': 'Already joined'})
        
        participant = ChatParticipant(
            room_id=room_id,
            user_id=jid,
        )
        db.session.add(participant)
        db.session.commit()
        
        return jsonify({'message': 'Joined successfully'})
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500

