from typing import Optional
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.asyncio import AsyncSession
from src.services.usuarios import UsuarioService
from src.core.auth import require_enterprise_or_front
from fastapi import APIRouter, Depends, HTTPException, Query, status
from src.schemas.usuarios import UsuarioCreate, UsuarioUpdate, UsuarioResponse
from src.core.database import get_db
from src.core.api_responses import (
    build_success_payload,
    SuccessResponse,
    ErrorResponse,
)

router = APIRouter(
    prefix="/usuarios",
    tags=["Usuarios"],
)

usuario_service = UsuarioService()


@router.post(
    "/criar",
    summary="Criar usuário",
    description="Cria um novo usuário.",
    status_code=status.HTTP_201_CREATED,
    response_model=SuccessResponse,
    responses={
        201: {"description": "Usuário criado com sucesso"},
        400: {"description": "Dados inválidos", "model": ErrorResponse},
        401: {
            "description": "Credenciais inválidas ou ausentes",
            "model": ErrorResponse,
        },
        500: {"description": "Erro interno", "model": ErrorResponse},
    },
)
async def criar_usuario(
    payload: UsuarioCreate,
    db: AsyncSession = Depends(get_db),
    enterprise_id: str = Depends(require_enterprise_or_front),
) -> SuccessResponse:
    """Criar um novo usuário."""
    try:
        usuario = await usuario_service.create_usuario(db, payload)
        return build_success_payload(
            data=UsuarioResponse.model_validate(usuario),
            message=f"Usuário criado com sucesso (ID: {usuario.id})",
        )
    except IntegrityError:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Erro ao criar usuário. Nome já existe.",
        )
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Erro ao criar usuário: {str(e)}",
        )


@router.get(
    "/{usuario_id}",
    summary="Obter usuário por ID",
    description="Recupera os detalhes de um usuário específico.",
    status_code=status.HTTP_200_OK,
    response_model=SuccessResponse,
    responses={
        200: {"description": "Usuário encontrado"},
        404: {"description": "Usuário não encontrado", "model": ErrorResponse},
        401: {
            "description": "Credenciais inválidas ou ausentes",
            "model": ErrorResponse,
        },
    },
)
async def obter_usuario(
    usuario_id: int,
    db: AsyncSession = Depends(get_db),
    enterprise_id: str = Depends(require_enterprise_or_front),
) -> SuccessResponse:
    """Obter usuário por ID."""
    usuario = await usuario_service.get_usuario(db, usuario_id)
    if not usuario:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Usuário não encontrado",
        )
    return build_success_payload(
        data=UsuarioResponse.model_validate(usuario),
        message="Usuário encontrado",
    )


@router.get(
    "",
    summary="Listar usuários",
    description="Lista todos os usuários com filtros opcionais.",
    status_code=status.HTTP_200_OK,
    response_model=SuccessResponse,
    responses={
        200: {"description": "Usuários listados com sucesso"},
        401: {
            "description": "Credenciais inválidas ou ausentes",
            "model": ErrorResponse,
        },
    },
)
async def listar_usuarios(
    ativo: Optional[bool] = Query(
        None, description="Filtrar por status ativo"
    ),
    nome: Optional[str] = Query(
        None, description="Filtrar por nome"
    ),
    db: AsyncSession = Depends(get_db),
    enterprise_id: str = Depends(require_enterprise_or_front),
) -> SuccessResponse:
    """Listar todos os usuários."""
    usuarios = await usuario_service.list_usuarios(db, ativo=ativo, nome=nome)
    return build_success_payload(
        data=[UsuarioResponse.model_validate(u) for u in usuarios],
        message=f"Total de {len(usuarios)} usuário(s) encontrado(s)",
    )


@router.put(
    "/{usuario_id}",
    summary="Atualizar usuário",
    description="Atualiza os dados de um usuário específico.",
    status_code=status.HTTP_200_OK,
    response_model=SuccessResponse,
    responses={
        200: {
            "description": "Usuário atualizado com sucesso"},
        404: {
            "description": "Usuário não encontrado",
            "model": ErrorResponse},
        400: {
            "description": "Dados inválidos",
            "model": ErrorResponse},
        401: {
            "description": "Credenciais inválidas ou ausentes",
            "model": ErrorResponse},
    },
)
async def atualizar_usuario(
    usuario_id: int,
    payload: UsuarioUpdate,
    db: AsyncSession = Depends(get_db),
    enterprise_id: str = Depends(require_enterprise_or_front),
) -> SuccessResponse:
    """Atualizar usuário."""
    try:
        usuario = await usuario_service.update_usuario(db, usuario_id, payload)
        if not usuario:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Usuário não encontrado",
            )
        return build_success_payload(
            data=UsuarioResponse.model_validate(usuario),
            message="Usuário atualizado com sucesso",
        )
    except IntegrityError:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Erro ao atualizar usuário. Verifique os dados fornecidos.",
        )
    except Exception as e:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=f"Erro ao atualizar usuário: {str(e)}",
        )


@router.delete(
    "/{usuario_id}",
    summary="Deletar usuário",
    description="Remove um usuário específico.",
    status_code=status.HTTP_200_OK,
    response_model=SuccessResponse,
    responses={
        200: {"description": "Usuário deletado com sucesso"},
        404: {"description": "Usuário não encontrado", "model": ErrorResponse},
        401: {
            "description": "Credenciais inválidas ou ausentes",
            "model": ErrorResponse,
        },
    },
)
async def deletar_usuario(
    usuario_id: int,
    db: AsyncSession = Depends(get_db),
    enterprise_id: str = Depends(require_enterprise_or_front),
) -> SuccessResponse:
    """Deletar usuário."""
    success = await usuario_service.delete_usuario(db, usuario_id)
    if not success:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Usuário não encontrado",
        )
    return build_success_payload(
        data=None,
        message="Usuário deletado com sucesso",
    )
