import uuid

from fastapi import APIRouter, Depends, Header, HTTPException, Query
from sqlalchemy.ext.asyncio import AsyncSession

from app.core.dependencies import (
    ensure_guest_mode_enabled,
    get_current_guest_actor,
    get_current_user,
    get_optional_user,
)
from app.core.responses import api_response
from app.db.database import get_async_session
from app.schemas.guest import (
    GuestMergeRequest,
    GuestSessionCreateRequest,
    GuestSessionUpdateTelephoneRequest,
)
from app.services.guest_session_service import GuestSessionService

router = APIRouter(
    prefix="/guest",
    tags=["Guest"],
    dependencies=[Depends(ensure_guest_mode_enabled)],
)


@router.post("/sessions", status_code=201)
async def create_guest_session(
    body: GuestSessionCreateRequest,
    db: AsyncSession = Depends(get_async_session),
):
    service = GuestSessionService(db)
    data = await service.create_session(body.telephone, body.deviceFingerprint)
    return api_response(data, message="Session invitée créée", status_code=201)


@router.get("/sessions/{guest_id}")
async def get_guest_session(
    guest_id: uuid.UUID,
    db: AsyncSession = Depends(get_async_session),
):
    service = GuestSessionService(db)
    data = await service.get_session(str(guest_id))
    return api_response(data, message="Session invitée récupérée")


@router.patch("/sessions/{guest_id}/telephone")
async def update_guest_phone(
    guest_id: uuid.UUID,
    body: GuestSessionUpdateTelephoneRequest,
    db: AsyncSession = Depends(get_async_session),
):
    service = GuestSessionService(db)
    data = await service.update_telephone(str(guest_id), body.telephone)
    return api_response(data, message="Téléphone invité mis à jour")


@router.get("/sessions/{guest_id}/merge-preview")
async def guest_merge_preview(
    guest_id: uuid.UUID,
    user_id: uuid.UUID | None = Query(default=None, alias="userId"),
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(get_optional_user),
):
    resolved_user_id = user_id or (current_user.id if current_user else None)
    if resolved_user_id is None:
        raise HTTPException(status_code=401, detail="AUTH_OR_USER_ID_REQUIRED")

    service = GuestSessionService(db)
    data = await service.merge_preview(str(guest_id), str(resolved_user_id))
    return api_response(data, message="Aperçu de fusion généré")


@router.post("/sessions/{guest_id}/merge")
async def merge_guest_session(
    guest_id: uuid.UUID,
    body: GuestMergeRequest,
    idempotency_key: str | None = Header(default=None, alias="Idempotency-Key"),
    db: AsyncSession = Depends(get_async_session),
    current_user=Depends(get_current_user),
):
    service = GuestSessionService(db)
    data = await service.merge_guest_into_user(
        guest_id=str(guest_id),
        user_id=str(current_user.id),
        idempotency_key=idempotency_key or "",
        accept_policy=body.acceptPolicy,
        resolutions=[item.model_dump() for item in body.resolutions],
    )
    return api_response(data, message="Fusion guest vers utilisateur terminée")


@router.get("/suivi")
async def get_guest_suivi(
    db: AsyncSession = Depends(get_async_session),
    actor=Depends(get_current_guest_actor),
):
    service = GuestSessionService(db)
    data = await service.get_guest_suivi(actor.actor_id)
    return api_response(data, message="Suivi invité récupéré")


@router.get("/suivi/{reference}")
async def get_guest_suivi_detail(
    reference: str,
    db: AsyncSession = Depends(get_async_session),
    actor=Depends(get_current_guest_actor),
):
    service = GuestSessionService(db)
    data = await service.get_guest_suivi_by_reference(actor.actor_id, reference)
    return api_response(data, message="Détail suivi invité récupéré")
