import uuid

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession
from pydantic import BaseModel

from app.core.dependencies import (
    get_current_actor,
    get_current_guest_actor,
    get_current_user,
    require_role,
    GESTIONNAIRE_PLUS,
)
from app.core.responses import api_response, normalize_page_param, page_response
from app.db.database import get_async_session
from app.schemas.discussion import DiscussionCreate
from app.schemas.typing import TypingStatus
from app.services.message_service import MessageService
from app.realtime import events as ws_events

router = APIRouter(prefix="/discussions", tags=["Discussions"])


class DiscussionAssignBody(BaseModel):
    gestionnaireId: str | None = None


@router.post("/", status_code=201)
async def creer_discussion(
    body: DiscussionCreate,
    db: AsyncSession = Depends(get_async_session),
    actor=Depends(get_current_actor),
):
    service = MessageService(db)
    data = await service.creer_discussion(
        body,
        actor_type=actor.actor_type,
        actor_id=actor.actor_id,
        current_user=actor.user,
    )
    return api_response(data, message="Discussion créée", status_code=201)


@router.get("/")
async def list_discussions(
    page: int = 0,
    size: int = 20,
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(get_current_user),
):
    resolved_page = normalize_page_param(page)
    service = MessageService(db)
    items, total = await service.list_discussions(current_user, page=resolved_page, size=size)
    return page_response(items, total=total, page=resolved_page, size=size)


@router.get("/{discussion_id}")
async def get_discussion(
    discussion_id: uuid.UUID,
    db: AsyncSession = Depends(get_async_session),
    actor=Depends(get_current_actor),
):
    service = MessageService(db)
    data = await service.get_discussion_for_actor(
        str(discussion_id),
        actor_type=actor.actor_type,
        actor_id=actor.actor_id,
        current_user=actor.user,
    )
    return api_response(data, message="Discussion récupérée")


@router.get("/guest/me")
async def list_guest_discussions(
    page: int = 0,
    size: int = 20,
    db: AsyncSession = Depends(get_async_session),
    actor=Depends(get_current_guest_actor),
):
    resolved_page = normalize_page_param(page)
    service = MessageService(db)
    items, total = await service.list_guest_discussions(actor.actor_id, page=resolved_page, size=size)
    return page_response(items, total=total, page=resolved_page, size=size)


@router.post("/{discussion_id}/typing")
async def update_typing_status(
    discussion_id: uuid.UUID,
    body: TypingStatus,
    actor=Depends(get_current_actor),
):
    await ws_events.broadcast_user_typing(
        discussion_id=str(discussion_id),
        user_id=str(actor.actor_id),
        user_name=actor.user.nom if actor.user else "Invité",
        is_typing=body.isTyping
    )
    return {"status": "ok"}


@router.put("/{discussion_id}/prendre-en-charge")
async def prendre_en_charge_discussion(
    discussion_id: uuid.UUID,
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(require_role(*GESTIONNAIRE_PLUS)),
):
    service = MessageService(db)
    data = await service.prendre_en_charge(discussion_id, current_user)
    return api_response(data, message="Discussion prise en charge")


@router.put("/{discussion_id}/assigner")
async def assigner_discussion(
    discussion_id: uuid.UUID,
    body: DiscussionAssignBody,
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(require_role(*GESTIONNAIRE_PLUS)),
):
    service = MessageService(db)
    data = await service.assigner(discussion_id, body.gestionnaireId, current_user)
    return api_response(data, message="Discussion assignée")


@router.put("/{discussion_id}/desassigner")
async def desassigner_discussion(
    discussion_id: uuid.UUID,
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(require_role(*GESTIONNAIRE_PLUS)),
):
    service = MessageService(db)
    data = await service.assigner(discussion_id, None, current_user)
    return api_response(data, message="Discussion désassignée")
