"""
Rutas para el catálogo de claves FDA
"""
from fastapi import APIRouter, Depends, HTTPException, status, Query
from sqlalchemy.orm import Session
from typing import Any, Dict, Optional
from api.v1.modules.a76.general_catalogs.fda_catalog.service import FDACatalogService
from api.v1.modules.a76.general_catalogs.fda_catalog.dto import FDACatalogResponse
from core.database import get_core_db
from core.security import get_current_user
from api.v1.common.tenant_crud_routes import validate_access_to_resource


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


@router.get("/")
async def list_fda_catalog(
    company_id: int = Query(..., description="Company ID"),
    page: int = Query(1, ge=1, description="Page number"),
    page_size: int = Query(50, ge=1, le=1000, description="Page size"),
    search: Optional[str] = Query(None, description="Search in FDA key, description or code"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user)
):
    """Listar entradas del catálogo FDA con búsqueda y paginación"""
    # 👇 PERMISO DE LECTURA 👇
    tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["goods_fda.view"])
    
    filters = {"search": search} if search else {}
    result = FDACatalogService.get_all(db, tenant_id, company_id, page, page_size, filters)
    
    return {
        "items": result["items"],
        "total": result["total"],
        "page": result["page"],
        "page_size": result["page_size"],
        "pages": result["pages"]
    }


@router.get("/{id}")
async def get_fda_catalog(
    id: int,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user)
):
    """Obtener una entrada del catálogo FDA por ID"""
    # 👇 PERMISO DE LECTURA 👇
    tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["goods_fda.view"])
    
    entry = FDACatalogService.get_by_id(db, tenant_id, company_id, id)
    if not entry:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Entrada no encontrada")
    
    return {
        "id": entry.id,
        "fda_key": entry.fda_key,
        "description": entry.description,
        "fda_code": entry.fda_code,
        "requirements": entry.requirements,
        "manufacturer_number": entry.manufacturer_number,
        "country_of_production": entry.country_of_production,
        "storage_status": entry.storage_status,
        "warehouse_code": entry.warehouse_code,
        "call_atl": entry.call_atl
    }


from api.v1.modules.a76.general_catalogs.fda_catalog.dto import FDACatalogCreate, FDACatalogUpdate
from sqlalchemy.exc import IntegrityError

@router.post("/", response_model=FDACatalogResponse, status_code=status.HTTP_201_CREATED)
async def create_fda_catalog(
    data: FDACatalogCreate,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user)
):
    """Crear nueva entrada en el catálogo FDA"""
    # 👇 PERMISO DE CREACIÓN 👇
    tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["goods_fda.create"])
    try:
        return FDACatalogService.create(db, tenant_id, company_id, data)
    except IntegrityError:
        db.rollback()
        raise HTTPException(status_code=400, detail="La Clave FDA ya existe o hay un conflicto de datos.")


@router.put("/{id}", response_model=FDACatalogResponse)
async def update_fda_catalog(
    id: int,
    data: FDACatalogUpdate,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user)
):
    """Actualizar entrada del catálogo FDA"""
    # 👇 PERMISO DE EDICIÓN 👇
    tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["goods_fda.edit"])
    
    try:
        entry = FDACatalogService.update(db, tenant_id, company_id, id, data)
        if not entry:
            raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Entrada no encontrada")
        return entry
    except IntegrityError:
        db.rollback()
        raise HTTPException(status_code=400, detail="Error de integridad de datos al actualizar la Clave FDA.")


@router.delete("/{id}")
async def delete_fda_catalog(
    id: int,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user)
):
    """Eliminar entrada del catálogo FDA"""
    # 👇 PERMISO DE ELIMINACIÓN 👇
    tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["goods_fda.delete"])
    success = FDACatalogService.delete(db, tenant_id, company_id, id)
    if not success:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Entrada no encontrada")
    return {"message": "Eliminado correctamente"}


from typing import List
from api.v1.modules.a76.general_catalogs.fda_catalog.service import FDADetailsService
from api.v1.modules.a76.general_catalogs.fda_catalog.dto import (
    FDASpecificationsCreate, FDASpecificationsResponse,
    FDAConstituentElementsCreate, FDAConstituentElementsUpdate, FDAConstituentElementsResponse,
    FDAAffirmationCodesCreate, FDAAffirmationCodesUpdate, FDAAffirmationCodesResponse,
    FDALotProductionCreate, FDALotProductionUpdate, FDALotProductionResponse
)

