"""
Endpoints API para gestión de clientes y proveedores
"""

from typing import List, Optional

from core.database import get_core_db
from core.security import get_current_user, validate_access_to_resource
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import or_
from sqlalchemy.orm import Session, joinedload
from api.v1.common.tenant_crud_routes import TenantCRUDRoutes
from .models import ClientOrProviderEnum

from .dto import (
    ClientProviderBasicDTO,
    ClientProviderCreateDTO,
    ClientProviderResponseDTO,
    ClientProviderUpdateDTO,
    ClientProviderPaginatedResponseDTO,
)
from .service import ClientProviderService
from .models import ClientProvider
from api.v1.modules.a76.layouts_csv.clients_and_providers.routes import router as imports_router

# Create main router to add custom endpoints
router = APIRouter(prefix="/clients-providers")

# CSV import (mismo flujo que customs_brokers/imports: upload → scan → commit)
router.include_router(imports_router, prefix="/imports", tags=["clients_and_providers / csv_import"])


@router.get("/", response_model=ClientProviderPaginatedResponseDTO)
async def get_clients_and_providers(
    company_id: int = Query(..., description="Company ID"),
    name: Optional[str] = Query(None, description="Filter by name (contains)"),
    rfc: Optional[str] = Query(None, description="Filter by RFC/TAX-ID (contains)"),
    type: Optional[ClientOrProviderEnum] = Query(
        None, description="Type of entity (client or provider)"
    ),
    active: Optional[bool] = Query(None, description="Active status"),
    page: Optional[int] = Query(None, ge=1, description="Page number (1-based)"),
    page_size: Optional[int] = Query(
        None, ge=1, le=1000, description="Page size when using page-based pagination"
    ),
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=1000),
    db: Session = Depends(get_core_db),
    current_user: dict = Depends(get_current_user),
):
    """Get clients and providers"""
    tenant_id = validate_access_to_resource(db, company_id, current_user, ["partners_mgmt.view"])

    resolved_limit = page_size if page_size is not None else limit
    resolved_skip = ((page - 1) * resolved_limit) if page is not None else skip

    query = db.query(ClientProvider).options(
        joinedload(ClientProvider.address),
        joinedload(ClientProvider.programs)
    ).filter(
        ClientProvider.tenant_id == tenant_id,
        ClientProvider.company_id == company_id,
    )

    if name:
        query = query.filter(ClientProvider.name.ilike(f"%{name.strip()}%"))

    if rfc:
        query = query.filter(ClientProvider.rfc.ilike(f"%{rfc.strip()}%"))

    if type is not None:
        # Include 'both' type when filtering by client or provider
        query = query.filter(
            or_(
                ClientProvider.client_or_provider == type,
                ClientProvider.client_or_provider == ClientOrProviderEnum.BOTH
            )
        )

    if active is not None:
        query = query.filter(ClientProvider.is_active == active)

    total = query.count()
    clients = query.offset(resolved_skip).limit(resolved_limit).all()

    return {
        "items": [ClientProviderResponseDTO.model_validate(c) for c in clients],
        "total": total,
        "page": (resolved_skip // resolved_limit) + 1,
        "page_size": resolved_limit,
    }

@router.get("/{client_id}/basic", response_model=ClientProviderBasicDTO)
async def get_clients_and_providers_basic_info(
    client_id: int,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: dict = Depends(get_current_user),
):
    """Get basic information for a client/provider (without address and programs)"""
    tenant_id = validate_access_to_resource(db, company_id, current_user, ["partners_mgmt.view"])

    client = ClientProviderService.get_by_id(db, client_id, tenant_id, company_id)
    if not client:
        raise HTTPException(status_code=404, detail="Client/Provider not found")

    return ClientProviderBasicDTO.model_validate(client)


@router.post("/", response_model=ClientProviderResponseDTO)
async def create_client_provider(
    client_data: ClientProviderCreateDTO,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: dict = Depends(get_current_user),
):
    """Create a new client/provider"""
    tenant_id = validate_access_to_resource(db, company_id, current_user, ["partners_mgmt.create"])

    return ClientProviderService.create(db, client_data, tenant_id, company_id)


@router.patch("/{client_id}", response_model=ClientProviderResponseDTO)
async def update_client_provider(
    client_id: int,
    client_data: ClientProviderUpdateDTO,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: dict = Depends(get_current_user),
):
    """Update a client/provider"""
    tenant_id = validate_access_to_resource(db, company_id, current_user, ["partners_mgmt.edit"])

    client = ClientProviderService.update(
        db, client_id, tenant_id, company_id, client_data
    )
    if not client:
        raise HTTPException(status_code=404, detail="Client/Provider not found")

    return client

@router.get("/{client_id}", response_model=ClientProviderResponseDTO)
async def get_client_provider_detail(
    client_id: int,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: dict = Depends(get_current_user),
):
    """
    Obtener un cliente/proveedor completo por ID.
    Esta es la ruta que tu formulario necesita para cargar los datos.
    """
    tenant_id = validate_access_to_resource(db, company_id, current_user, ["partners_mgmt.view"])

    # Usamos el servicio para buscar por ID
    client = ClientProviderService.get_by_id(db, client_id, tenant_id, company_id)
    
    if not client:
        raise HTTPException(status_code=404, detail="Client/Provider not found")

    return client

@router.delete("/{client_id}", response_model=bool)
async def delete_client_provider(
    client_id: int,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: dict = Depends(get_current_user),
):
    """Delete a client/provider"""
    tenant_id = validate_access_to_resource(db, company_id, current_user, ["partners_mgmt.delete"])

    success = ClientProviderService.delete(db, client_id, tenant_id, company_id)
    if not success:
        raise HTTPException(status_code=404, detail="Client/Provider not found")

    return success
