from __future__ import annotations

from fastapi import APIRouter, Depends, Query, status

from src.core.deps import get_empresas_service, require_api_key
from src.modules.empresas.schemas import (
    EmpresaCreate,
    EmpresaOut,
    EmpresaRawOut,
    EmpresaUpdate,
)
from src.modules.empresas.service import EmpresasService

router = APIRouter(prefix="/api/v1/empresas", tags=["Empresas"])

_ALLOWED_SORT_FIELDS = {
    "cnpj",
    "razao-social",
    "razaoSocial",
    "nome-fantasia",
    "nomeFantasia",
    "data-abertura",
    "$createdAt",
}


@router.get(
    "",
    summary="List empresas",
    description="Return a paginated list of empresas 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": "emp_1",
                                "cnpj": "00.000.000/0001-91",
                                "razao-social": "Save in Med LTDA",
                                "nome-fantasia": "Save in Med",
                                "data-abertura": "2020-01-01",
                                "situacao": "Ativa",
                                "natureza-juridica": "Sociedade Limitada",
                                "porte": "ME",
                                "capital-social": 100000.0,
                                "telefone": "62999999999",
                                "email": "contato@saveinmed.com",
                                "atividade-principal-codigo": "47.89-0-99",
                                "atividade-principal-desc": "Comércio varejista",
                                "enderecos": ["addr_1", "addr_2"],
                                "createdAt": "2025-09-29T12:00:00.000Z",
                                "updatedAt": "2025-09-29T12:00:00.000Z",
                            },
                            {
                                "id": "emp_2",
                                "cnpj": "11111111000155",
                                "razao-social": "Farmácia Popular SA",
                                "nome-fantasia": "Farmácia Popular",
                                "data-abertura": "2022-05-03T10:00:00Z",
                                "situacao": "Ativa",
                                "natureza-juridica": "Sociedade Limitada",
                                "porte": "EPP",
                                "capital-social": 50000.0,
                                "telefone": "62988887777",
                                "email": "contato@farmaciapopular.com",
                                "atividade-principal-codigo": "47.71-7-01",
                                "atividade-principal-desc": "Comércio varejista de produtos farmacêuticos",
                                "enderecos": ["addr_3"],
                                "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_empresas(
    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: EmpresasService = Depends(get_empresas_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(
    "/{empresa_id}",
    summary="Retrieve empresa",
    description="Fetch a single empresa by its identifier, returning raw Appwrite fields.",
    response_model=EmpresaRawOut,
    responses={
        status.HTTP_200_OK: {
            "description": "Empresa details",
            "content": {
                "application/json": {
                    "example": {
                        "id": "emp_1",
                        "cnpj": "00000000000191",
                        "razao-social": "Save in Med LTDA",
                        "nome-fantasia": "Save in Med",
                        "data-abertura": "2020-01-01",
                        "situacao": "Ativa",
                        "natureza-juridica": "Sociedade Limitada",
                        "porte": "ME",
                        "capital-social": 100000.0,
                        "telefone": "62999999999",
                        "email": "contato@saveinmed.com",
                        "atividade-principal-codigo": "47.89-0-99",
                        "atividade-principal-desc": "Comércio varejista",
                        "enderecos": ["addr_1", "addr_2"],
                        "createdAt": "2025-09-29T12:00:00.000Z",
                        "updatedAt": "2025-09-29T12:00:00.000Z",
                    }
                }
            },
        },
        status.HTTP_404_NOT_FOUND: {
            "description": "Empresa not found",
            "content": {"application/json": {"example": {"detail": "Empresa not found."}}},
        },
    },
)
async def get_empresa(
    empresa_id: str,
    _: None = Depends(require_api_key),
    service: EmpresasService = Depends(get_empresas_service),
) -> EmpresaOut:
    # Retorna o documento bruto para incluir campos como $id, $createdAt, etc.
    return await service.get(empresa_id, raw=True)


@router.post(
    "",
    summary="Create empresa",
    description="Create a new empresa with optional trade name and social reason fields.",
    response_model=EmpresaOut,
    status_code=status.HTTP_201_CREATED,
    responses={
        status.HTTP_201_CREATED: {
            "description": "Empresa created",
            "content": {
                "application/json": {
                    "example": {
                        "id": "emp_3",
                        "cnpj": "22222222000109",
                        "razao-social": "Nova Empresa LTDA",
                        "nome-fantasia": "Nova Farma",
                        "data-abertura": "2023-06-01",
                        "situacao": "Ativa",
                        "natureza-juridica": "Sociedade Limitada",
                        "porte": "ME",
                        "capital-social": 80000.0,
                        "telefone": "62991234567",
                        "email": "contato@novafarma.com",
                        "atividade-principal-codigo": "47.71-7-01",
                        "atividade-principal-desc": "Comércio varejista de produtos farmacêuticos",
                        "enderecos": ["addr_9"],
                        "createdAt": "2025-09-29T12:20:00.000Z",
                        "updatedAt": "2025-09-29T12:20:00.000Z",
                    }
                }
            },
        },
        status.HTTP_409_CONFLICT: {
            "description": "Empresa already exists",
            "content": {
                "application/json": {
                    "example": {"detail": "Empresa already exists."}
                }
            },
        },
    },
)
async def create_empresa(
    payload: EmpresaCreate,
    _: None = Depends(require_api_key),
    service: EmpresasService = Depends(get_empresas_service),
) -> EmpresaOut:
    return await service.create(payload)


@router.patch(
    "/{empresa_id}",
    summary="Update empresa",
    description="Update an existing empresa partially, supporting optional field changes.",
    response_model=EmpresaOut,
    responses={
        status.HTTP_200_OK: {
            "description": "Empresa updated",
            "content": {
                "application/json": {
                    "example": {
                        "id": "emp_1",
                        "cnpj": "00000000000191",
                        "razao-social": "Save in Med LTDA",
                        "nome-fantasia": "Save in Med",
                        "data-abertura": "2020-01-01",
                        "situacao": "Ativa",
                        "natureza-juridica": "Sociedade Limitada",
                        "porte": "ME",
                        "capital-social": 100000.0,
                        "telefone": "62999999999",
                        "email": "contato@saveinmed.com",
                        "atividade-principal-codigo": "47.89-0-99",
                        "atividade-principal-desc": "Comércio varejista",
                        "enderecos": ["addr_1", "addr_2"],
                        "createdAt": "2025-09-29T12:00:00.000Z",
                        "updatedAt": "2025-09-29T12:05:00.000Z",
                    }
                }
            },
        },
        status.HTTP_404_NOT_FOUND: {
            "description": "Empresa not found",
            "content": {"application/json": {"example": {"detail": "Empresa not found."}}},
        },
        status.HTTP_409_CONFLICT: {
            "description": "Empresa already exists",
            "content": {
                "application/json": {
                    "example": {"detail": "Empresa already exists."}
                }
            },
        },
    },
)
async def update_empresa(
    empresa_id: str,
    payload: EmpresaUpdate,
    _: None = Depends(require_api_key),
    service: EmpresasService = Depends(get_empresas_service),
) -> EmpresaOut:
    return await service.update(empresa_id, payload)


@router.delete(
    "/{empresa_id}",
    summary="Delete empresa",
    description="Remove an empresa from the system.",
    status_code=status.HTTP_204_NO_CONTENT,
    responses={
        status.HTTP_204_NO_CONTENT: {"description": "Empresa removed"},
        status.HTTP_404_NOT_FOUND: {
            "description": "Empresa not found",
            "content": {"application/json": {"example": {"detail": "Empresa not found."}}},
        },
    },
)
async def delete_empresa(
    empresa_id: str,
    _: None = Depends(require_api_key),
    service: EmpresasService = Depends(get_empresas_service),
) -> None:
    await service.delete(empresa_id)