# === FDA01: Especificaciones del Producto ===
@router.get("/{id}/specifications", response_model=Optional[FDASpecificationsResponse])
async def get_fda_specifications(
    id: int,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user)
):
    tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["goods_fda.view"])
    catalog_entry = FDACatalogService.get_by_id(db, tenant_id, company_id, id)
    if not catalog_entry:
        raise HTTPException(status_code=404, detail="Catálogo FDA no encontrado")
        
    return FDADetailsService.get_specifications(db, tenant_id, company_id, id)

@router.put("/{id}/specifications", response_model=FDASpecificationsResponse)
async def save_fda_specifications(
    id: int,
    data: FDASpecificationsCreate,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user)
):
    # Aquí usamos .edit porque estamos modificando un catálogo existente
    tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["goods_fda.edit"])
    catalog_entry = FDACatalogService.get_by_id(db, tenant_id, company_id, id)
    if not catalog_entry:
        raise HTTPException(status_code=404, detail="Catálogo FDA no encontrado")
        
    return FDADetailsService.save_specifications(db, tenant_id, company_id, id, data.model_dump(exclude_unset=True))

# === FDA04: Elementos Constitutivos ===
@router.get("/{id}/constituent-elements", response_model=List[FDAConstituentElementsResponse])
async def list_fda_constituent_elements(
    id: int,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user)
):
    tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["goods_fda.view"])
    return FDADetailsService.get_constituent_elements(db, tenant_id, company_id, id)

@router.post("/{id}/constituent-elements", response_model=FDAConstituentElementsResponse)
async def create_fda_constituent_element(
    id: int,
    data: FDAConstituentElementsCreate,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user)
):
    tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["goods_fda.create"])
    return FDADetailsService.create_constituent_element(db, tenant_id, company_id, id, data.model_dump())

@router.delete("/{id}/constituent-elements/{element_id}")
async def delete_fda_constituent_element(
    id: int,
    element_id: int,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user)
):
    tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["goods_fda.delete"])
    success = FDADetailsService.delete_constituent_element(db, tenant_id, company_id, element_id)
    if not success:
        raise HTTPException(status_code=404, detail="Elemento no encontrado")
    return {"message": "Eliminado correctamente"}

# === FDA23: Códigos de Afirmación ===
@router.get("/{id}/affirmation-codes", response_model=List[FDAAffirmationCodesResponse])
async def list_fda_affirmation_codes(
    id: int,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user)
):
    tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["goods_fda.view"])
    return FDADetailsService.get_affirmation_codes(db, tenant_id, company_id, id)

@router.post("/{id}/affirmation-codes", response_model=FDAAffirmationCodesResponse)
async def create_fda_affirmation_code(
    id: int,
    data: FDAAffirmationCodesCreate,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user)
):
    tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["goods_fda.create"])
    return FDADetailsService.create_affirmation_code(db, tenant_id, company_id, id, data.model_dump())

@router.delete("/{id}/affirmation-codes/{code_id}")
async def delete_fda_affirmation_code(
    id: int,
    code_id: int,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user)
):
    tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["goods_fda.delete"])
    success = FDADetailsService.delete_affirmation_code(db, tenant_id, company_id, code_id)
    if not success:
        raise HTTPException(status_code=404, detail="Código no encontrado")
    return {"message": "Eliminado correctamente"}

# === FDA25: Lotes de Producción ===
@router.get("/{id}/lot-productions", response_model=List[FDALotProductionResponse])
async def list_fda_lot_productions(
    id: int,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user)
):
    tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["goods_fda.view"])
    return FDADetailsService.get_lot_productions(db, tenant_id, company_id, id)

@router.post("/{id}/lot-productions", response_model=FDALotProductionResponse)
async def create_fda_lot_production(
    id: int,
    data: FDALotProductionCreate,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user)
):
    tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["goods_fda.create"])
    return FDADetailsService.create_lot_production(db, tenant_id, company_id, id, data.model_dump())

@router.delete("/{id}/lot-productions/{lot_id}")
async def delete_fda_lot_production(
    id: int,
    lot_id: int,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user)
):
    tenant_id = validate_access_to_resource(db, company_id, current_user, required_permissions=["goods_fda.delete"])
    success = FDADetailsService.delete_lot_production(db, tenant_id, company_id, lot_id)
    if not success:
        raise HTTPException(status_code=404, detail="Lote no encontrado")
    return {"message": "Eliminado correctamente"}