from __future__ import annotations

from fastapi import APIRouter, Depends, Query, status

from src.core.deps import get_enderecos_service, require_api_key
from src.modules.enderecos.schemas import EnderecoCreate, EnderecoOut, EnderecoUpdate
from src.modules.enderecos.service import EnderecosService

router = APIRouter(prefix="/api/v1/enderecos", tags=["Enderecos"])

_ALLOWED_SORT_FIELDS = {"titulo", "cep", "cidade", "estado", "$createdAt"}


@router.get(
    "",
    summary="List enderecos",
    description="Return a paginated list of enderecos with optional filtering, sorting, and search.",
    response_model=dict,
    responses={
        status.HTTP_200_OK: {
            "description": "Successful response",
            "content": {
                "application/json": {
                    "example": {
                        "page": 1,
                        "limit": 20,
                        "total": 2,
                        "items": [
                            {
                                "id": "end_1",
                                "titulo": "Matriz",
                                "cep": "12345-678",
                                "cidade": "São Paulo",
                                "estado": "SP",
                                "pais": "Brasil",
                                "createdAt": "2025-09-29T12:00:00.000Z",
                                "updatedAt": "2025-09-29T12:00:00.000Z",
                            },
                            {
                                "id": "end_2",
                                "titulo": "Filial",
                                "cep": "87654-321",
                                "cidade": "Rio de Janeiro",
                                "estado": "RJ",
                                "pais": "Brasil",
                                "createdAt": "2025-09-29T12:10:00.000Z",
                                "updatedAt": "2025-09-29T12:10:00.000Z",
                            },
                        ],
                    }
                }
            },
        },
        status.HTTP_400_BAD_REQUEST: {
            "description": "Invalid request parameters",
            "content": {
                "application/json": {
                    "example": {"detail": "Invalid sort field."}
                }
            },
        },
    },
)
async def list_enderecos(
    page: int = Query(1, ge=1),
    limit: int | None = Query(None, ge=1, le=100),
    q: str | None = Query(None, min_length=1),
    sort: str | None = Query(None),
    order: str | None = Query(None, pattern="^(?i)(asc|desc)$"),
    _: None = Depends(require_api_key),
    service: EnderecosService = Depends(get_enderecos_service),
) -> dict:
    normalized_order = order.lower() if order else None
    normalized_sort = sort if sort in _ALLOWED_SORT_FIELDS else sort
    return await service.list(page=page, limit=limit, q=q, sort=normalized_sort, order=normalized_order)


@router.get(
    "/{endereco_id}",
    summary="Retrieve endereco",
    description="Fetch a single endereco by its identifier, including audit metadata.",
    response_model=EnderecoOut,
    responses={
        status.HTTP_200_OK: {
            "description": "Endereco details",
            "content": {
                "application/json": {
                    "example": {
                        "id": "end_1",
                        "titulo": "Matriz",
                        "cep": "12345-678",
                        "logradouro": "Rua das Flores",
                        "numero": "123",
                        "complemento": "Sala 10",
                        "cidade": "São Paulo",
                        "estado": "SP",
                        "pais": "Brasil",
                        "latitude": -23.5505,
                        "longitude": -46.6333,
                        "bairro": "Centro",
                        "createdAt": "2025-09-29T12:00:00.000Z",
                        "updatedAt": "2025-09-29T12:00:00.000Z",
                    }
                }
            },
        },
        status.HTTP_404_NOT_FOUND: {
            "description": "Endereco not found",
            "content": {"application/json": {"example": {"detail": "Endereco not found."}}},
        },
    },
)
async def get_endereco(
    endereco_id: str,
    _: None = Depends(require_api_key),
    service: EnderecosService = Depends(get_enderecos_service),
) -> EnderecoOut:
    return await service.get(endereco_id)


@router.post(
    "",
    summary="Create endereco",
    description="Create a new endereco with optional geolocation and complement information.",
    response_model=EnderecoOut,
    status_code=status.HTTP_201_CREATED,
    responses={
        status.HTTP_201_CREATED: {
            "description": "Endereco created",
            "content": {
                "application/json": {
                    "example": {
                        "id": "end_3",
                        "titulo": "CD",
                        "cep": "54321-000",
                        "cidade": "Curitiba",
                        "estado": "PR",
                        "pais": "Brasil",
                        "createdAt": "2025-09-29T12:20:00.000Z",
                        "updatedAt": "2025-09-29T12:20:00.000Z",
                    }
                }
            },
        },
        status.HTTP_409_CONFLICT: {
            "description": "Endereco already exists",
            "content": {
                "application/json": {
                    "example": {"detail": "Endereco already exists."}
                }
            },
        },
    },
)
async def create_endereco(
    payload: EnderecoCreate,
    _: None = Depends(require_api_key),
    service: EnderecosService = Depends(get_enderecos_service),
) -> EnderecoOut:
    return await service.create(payload)


@router.patch(
    "/{endereco_id}",
    summary="Update endereco",
    description="Update an existing endereco partially, supporting address and coordinate fields.",
    response_model=EnderecoOut,
    responses={
        status.HTTP_200_OK: {
            "description": "Endereco updated",
            "content": {
                "application/json": {
                    "example": {
                        "id": "end_1",
                        "titulo": "Matriz",
                        "cep": "12345-678",
                        "cidade": "São Paulo",
                        "estado": "SP",
                        "pais": "Brasil",
                        "createdAt": "2025-09-29T12:00:00.000Z",
                        "updatedAt": "2025-09-29T12:05:00.000Z",
                    }
                }
            },
        },
        status.HTTP_404_NOT_FOUND: {
            "description": "Endereco not found",
            "content": {"application/json": {"example": {"detail": "Endereco not found."}}},
        },
        status.HTTP_409_CONFLICT: {
            "description": "Endereco already exists",
            "content": {
                "application/json": {
                    "example": {"detail": "Endereco already exists."}
                }
            },
        },
    },
)
async def update_endereco(
    endereco_id: str,
    payload: EnderecoUpdate,
    _: None = Depends(require_api_key),
    service: EnderecosService = Depends(get_enderecos_service),
) -> EnderecoOut:
    return await service.update(endereco_id, payload)


@router.delete(
    "/{endereco_id}",
    summary="Delete endereco",
    description="Remove an endereco from the system.",
    status_code=status.HTTP_204_NO_CONTENT,
    responses={
        status.HTTP_204_NO_CONTENT: {"description": "Endereco removed"},
        status.HTTP_404_NOT_FOUND: {
            "description": "Endereco not found",
            "content": {"application/json": {"example": {"detail": "Endereco not found."}}},
        },
    },
)
async def delete_endereco(
    endereco_id: str,
    _: None = Depends(require_api_key),
    service: EnderecosService = Depends(get_enderecos_service),
) -> None:
    await service.delete(endereco_id)
