import logging

from sqlalchemy import text
from typing import Optional, Literal
from fastapi import APIRouter, Query
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(limit: int = Query(10, le=10), offset: int = Query(0, ge=0)) -> ResponseWrapper[dict]:
    async with get_async_db() as db:
        result = await db.execute(
            text("""
                SELECT 
                    id AS conversation_id,
                    first_message,
                    created_at,
                    updated_at
                FROM conversations
                ORDER BY updated_at DESC
                LIMIT :limit
                OFFSET :offset;
            """),
            {"limit": limit, "offset": offset}
        )

        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,
            "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.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,
            "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):

    args.conversation_id = await save_conversation(args.conversation_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)