"""
Endpoints API para fracciones arancelarias
Catálogo de referencia global (no tenant-scoped)
"""

from typing import Any, Dict, Optional
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, get_tenant_from_token, validate_access_to_resource

from .dto import (
    TariffFractionCreateDTO,
    TariffFractionResponseDTO,
    TariffFractionUpdateDTO,
)
from .service import TariffFractionService

router = APIRouter(prefix="/tariff-fractions", tags=["a76 / general catalogs / tariff fractions"])

# Custom list endpoint with search filter
@router.get(
    "/",
    response_model=Dict[str, Any],
    summary="List Tariff Fractions",
    description="Get paginated list of Tariff Fractions with optional search filter (global catalog)",
)
async def list_tariff_fractions(
    company_id: int = Query(..., description="Company ID"),
    page: int = Query(1, ge=1, description="Page number"),
    page_size: int = Query(50, ge=1, le=10000, description="Page size"),
    search: Optional[str] = Query(None, description="Search in code, fraction, description, nico, or umt"),
    level: Optional[int] = Query(None, description="Filter by hierarchy level (e.g. 5)"),
    catalog: Optional[str] = Query(
        "mex",
        description="Catalog: 'mex' (default), 'usa', or 'american' (both US read-only via SITAR)",
    ),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user),
):
    # Validar permisos según el catálogo solicitado
    if catalog == "mex":
        validate_access_to_resource(db, company_id, current_user, ["frac_sitar.view"])
    elif catalog == "usa":
        validate_access_to_resource(db, company_id, current_user, ["frac_sitar_us.view"])
    elif catalog == "american":
        validate_access_to_resource(db, company_id, current_user, ["frac_american.view"])
    
    skip = (page - 1) * page_size
    filters = {}
    if search:
        filters["search"] = search
    if level is not None:
        filters["level"] = level
    
    # Updated to async call with Sitar integration
    # WARNING: Using async def with blocking DB dependency (Session) run in threadpool by FastAPI.
    # Service.get_all calls Sitar (async) or DB (sync).
    # This should be fine.
    
    tenant_id = get_tenant_from_token(current_user)
    if tenant_id is None:
        tenant_id = current_user.get("tenant_id")
    # If using headers for selected company, it might be in current_user context if middleware sets it.
    
    items, total = await TariffFractionService.get_all(
        db, skip, page_size, filters, catalog, tenant_id, company_id
    )
    
    return {
        "items": [TariffFractionResponseDTO.model_validate(item) for item in items],
        "total": total,
        "page": page,
        "page_size": page_size,
        "pages": (total + page_size - 1) // page_size,
    }


@router.get(
    "/{tariff_fraction_id}",
    response_model=TariffFractionResponseDTO,
    summary="Get Tariff Fraction by ID",
    description="Get a specific tariff fraction by ID (Lookups in Local DB for legacy compatibility)",
)
async def get_tariff_fraction(
    tariff_fraction_id: int,
    catalog: str = Query("mex", description="Catalog source: 'mex', 'usa', or 'american'"),
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user),
):
    if catalog == "mex":
        validate_access_to_resource(db, company_id, current_user, ["frac_sitar.view"])
    elif catalog == "usa":
        validate_access_to_resource(db, company_id, current_user, ["frac_sitar_us.view"])
    elif catalog == "american":
        validate_access_to_resource(db, company_id, current_user, ["frac_american.view"])
    else:
        raise HTTPException(status_code=400, detail=f"Unsupported catalog '{catalog}'")
    item = TariffFractionService.get_by_id(db, tariff_fraction_id)
    if not item:
        from fastapi import HTTPException
        raise HTTPException(status_code=404, detail="Tariff fraction not found")
    return TariffFractionResponseDTO.model_validate(item)


