"""
Chat API Endpoints.

Provides REST API for accessing player-NPC conversation history,
searching messages, and managing chat data.
"""

from flask import Blueprint, request
from datetime import datetime, timezone

from app.utils.auth import require_auth, get_current_user
from app.services.chat_message_service import (
    get_chat_message_service,
    ChatMessageNotFound,
    ChatMessagePermissionDenied
)
from app.services.npc_loader import get_npc_loader
from app.models.chat_message import MessageContext
from app.utils.response import (
    success_response,
    error_response,
    not_found_response,
    validation_error_response
)
from app.utils.logging import get_logger

logger = get_logger(__file__)

chat_bp = Blueprint('chat', __name__)


@chat_bp.route('/api/v1/characters/<character_id>/chats', methods=['GET'])
@require_auth
def get_conversations_summary(character_id: str):
    """
    Get summary of all NPC conversations for a character.

    Returns list of NPCs the character has talked to, with message counts,
    last message timestamp, and preview of most recent exchange.

    Path params:
        character_id: Character ID

    Query params:
        None

    Returns:
        JSON response with list of conversation summaries
    """
    try:
        user = get_current_user()

        # Get conversation summaries
        chat_service = get_chat_message_service()
        summaries = chat_service.get_all_conversations_summary(character_id, user.id)

        # Convert to dict for JSON response
        conversations = [summary.to_dict() for summary in summaries]

        logger.info("Retrieved conversation summaries",
                   user_id=user.id,
                   character_id=character_id,
                   count=len(conversations))

        return success_response({"conversations": conversations})

    except ChatMessagePermissionDenied as e:
        logger.warning("Permission denied getting conversations",
                      user_id=user.id if 'user' in locals() else None,
                      character_id=character_id)
        return error_response(str(e), 403)
    except Exception as e:
        logger.error("Failed to get conversations summary",
                    character_id=character_id,
                    error=str(e))
        return error_response(f"Failed to retrieve conversations: {str(e)}", 500)


@chat_bp.route('/api/v1/characters/<character_id>/chats/<npc_id>', methods=['GET'])
@require_auth
def get_conversation_history(character_id: str, npc_id: str):
    """
    Get full conversation history between character and specific NPC.

    Returns paginated list of messages ordered by timestamp DESC (most recent first).

    Path params:
        character_id: Character ID
        npc_id: NPC ID

    Query params:
        limit: Maximum messages to return (default 50, max 100)
        offset: Number of messages to skip (default 0)

    Returns:
        JSON response with messages and pagination info
    """
    try:
        user = get_current_user()

        # Get query parameters
        limit = request.args.get('limit', 50, type=int)
        offset = request.args.get('offset', 0, type=int)

        # Validate parameters
        if limit < 1:
            return validation_error_response("limit must be at least 1")
        if offset < 0:
            return validation_error_response("offset must be at least 0")

        # Get conversation history
        chat_service = get_chat_message_service()
        messages = chat_service.get_conversation_history(
            character_id=character_id,
            user_id=user.id,
            npc_id=npc_id,
            limit=limit,
            offset=offset
        )

        # Get NPC name if available
        npc_loader = get_npc_loader()
        npc = npc_loader.load_npc(npc_id)
        npc_name = npc.name if npc else npc_id.replace('_', ' ').title()

        # Convert messages to dict
        message_dicts = [msg.to_dict() for msg in messages]

        result = {
            "npc_id": npc_id,
            "npc_name": npc_name,
            "total_messages": len(messages),  # Count in this batch
            "messages": message_dicts,
            "pagination": {
                "limit": limit,
                "offset": offset,
                "has_more": len(messages) == limit  # If we got a full batch, there might be more
            }
        }

        logger.info("Retrieved conversation history",
                   user_id=user.id,
                   character_id=character_id,
                   npc_id=npc_id,
                   count=len(messages))

        return success_response(result)

    except ChatMessagePermissionDenied as e:
        logger.warning("Permission denied getting conversation",
                      user_id=user.id if 'user' in locals() else None,
                      character_id=character_id,
                      npc_id=npc_id)
        return error_response(str(e), 403)
    except Exception as e:
        logger.error("Failed to get conversation history",
                    character_id=character_id,
                    npc_id=npc_id,
                    error=str(e))
        return error_response(f"Failed to retrieve conversation: {str(e)}", 500)


