from __future__ import annotations

from fastapi import APIRouter, Depends, HTTPException, Query, status

from src.core.deps import (
    get_usuario_empresa_perfis_service,
    require_api_key,
    require_company_scope,
)

from .schemas import (
    PaginatedUsuarioEmpresaPerfis,
    UsuarioEmpresaPerfilCreate,
    UsuarioEmpresaPerfilOut,
    UsuarioEmpresaPerfilUpdate,
)
from .service import UsuarioEmpresaPerfisService

router = APIRouter(
    prefix="/api/v1/usuario-empresa-perfis",
    tags=["Usuários - Empresas & Perfis"],
)


@router.get(
    "",
    summary="Listar vínculos usuário-empresa-perfil",
    response_model=PaginatedUsuarioEmpresaPerfis,
    response_model_exclude_none=True,
        responses={
            status.HTTP_200_OK: {
                "description": "Lista paginada de vínculos com relacionamentos populados",
                "content": {
                    "application/json": {
                        "example": {
                            "items": [
                                {
                                    "id": "vinculo_01",
                                    "usuarioId": "usuario_01",
                                    "empresaId": "empresa_01",
                                    "perfilId": "perfil_admin",
                                    "usuario": {"id": "usuario_01", "nome": "admin@saveinmed.com"},
                                    "empresa": {"id": "empresa_01", "nome": "Farmácia Central"},
                                    "perfil": {"id": "perfil_admin", "nome": "Administrador"},
                                    "createdAt": "2025-01-15T12:00:00.000Z",
                                    "updatedAt": "2025-01-15T12:00:00.000Z",
                                }
                            ],
                            "total": 1,
                        }
                    }
                },
            }
        },
)
async def list_usuario_empresa_perfis(
    page: int = Query(1, ge=1, description="Página atual (>=1)"),
    limit: int | None = Query(None, ge=1, le=100, description="Itens por página (1-100)"),
    q: str | None = Query(None, description="Busca por identificadores"),
    sort: str | None = Query(
        None,
        description="Campo para ordenação",
        pattern="^(usuarios|empresas-dados|usuario-perfis|\\$createdAt)$",
    ),
    order: str | None = Query(None, pattern="^(asc|desc)$", description="Ordem da ordenação"),
    _: None = Depends(require_api_key),
    empresa_id: str = Depends(require_company_scope),
    service: UsuarioEmpresaPerfisService = Depends(get_usuario_empresa_perfis_service),
) -> PaginatedUsuarioEmpresaPerfis:
    return await service.list(
        page=page,
        limit=limit,
        q=q,
        sort=sort,
        order=order,
        empresa_id=empresa_id,
    )


@router.get(
    "/{vinculo_id}",
    summary="Detalhar vínculo usuário-empresa-perfil",
    response_model=UsuarioEmpresaPerfilOut,
    response_model_exclude_none=True,
        responses={
            status.HTTP_200_OK: {
                "description": "Vínculo encontrado com relacionamentos populados",
                "content": {
                    "application/json": {
                        "example": {
                            "id": "vinculo_01",
                            "usuarioId": "usuario_01",
                            "empresaId": "empresa_01",
                            "perfilId": "perfil_admin",
                            "usuario": {"id": "usuario_01", "nome": "admin@saveinmed.com"},
                            "empresa": {"id": "empresa_01", "nome": "Farmácia Central"},
                            "perfil": {"id": "perfil_admin", "nome": "Administrador"},
                            "createdAt": "2025-01-15T12:00:00.000Z",
                            "updatedAt": "2025-01-15T12:00:00.000Z",
                        }
                    }
                },
            },
            status.HTTP_404_NOT_FOUND: {
                "description": "Vínculo não encontrado",
                "content": {"application/json": {"example": {"detail": "Vínculo não encontrado."}}},
            },
        },
)
async def get_usuario_empresa_perfil(
    vinculo_id: str,
    _: None = Depends(require_api_key),
    empresa_id: str = Depends(require_company_scope),
    service: UsuarioEmpresaPerfisService = Depends(get_usuario_empresa_perfis_service),
) -> UsuarioEmpresaPerfilOut:
    return await service.get(vinculo_id, empresa_id=empresa_id)


