"""
Rutas para gestión de catálogos de errores
"""

from typing import List

from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.orm import Session

from core.database import get_core_db
from core.security import get_current_user
from api.v1.common.tenant_crud_routes import TenantCRUDRoutes, validate_access_to_resource
from .dto import (
    ErrorClassificationCreateDTO,
    ErrorClassificationResponseDTO,
    ErrorClassificationUpdateDTO,
    ErrorClassificationDetailResponseDTO,
    ErrorCatalogCreateDTO,
    ErrorCatalogResponseDTO,
    ErrorCatalogUpdateDTO,
    ErrorCatalogDetailResponseDTO,
)
from .models import ErrorClassification, ErrorCatalog
from .service import ErrorClassificationService, ErrorCatalogService

router = APIRouter(prefix="/error-catalogs", tags=["error-catalogs"])


classification_crud = TenantCRUDRoutes(
    service=ErrorClassificationService,
    create_schema=ErrorClassificationCreateDTO,
    update_schema=ErrorClassificationUpdateDTO,
    response_schema=ErrorClassificationResponseDTO,
    prefix="/classifications",
    tags=["error-classifications"],
    resource_name="ErrorClassification",
    enable_list=True,
    list_permissions=["cat_errors.view"],
    get_permissions=["cat_errors.view"],
    create_permissions=["cat_errors.create"],
    update_permissions=["cat_errors.edit"],
    delete_permissions=["cat_errors.delete"],
)

# Add custom endpoints for classifications


@classification_crud.router.get(
    "/code/{code}",
    response_model=ErrorClassificationDetailResponseDTO,
    summary="Get error classification by code with errors",
)
async def get_classification_by_code(
    code: str,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: dict = Depends(get_current_user),
):
    """Get an error classification by its code with all related errors"""
    tenant_id = validate_access_to_resource(db, company_id, current_user, ["cat_errors.view"])
    classification = ErrorClassificationService.get_by_code(
        db,
        code,
        tenant_id=tenant_id,
        company_id=company_id,
    )
    if not classification:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Classification not found",
        )
    return ErrorClassificationDetailResponseDTO.model_validate(classification)

# Override get_by_id to return detail DTO


@classification_crud.router.get(
    "/{id}",
    response_model=ErrorClassificationDetailResponseDTO,
    summary="Get error classification by ID with errors",
)
async def get_classification(
    id: int,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: dict = Depends(get_current_user),
):
    """Get an error classification by its ID with all related errors"""
    tenant_id = validate_access_to_resource(db, company_id, current_user, ["cat_errors.view"])
    classification = ErrorClassificationService.get_by_id(
        db,
        id,
        tenant_id=tenant_id,
        company_id=company_id,
    )
    if not classification:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Classification not found",
        )
    return ErrorClassificationDetailResponseDTO.model_validate(classification)

router.include_router(classification_crud.router)



catalog_crud = TenantCRUDRoutes(
    service=ErrorCatalogService,
    create_schema=ErrorCatalogCreateDTO,
    update_schema=ErrorCatalogUpdateDTO,
    response_schema=ErrorCatalogResponseDTO,
    prefix="",
    tags=["error-catalogs"],
    resource_name="ErrorCatalog",
    enable_list=True,
    list_permissions=["cat_errors.view"],
    get_permissions=["cat_errors.view"],
    create_permissions=["cat_errors.create"],
    update_permissions=["cat_errors.edit"],
    delete_permissions=["cat_errors.delete"],
)

# Add custom endpoints for catalogs


@catalog_crud.router.get(
    "/code/{code}",
    response_model=ErrorCatalogDetailResponseDTO,
    summary="Get error by code",
)
async def get_error_by_code(
    code: str,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: dict = Depends(get_current_user),
):
    """Get an error by its code with classification details"""
    tenant_id = validate_access_to_resource(db, company_id, current_user, ["cat_errors.view"])
    error = ErrorCatalogService.get_by_code(
        db,
        code,
        tenant_id=tenant_id,
        company_id=company_id,
    )
    if not error:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Error not found",
        )
    return ErrorCatalogDetailResponseDTO.model_validate(error)


@catalog_crud.router.get(
    "/classification/{classification_id}",
    response_model=List[ErrorCatalogResponseDTO],
    summary="Get errors by classification",
)
async def get_errors_by_classification(
    classification_id: int,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: dict = Depends(get_current_user),
):
    """Get all errors for a specific classification"""
    tenant_id = validate_access_to_resource(db, company_id, current_user, ["cat_errors.view"])
    errors = ErrorCatalogService.get_by_classification(
        db,
        classification_id,
        tenant_id=tenant_id,
        company_id=company_id,
    )
    return [ErrorCatalogResponseDTO.model_validate(error) for error in errors]

# Override get_by_id to return detail DTO


@catalog_crud.router.get(
    "/{id}",
    response_model=ErrorCatalogDetailResponseDTO,
    summary="Get error by ID",
)
async def get_error(
    id: int,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: dict = Depends(get_current_user),
):
    """Get an error by its ID with classification details"""
    tenant_id = validate_access_to_resource(db, company_id, current_user, ["cat_errors.view"])
    error = ErrorCatalogService.get_by_id(
        db,
        id,
        tenant_id=tenant_id,
        company_id=company_id,
    )
    if not error:
        raise HTTPException(
            status_code=status.HTTP_404_NOT_FOUND,
            detail="Error not found",
        )
    return ErrorCatalogDetailResponseDTO.model_validate(error)

router.include_router(catalog_crud.router)
