from typing import Optional
from sqlalchemy.exc import IntegrityError
from sqlalchemy.ext.asyncio import AsyncSession
from fastapi import APIRouter, Depends, HTTPException, Query, status

from src.core.database import get_db
from src.services.times import TimeService
from src.core.auth import require_enterprise_or_front, AuthContext
from src.schemas.times import TimeCreate, TimeUpdate, TimeResponse
from src.core.api_responses import (
    build_success_payload,
    SuccessResponse,
    ErrorResponse,
)

router = APIRouter(
    prefix="/times",
    tags=["Times"],
)

time_service = TimeService()

@router.get(
    "/{time_id}",
    summary="Obter time por ID",
    description="Recupera os detalhes de um time específico.",
    status_code=status.HTTP_200_OK,
    response_model=SuccessResponse,
    responses={
        200: {"description": "Time encontrado"},
        404: {"description": "Time não encontrado", "model": ErrorResponse},
        401: {
            "description": "Credenciais inválidas ou ausentes",
            "model": ErrorResponse,
        },
    },
)
async def obter_time(
    time_id: int,
    db: AsyncSession = Depends(get_db),
    auth_ctx: AuthContext = Depends(require_enterprise_or_front),
) -> SuccessResponse:
    """Obter time por ID."""
    time = await time_service.get_time(db, time_id)
    if not time:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Time não encontrado",
        )
    if auth_ctx.get("type") == "enterprise":
        if time.empresa_id != auth_ctx["empresa"].id:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="Time não pertence à sua empresa",
            )
    return build_success_payload(
        data=TimeResponse.model_validate(time),
        message="Time encontrado",
    )


@router.get(
    "/empresa/{empresa_id}",
    summary="Listar times de uma empresa",
    description="Lista todos os times vinculados a uma empresa específica.",
    status_code=status.HTTP_200_OK,
    response_model=SuccessResponse,
    responses={
        200: {
            "description": "Times listados com sucesso"},
        401: {
            "description": "Credenciais inválidas ou ausentes",
            "model": ErrorResponse},
    },
)
async def listar_times_empresa(
    empresa_id: str,
    db: AsyncSession = Depends(get_db),
    auth_ctx: AuthContext = Depends(require_enterprise_or_front),
) -> SuccessResponse:
    """Listar times de uma empresa."""
    if auth_ctx.get("type") == "enterprise":
        if empresa_id != auth_ctx["empresa"].id:
            raise HTTPException(
                status_code=status.HTTP_403_FORBIDDEN,
                detail="Não autorizado a listar times de outra empresa",
            )
    times = await time_service.get_times_by_empresa(db, empresa_id)
    return build_success_payload(
        data=[TimeResponse.model_validate(t) for t in times],
        message=f"Total de {len(times)} time(s) encontrado(s)",
    )


@router.get(
    "",
    summary="Listar times",
    description="Lista todos os times com filtros opcionais.",
    status_code=status.HTTP_200_OK,
    response_model=SuccessResponse,
    responses={
        200: {"description": "Times listados com sucesso"},
        401: {
            "description": "Credenciais inválidas ou ausentes",
            "model": ErrorResponse,
        },
    },
)
async def listar_times(
    empresa_id: Optional[str] = Query(
        None, description="Filtrar por empresa_id"
    ),
    nome: Optional[str] = Query(
        None, description="Filtrar por nome"
    ),
    db: AsyncSession = Depends(get_db),
    auth_ctx: AuthContext = Depends(require_enterprise_or_front),
) -> SuccessResponse:
    """Listar todos os times."""
    if auth_ctx.get("type") == "enterprise":
        empresa_id = auth_ctx["empresa"].id
    times = await time_service.list_times(db, empresa_id=empresa_id, nome=nome)
    return build_success_payload(
        data=[TimeResponse.model_validate(t) for t in times],
        message=f"Total de {len(times)} time(s) encontrado(s)",
    )