@router.post(
    "",
    summary="Criar vínculo usuário-empresa-perfil",
    status_code=status.HTTP_201_CREATED,
    response_model=UsuarioEmpresaPerfilOut,
    response_model_exclude_none=True,
        responses={
            status.HTTP_201_CREATED: {
                "description": "Vínculo criado",
                "content": {
                    "application/json": {
                        "example": {
                            "id": "vinculo_02",
                            "usuarioId": "usuario_02",
                            "empresaId": "empresa_02",
                            "perfilId": "perfil_vendedor",
                            "usuario": {"id": "usuario_02", "nome": "suporte@saveinmed.com"},
                            "empresa": {"id": "empresa_02", "nome": "Drogaria Bairro"},
                            "perfil": {"id": "perfil_vendedor", "nome": "Vendedor"},
                            "createdAt": "2025-02-01T09:30:00.000Z",
                            "updatedAt": "2025-02-01T09:30:00.000Z",
                        }
                    }
                },
            }
        },
)
async def create_usuario_empresa_perfil(
    body: UsuarioEmpresaPerfilCreate,
    _: None = Depends(require_api_key),
    empresa_id: str = Depends(require_company_scope),
    service: UsuarioEmpresaPerfisService = Depends(get_usuario_empresa_perfis_service),
) -> UsuarioEmpresaPerfilOut:
    if body.empresaId != empresa_id:
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Empresa do payload difere do escopo informado.",
        )
    return await service.create(body, empresa_id=empresa_id)


@router.put(
    "/{vinculo_id}",
    summary="Atualizar vínculo usuário-empresa-perfil",
    response_model=UsuarioEmpresaPerfilOut,
    response_model_exclude_none=True,
        responses={
            status.HTTP_200_OK: {
                "description": "Vínculo atualizado",
                "content": {
                    "application/json": {
                        "example": {
                            "id": "vinculo_02",
                            "usuarioId": "usuario_02",
                            "empresaId": "empresa_03",
                            "perfilId": "perfil_vendedor",
                            "usuario": {"id": "usuario_02", "nome": "suporte@saveinmed.com"},
                            "empresa": {"id": "empresa_03", "nome": "Unidade Centro"},
                            "perfil": {"id": "perfil_vendedor", "nome": "Vendedor"},
                            "createdAt": "2025-02-01T09:30:00.000Z",
                            "updatedAt": "2025-03-10T08:00:00.000Z",
                        }
                    }
                },
            },
            status.HTTP_404_NOT_FOUND: {
                "description": "Vínculo não encontrado",
                "content": {"application/json": {"example": {"detail": "Vínculo não encontrado."}}},
            },
        },
)
async def update_usuario_empresa_perfil(
    vinculo_id: str,
    body: UsuarioEmpresaPerfilUpdate,
    _: None = Depends(require_api_key),
    empresa_id: str = Depends(require_company_scope),
    service: UsuarioEmpresaPerfisService = Depends(get_usuario_empresa_perfis_service),
) -> UsuarioEmpresaPerfilOut:
    if body.empresaId not in (None, empresa_id):
        raise HTTPException(
            status_code=status.HTTP_403_FORBIDDEN,
            detail="Não é permitido alterar a empresa do vínculo para outro escopo.",
        )
    return await service.update(vinculo_id, body, empresa_id=empresa_id)


@router.delete(
    "/{vinculo_id}",
    status_code=status.HTTP_204_NO_CONTENT,
    summary="Remover vínculo usuário-empresa-perfil",
)
async def delete_usuario_empresa_perfil(
    vinculo_id: str,
    _: None = Depends(require_api_key),
    empresa_id: str = Depends(require_company_scope),
    service: UsuarioEmpresaPerfisService = Depends(get_usuario_empresa_perfis_service),
) -> None:
    await service.delete(vinculo_id, empresa_id=empresa_id)
