from uuid import UUID

from fastapi import APIRouter, Depends
from pydantic import BaseModel

from app.api.deps import AsyncSession, CurrentUser, get_current_user, get_db, require_tenant
from app.schemas.common import (
    ContactCreate,
    ContactOut,
    ContactSourceCreate,
    ContactSourceOut,
)
from app.services.contact_service import ContactService

router = APIRouter()


class CSVImportBody(BaseModel):
    csv_text: str


class ResolveBody(BaseModel):
    source_id: UUID | None = None
    query: dict | None = None
    channel: str = "sms"


@router.get("/manual", response_model=list[ContactOut])
async def list_manual_contacts(
    tenant_id: UUID = Depends(require_tenant),
    session: AsyncSession = Depends(get_db),
    _: CurrentUser = Depends(get_current_user),
):
    return await ContactService(session).list_manual(tenant_id)


@router.post("/manual", response_model=ContactOut, status_code=201)
async def create_manual_contact(
    body: ContactCreate,
    tenant_id: UUID = Depends(require_tenant),
    session: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await ContactService(session).create_manual(
        tenant_id, body.model_dump(), actor_id=user.user_id
    )


@router.post("/manual/import-csv", response_model=list[ContactOut], status_code=201)
async def import_csv(
    body: CSVImportBody,
    tenant_id: UUID = Depends(require_tenant),
    session: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await ContactService(session).import_csv(
        tenant_id, body.csv_text, actor_id=user.user_id
    )


@router.get("/sources", response_model=list[ContactSourceOut])
async def list_sources(
    tenant_id: UUID = Depends(require_tenant),
    session: AsyncSession = Depends(get_db),
    _: CurrentUser = Depends(get_current_user),
):
    return await ContactService(session).list_sources(tenant_id)


@router.post("/sources", response_model=ContactSourceOut, status_code=201)
async def create_source(
    body: ContactSourceCreate,
    tenant_id: UUID = Depends(require_tenant),
    session: AsyncSession = Depends(get_db),
    user: CurrentUser = Depends(get_current_user),
):
    return await ContactService(session).create_source(
        tenant_id, body.model_dump(), actor_id=user.user_id
    )


@router.post("/resolve")
async def resolve_contacts(
    body: ResolveBody,
    tenant_id: UUID = Depends(require_tenant),
    session: AsyncSession = Depends(get_db),
    _: CurrentUser = Depends(get_current_user),
):
    resolved = await ContactService(session).resolve(
        tenant_id,
        source_id=body.source_id,
        query=body.query,
        channel=body.channel,
    )
    return [
        {
            "address": r.address,
            "display_name": r.display_name,
            "external_ref": r.external_ref,
            "source_type": r.source_type,
        }
        for r in resolved
    ]
