"""NPC chat routes backed by Azure AI service."""
import uuid
from typing import Any, Dict

from flask import Blueprint, request, session
from flask_restx import Api, Resource, fields

from models.user import User
from models.quest import Quest, db
from services.npc_chat_service import NpcChatService

npc_chat_bp = Blueprint('npc_chat', __name__, url_prefix='/api')
npc_chat_api = Api(npc_chat_bp, doc=False, prefix='/chat')

chat_start_model = npc_chat_api.model('ChatStartRequest', {
    'character': fields.String(required=False, description='frodo|sam|gandalf'),
})

chat_message_model = npc_chat_api.model('ChatMessageRequest', {
    'character': fields.String(required=False, description='frodo|sam|gandalf'),
    'message': fields.String(required=True, description='User message'),
})

quest_creation_model = npc_chat_api.model('QuestCreationRequest', {
    'character': fields.String(required=False, description='frodo|sam|gandalf - NPC who proposes the quest'),
    'title': fields.String(required=True, description='Quest title'),
    'description': fields.String(required=True, description='Quest description'),
    'quest_type': fields.String(required=True, description='Quest type (The Journey, The Battle, The Fellowship, The Ring, Dark Magic)'),
    'priority': fields.String(required=True, description='Quest priority (Critical, Important, Standard)'),
})


def _require_auth() -> bool:
    return session.get('user_id') is not None


def _get_current_user() -> User:
    user_id = session.get('user_id')
    return User.query.get(user_id)


def _get_chat_scope_id() -> str:
    scope_id = session.get('chat_scope_id')
    if not scope_id:
        scope_id = uuid.uuid4().hex
        session['chat_scope_id'] = scope_id
    return scope_id


@npc_chat_api.route('/start')
class ChatStart(Resource):
    @npc_chat_api.expect(chat_start_model)
    def post(self) -> tuple[Dict[str, Any], int]:
        if not _require_auth():
            return {'error': 'Authentication required'}, 401

        user = _get_current_user()
        if not user:
            return {'error': 'User not found'}, 404

        data = request.get_json() or {}
        scope_id = _get_chat_scope_id()
        payload = NpcChatService.start_conversation(
            user_id=user.id,
            username=user.username,
            character=data.get('character'),
            scope_id=scope_id,
        )
        return payload, 200


@npc_chat_api.route('/message')
class ChatMessage(Resource):
    @npc_chat_api.expect(chat_message_model)
    def post(self) -> tuple[Dict[str, Any], int]:
        if not _require_auth():
            return {'error': 'Authentication required'}, 401

        user = _get_current_user()
        if not user:
            return {'error': 'User not found'}, 404

        data = request.get_json() or {}
        message = (data.get('message') or '').strip()
        if not message:
            return {'error': 'message is required'}, 400

        scope_id = _get_chat_scope_id()
        payload = NpcChatService.send_message(
            user_id=user.id,
            username=user.username,
            character=data.get('character'),
            user_message=message,
            scope_id=scope_id,
        )
        return payload, 200


@npc_chat_api.route('/session')
class ChatSession(Resource):
    def get(self) -> tuple[Dict[str, Any], int]:
        if not _require_auth():
            return {'error': 'Authentication required'}, 401

        user = _get_current_user()
        if not user:
            return {'error': 'User not found'}, 404

        character = request.args.get('character')
        scope_id = _get_chat_scope_id()
        payload = NpcChatService.get_session(user_id=user.id, character=character, scope_id=scope_id)
        return payload, 200


@npc_chat_api.route('/reset')
class ChatReset(Resource):
    @npc_chat_api.expect(chat_start_model)
    def post(self) -> tuple[Dict[str, Any], int]:
        if not _require_auth():
            return {'error': 'Authentication required'}, 401

        user = _get_current_user()
        if not user:
            return {'error': 'User not found'}, 404

        data = request.get_json() or {}
        scope_id = _get_chat_scope_id()
        payload = NpcChatService.reset_session(user_id=user.id, character=data.get('character'), scope_id=scope_id)
        return payload, 200


@npc_chat_api.route('/create_quest')
class ChatCreateQuest(Resource):
    """Create a quest from NPC chat interaction."""
    
    @npc_chat_api.expect(quest_creation_model)
    def post(self) -> tuple[Dict[str, Any], int]:
        """Create a quest proposed by an NPC.
        
        This endpoint allows the frontend to persist a suggested quest
        that was generated during NPC chat.
        """
        if not _require_auth():
            return {'error': 'Authentication required'}, 401

        user = _get_current_user()
        if not user:
            return {'error': 'User not found'}, 404

        data = request.get_json() or {}
        
        # Validate required fields
        required_fields = ['title', 'description', 'quest_type', 'priority']
        if not all(data.get(field) for field in required_fields):
            return {'error': 'Missing required fields: title, description, quest_type, priority'}, 400

        # Create the quest
        quest = Quest(
            title=data.get('title'),
            description=data.get('description'),
            quest_type=data.get('quest_type'),
            priority=data.get('priority'),
            is_dark_magic=data.get('is_dark_magic', False),
            assigned_to=user.id,
            location_id=data.get('location_id'),
        )
        
        db.session.add(quest)
        db.session.commit()
        
        return {
            'quest': quest.to_dict(),
            'message': f'{data.get("character", "An NPC")} has created a quest for you!',
        }, 201
