from typing import List, Dict, Any
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from core.database import get_core_db
from core.security import get_current_user, validate_access_to_resource
from api.v1.modules.a76.invoice_settings import services
from api.v1.modules.a76.invoice_settings.dto import InvoiceSettingsRequest, InvoiceSettingsResponse, OperationType
from api.v1.modules.core.permissions.service import PermissionService
from api.v1.modules.a76.invoices.permission_map import get_invoice_permission_base

router = APIRouter(
    prefix="/a76/invoice-settings",
    tags=["a76/invoice-settings"]
)


def _invoice_perm_base_for_settings(operation_type: OperationType, invoice_type: str) -> str:
    """Alineado con `permission_map.get_invoice_permission_base`."""
    return get_invoice_permission_base(operation_type, invoice_type)


def _can_read_invoice_settings_row(
    db: Session,
    company_id: int,
    current_user: Dict[str, Any],
    invoice_type: str,
    operation_type: OperationType,
) -> bool:
    """
    Ver configuración por tipo/op: settings_general.view O ver facturas de ese mismo contexto
    (para cargar defaults en alta/edición sin abrir la pantalla de parámetros).
    """
    user_roles = current_user.get("realm_access", {}).get("roles", [])
    if "admin" in user_roles:
        return True
    user_id = current_user.get("sub") or current_user.get("id")
    if not user_id:
        return False
    ps = PermissionService(db)
    if ps.has_permission(str(user_id), company_id, "settings_general.view"):
        return True
    base = _invoice_perm_base_for_settings(operation_type, invoice_type)
    return ps.has_permission(str(user_id), company_id, f"{base}.view")


@router.get("/{invoice_type}", response_model=InvoiceSettingsResponse)
def get_invoice_settings(
    invoice_type: str,
    operation_type: OperationType = Query(...),
    company_id: int = Query(...),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user),
):
    """Get settings for a specific invoice type and operation"""
    tenant_id = validate_access_to_resource(db, company_id, current_user)
    if not _can_read_invoice_settings_row(
        db, company_id, current_user, invoice_type, operation_type
    ):
        raise HTTPException(
            status_code=403,
            detail="Missing required permissions: settings_general.view "
            f"(o permiso de vista del tipo de factura solicitado, p. ej. {_invoice_perm_base_for_settings(operation_type, invoice_type)}.view)",
        )
    
    settings = services.get_settings(
        db,
        tenant_id,
        company_id,
        invoice_type,
        operation_type
    )
    
    if not settings:
        # Return empty default if not found, to simplify frontend logic
        return InvoiceSettingsResponse(
            invoice_type=invoice_type,
            operation_type=operation_type,
            settings={},
            id=0,
            tenant_id=tenant_id,
            company_id=company_id
        )
    return InvoiceSettingsResponse.model_validate(settings)

@router.get("/", response_model=List[InvoiceSettingsResponse])
def list_invoice_settings(
    company_id: int = Query(...),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user),
):
    """List all configured settings for validation or overview"""
    tenant_id = validate_access_to_resource(
        db,
        company_id,
        current_user,
        required_permissions=["settings_general.view"],
    )

    return services.list_settings(
        db,
        tenant_id,
        company_id
    )

@router.put("/", response_model=InvoiceSettingsResponse)
def save_invoice_settings(
    settings_data: InvoiceSettingsRequest,
    company_id: int = Query(...),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user),
):
    """Create or update invoice settings"""
    tenant_id = validate_access_to_resource(
        db,
        company_id,
        current_user,
        required_permissions=["settings_general.edit"],
    )
    
    return services.upsert_settings(
        db,
        tenant_id,
        company_id,
        settings_data
    )
