import logging

from sqlalchemy import text
from typing import Optional, Literal
from fastapi import APIRouter, Query, Request
from pydantic import BaseModel

from app.exceptions.http import HTTPException
from app.schemas import ResponseWrapper
from app.utils.store_conversation import save_conversation, save_conversation_feedback
from app.models.connection import get_async_db

router = APIRouter()

logger = logging.getLogger(__name__)

class SaveConversationRequest(BaseModel):
    conversation_id: Optional[str] = None
    question: Optional[str] = None
    answer: Optional[str] = None
    customer_id: Optional[str] = None


class RateConversationRequest(BaseModel):
    conversation_id: str
    feedback: Literal["up", "down"]

@router.get(
    "/conversations",
    tags=["Conversations"],
    response_model=ResponseWrapper[dict],
    summary="Get all conversations",
    status_code=200,
)
async def get_all_conversations(request: Request, limit: int = Query(10, le=30), offset: int = Query(0, ge=0)) -> ResponseWrapper[dict]:
    
    hotel_id = request.state.HOTEL_ID
    sub_hotel_id = request.state.SUB_HOTEL_ID

    search_params = {
        "hotel_id": hotel_id,
        "limit": limit,
        "offset": offset
    }

    if sub_hotel_id:
        search_params["sub_hotel_id"] = sub_hotel_id

    async with get_async_db() as db:
        result = await db.execute(
            text("""
                SELECT 
                    id AS conversation_id,
                    first_message,
                    metadata,
                    created_at,
                    updated_at
                FROM conversations
                WHERE hotel_id = :hotel_id"""+ (""" AND sub_hotel_id = :sub_hotel_id""" if sub_hotel_id else "") + """
                ORDER BY updated_at DESC
                LIMIT :limit
                OFFSET :offset;
            """),
            search_params
        )

        rows = result.fetchall()

        if not rows:
            return ResponseWrapper(
                status=True,
                message="No conversations found",
                data={"conversations": []}
            )

    conversations = [
        {
            "conversation_id": row.conversation_id,
            "first_message": row.first_message,
            "metadata": row.metadata,
            "created_at": row.created_at.isoformat() if row.created_at else None,
            "updated_at": row.updated_at.isoformat() if row.updated_at else None,
        }
        for row in rows
    ]

    return ResponseWrapper(
        status=True,
        message="OK",
        data={"conversations": conversations}
    )


@router.get(
    "/conversations/{conversation_id}",
    tags=["Conversation"],
    response_model=ResponseWrapper[dict],
    summary="Get conversation",
    status_code=200,
)
async def get_conversation(conversation_id: str) -> ResponseWrapper[dict]:
    async with get_async_db() as db:
        result = await db.execute(
            text("""
                SELECT 
                    c.id AS conversation_id,
                    m.customer_id,
                    m.message,
                    m.role,
                    m.feedback,
                    m.created_at,
                    m.updated_at
                FROM conversations c
                LEFT JOIN messages m 
                    ON m.conversation_id = c.id
                WHERE c.id = :id
                ORDER BY m.created_at ASC;
            """),
            {"id": conversation_id}
        )

        rows = result.fetchall()

        if not rows:
            raise HTTPException(status_code=404, detail="Conversation not found")

    # Extract base info
    conv_id = rows[0].conversation_id
    customer_id = next((r.customer_id for r in rows if r.customer_id), None)

    # Build messages list
    messages = [
        {
            "role": row.role,
            "text": row.message,
            "feedback": row.feedback,
            "created_at": row.created_at,
            "updated_at": row.updated_at
        }
        for row in rows if row.message is not None
    ]

    response_data = {
        "conversation_id": conv_id,
        "customer_id": customer_id,
        "messages": messages
    }

    return ResponseWrapper(status=True, message="OK", data=response_data)

@router.post(
    "/save/conversation",
    tags=["Conversation"],
    response_model=ResponseWrapper[str | None],
    summary="Save conversation",
    status_code=200,
)
async def save_conversations(args: SaveConversationRequest, request: Request):

    args.conversation_id = await save_conversation(args.conversation_id, request.state.HOTEL_ID, request.state.SUB_HOTEL_ID, args.question, args.answer, args.customer_id)

    return ResponseWrapper(status=True, message="OK", data=args.conversation_id)

@router.post(
    "/rate/conversation",
    tags=["Conversation"],
    response_model=ResponseWrapper[None],
    summary="Save thumbs up/down feedback for latest AI response",
    status_code=200,
)
async def rate_conversation(args: RateConversationRequest) -> ResponseWrapper[None]:

    saved = await save_conversation_feedback(
        conversation_id=args.conversation_id,
        feedback=args.feedback,
    )
    if not saved:
        raise HTTPException(status_code=500, detail="Failed to save feedback")

    return ResponseWrapper(status=True, message="OK", data=None)