import uuid
from datetime import datetime
from typing import Optional
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, desc

from app.domain.models import (
    ThreadCreateRequest, ThreadCreatedResponse,
    MessageCreateRequest, MessageListResponse, MessageDto,
    SenderRole,
)
from app.adapters.orm import Thread, Message

async def create_thread(
    document_id: uuid.UUID,
    req: ThreadCreateRequest,
    session: AsyncSession,
    citizen_id: str,
) -> ThreadCreatedResponse:
    thread = Thread(
        document_id=document_id,
        type=req.type,
        assigned_official_id=None,
    )
    session.add(thread)
    await session.flush()

    if req.initialMessage:
        msg = Message(
            thread_id=thread.id,
            sender_role=SenderRole.CITIZEN,
            content_blob=req.initialMessage,
        )
        session.add(msg)

    await session.commit()
    await session.refresh(thread)

    return ThreadCreatedResponse(
        threadId=str(thread.id),
        status="PENDING_OFFICIAL",
        estimatedWaitTime="4h",
    )

async def add_message(
    thread_id: uuid.UUID,
    req: MessageCreateRequest,
    session: AsyncSession,
    sender_role: SenderRole,
) -> MessageDto:
    msg = Message(
        thread_id=thread_id,
        sender_role=sender_role,
        content_blob=req.content,
    )
    session.add(msg)

    stmt_thread = select(Thread).where(Thread.id == thread_id)
    res = await session.execute(stmt_thread)
    thread = res.scalar_one()
    thread.last_activity_at = datetime.utcnow()

    await session.commit()
    await session.refresh(msg)

    return MessageDto(
        id=str(msg.id),
        senderRole=msg.sender_role,
        content=msg.content_blob,
        timestamp=msg.created_at,
    )

async def list_messages(
    thread_id: uuid.UUID,
    session: AsyncSession,
    limit: int = 20,
    before: Optional[datetime] = None,
) -> MessageListResponse:
    if before is None:
        before = datetime.utcnow()

    stmt = (
        select(Message)
        .where(Message.thread_id == thread_id, Message.created_at <= before)
        .order_by(desc(Message.created_at))
        .limit(limit)
    )
    res = await session.execute(stmt)
    messages = list(res.scalars())

    next_cursor = messages[-1].created_at.isoformat() if messages else None

    data = [
        MessageDto(
            id=str(m.id),
            senderRole=m.sender_role,
            content=m.content_blob,
            timestamp=m.created_at,
        )
        for m in messages
    ]

    return MessageListResponse(
        data=data,
        paging={"nextCursor": next_cursor},
    )