@router.post(
    "/",
    response_model=TariffFractionResponseDTO,
    summary="Create Tariff Fraction",
    description="Not supported: all catalogs are read-only (SITAR-backed for US).",
)
async def create_tariff_fraction(
    fraction_data: TariffFractionCreateDTO,
    catalog: str = Query("mex", description="Catalog source: 'mex', 'usa', or 'american'"),
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user),
):
    """
    Crea una nueva fracción.
    - MEX/USA: No permitido (Read-Only)
    - AMERICAN: Permitido (Local DB)
    """
    from fastapi import HTTPException
    
    tenant_id = current_user.get("tenant_id")
    
    if catalog == "american":
        validate_access_to_resource(db, company_id, current_user, ["frac_american.create"])
        from api.v1.modules.a76.general_catalogs.fractions.us_tariff_fractions.service import USTariffFractionService
        from api.v1.modules.a76.general_catalogs.fractions.us_tariff_fractions.dto import USTariffFractionCreateDTO
        import re

        # Map generic DTO to US DTO
        ad_valorem = None
        if fraction_data.adv_impo:
            try:
                # remove non-numeric chars except dot
                clean = re.sub(r'[^\d.]', '', fraction_data.adv_impo)
                if clean:
                    ad_valorem = float(clean)
            except:
                pass
        
        us_dto = USTariffFractionCreateDTO(
            code=fraction_data.fraction, # Store the punctuated fraction in the DB
            description=fraction_data.description,
            unit_of_measure=fraction_data.umt,
            ad_valorem=ad_valorem,
            # Defaults for others
            prefix=None,
            type_code=None,
            fixed_cost=None
        )
        
        created = USTariffFractionService.create(db, us_dto, tenant_id, company_id)
        return TariffFractionService.to_domain_usa_local(created)
    
    else:
        raise HTTPException(status_code=400, detail=f"Creation not allowed for '{catalog}' catalog (Read-Only)")
    raise HTTPException(
        status_code=status.HTTP_405_METHOD_NOT_ALLOWED,
        detail=f"Creation not allowed for '{catalog}' catalog (read-only; US data from SITAR).",
    )


@router.put(
    "/{tariff_fraction_id}",
    response_model=TariffFractionResponseDTO,
    summary="Update Tariff Fraction",
    description="Not supported: all catalogs are read-only (SITAR-backed for US).",
)
async def update_tariff_fraction(
    tariff_fraction_id: int,
    fraction_data: TariffFractionUpdateDTO,
    catalog: str = Query("mex", description="Catalog source: 'mex', 'usa', or 'american'"),
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user),
):
    from fastapi import HTTPException
    
    tenant_id = current_user.get("tenant_id")
    
    if catalog == "american":
        validate_access_to_resource(db, company_id, current_user, ["frac_american.edit"])
        from api.v1.modules.a76.general_catalogs.fractions.us_tariff_fractions.service import USTariffFractionService
        from api.v1.modules.a76.general_catalogs.fractions.us_tariff_fractions.dto import USTariffFractionUpdateDTO
        import re

        ad_valorem = None
        if fraction_data.adv_impo:
            try:
                clean = re.sub(r'[^\d.]', '', fraction_data.adv_impo)
                if clean:
                    ad_valorem = float(clean)
            except:
                pass
        
        us_dto = USTariffFractionUpdateDTO(
            code=fraction_data.fraction,
            description=fraction_data.description,
            unit_of_measure=fraction_data.umt,
            ad_valorem=ad_valorem
        )
        
        updated = USTariffFractionService.update(db, tariff_fraction_id, tenant_id, us_dto, company_id)
        if not updated:
             raise HTTPException(status_code=404, detail="US Tariff fraction not found")
        return TariffFractionService.to_domain_usa_local(updated)

    else:
         raise HTTPException(status_code=400, detail=f"Update not allowed for '{catalog}' catalog (Read-Only)")
    raise HTTPException(
        status_code=status.HTTP_405_METHOD_NOT_ALLOWED,
        detail=f"Update not allowed for '{catalog}' catalog (read-only; US data from SITAR).",
    )


@router.delete(
    "/{tariff_fraction_id}",
    summary="Delete Tariff Fraction",
    description="Not supported: all catalogs are read-only (SITAR-backed for US).",
)
async def delete_tariff_fraction(
    tariff_fraction_id: int,
    catalog: str = Query("mex", description="Catalog source: 'mex', 'usa', or 'american'"),
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user),
):
    from fastapi import HTTPException
    tenant_id = current_user.get("tenant_id")
    
    if catalog == "american":
        validate_access_to_resource(db, company_id, current_user, ["frac_american.delete"])
        from api.v1.modules.a76.general_catalogs.fractions.us_tariff_fractions.service import USTariffFractionService
        success = USTariffFractionService.delete(db, tariff_fraction_id, tenant_id, company_id)
        if not success:
             raise HTTPException(status_code=404, detail="US Tariff fraction not found")
        return {"ok": True}
    
    else:
        raise HTTPException(status_code=400, detail=f"Delete not allowed for '{catalog}' catalog (Read-Only)")
    raise HTTPException(
        status_code=status.HTTP_405_METHOD_NOT_ALLOWED,
        detail=f"Delete not allowed for '{catalog}' catalog (read-only; US data from SITAR).",
    )