@chat_bp.route('/api/v1/characters/<character_id>/chats/search', methods=['GET'])
@require_auth
def search_messages(character_id: str):
    """
    Search messages by text with optional filters.

    Query params:
        q (required): Search text to find in player_message and npc_response
        npc_id (optional): Filter by specific NPC
        context (optional): Filter by message context (dialogue, quest_offered, shop, etc.)
        date_from (optional): Start date ISO format (e.g., 2025-11-25T00:00:00Z)
        date_to (optional): End date ISO format
        limit (optional): Maximum messages to return (default 50, max 100)
        offset (optional): Number of messages to skip (default 0)

    Returns:
        JSON response with matching messages
    """
    try:
        user = get_current_user()

        # Get query parameters
        search_text = request.args.get('q')
        npc_id = request.args.get('npc_id')
        context_str = request.args.get('context')
        date_from = request.args.get('date_from')
        date_to = request.args.get('date_to')
        limit = request.args.get('limit', 50, type=int)
        offset = request.args.get('offset', 0, type=int)

        # Validate required parameters
        if not search_text:
            return validation_error_response("q (search text) is required")

        # Validate optional parameters
        if limit < 1:
            return validation_error_response("limit must be at least 1")
        if offset < 0:
            return validation_error_response("offset must be at least 0")

        # Parse context enum if provided
        context = None
        if context_str:
            try:
                context = MessageContext(context_str)
            except ValueError:
                valid_contexts = [c.value for c in MessageContext]
                return validation_error_response(
                    f"Invalid context. Must be one of: {', '.join(valid_contexts)}"
                )

        # Search messages
        chat_service = get_chat_message_service()
        messages = chat_service.search_messages(
            character_id=character_id,
            user_id=user.id,
            search_text=search_text,
            npc_id=npc_id,
            context=context,
            date_from=date_from,
            date_to=date_to,
            limit=limit,
            offset=offset
        )

        # Convert messages to dict
        message_dicts = [msg.to_dict() for msg in messages]

        result = {
            "search_text": search_text,
            "filters": {
                "npc_id": npc_id,
                "context": context_str,
                "date_from": date_from,
                "date_to": date_to
            },
            "total_results": len(messages),
            "messages": message_dicts,
            "pagination": {
                "limit": limit,
                "offset": offset,
                "has_more": len(messages) == limit
            }
        }

        logger.info("Search completed",
                   user_id=user.id,
                   character_id=character_id,
                   search_text=search_text,
                   results=len(messages))

        return success_response(result)

    except ChatMessagePermissionDenied as e:
        logger.warning("Permission denied searching messages",
                      user_id=user.id if 'user' in locals() else None,
                      character_id=character_id)
        return error_response(str(e), 403)
    except Exception as e:
        logger.error("Failed to search messages",
                    character_id=character_id,
                    error=str(e))
        return error_response(f"Search failed: {str(e)}", 500)


@chat_bp.route('/api/v1/characters/<character_id>/chats/<message_id>', methods=['DELETE'])
@require_auth
def delete_message(character_id: str, message_id: str):
    """
    Soft delete a message (sets is_deleted=True).

    Used for privacy/moderation. Message remains in database but filtered from queries.

    Path params:
        character_id: Character ID (for ownership validation)
        message_id: Message ID to delete

    Returns:
        JSON response with success confirmation
    """
    try:
        user = get_current_user()

        # Soft delete message
        chat_service = get_chat_message_service()
        success = chat_service.soft_delete_message(
            message_id=message_id,
            character_id=character_id,
            user_id=user.id
        )

        logger.info("Message deleted",
                   user_id=user.id,
                   character_id=character_id,
                   message_id=message_id)

        return success_response({
            "message_id": message_id,
            "deleted": success
        })

    except ChatMessageNotFound as e:
        logger.warning("Message not found for deletion",
                      message_id=message_id,
                      character_id=character_id)
        return not_found_response(str(e))
    except ChatMessagePermissionDenied as e:
        logger.warning("Permission denied deleting message",
                      user_id=user.id if 'user' in locals() else None,
                      character_id=character_id,
                      message_id=message_id)
        return error_response(str(e), 403)
    except Exception as e:
        logger.error("Failed to delete message",
                    message_id=message_id,
                    character_id=character_id,
                    error=str(e))
        return error_response(f"Delete failed: {str(e)}", 500)
