from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy import and_
from sqlalchemy.orm import Session
from sqlalchemy.exc import IntegrityError
from models.condiciones_imp import Condiciones_imp
from schemas.condiciones_imp import (
    Condiciones_impCreate,
    Condiciones_impUpdate,
    Condiciones_impOut,
    Condiciones_impSearch
)

from database import get_db

router = APIRouter()

# Crear Condicines Impositivas
@router.post("/", response_model=Condiciones_impOut)
def create_condiciones_imp(condiciones_imp: Condiciones_impCreate, db: Session = Depends(get_db)):
    if not condiciones_imp.descripcion:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="El campo descripcion es obligatorio"
        )
    
    if not condiciones_imp.siglas:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="El campo siglas es obligatorio"
        )

    # Crear la instancia de Condiciones_imp con los datos proporcionados
    db_condiciones_imp = Condiciones_imp(
        siglas=condiciones_imp.siglas,
        descripcion=condiciones_imp.descripcion,
        tasa_21=condiciones_imp.tasa_21,
        tasa_105=condiciones_imp.tasa_105,
        tasa_27=condiciones_imp.tasa_27
    )
    db.add(db_condiciones_imp)
    db.commit()
    db.refresh(db_condiciones_imp)

    return db_condiciones_imp  # SQLAlchemy convertirá el objeto correctamente

    # actualiza Condiciones impositivas
@router.put("/{id}", response_model=Condiciones_impOut)
def update_condiciones_imp(id: int, condiciones_imp: Condiciones_impUpdate, db: Session = Depends(get_db)):
    # Buscar el Condiciones Impositivas en la base de datos
    existing_condiciones_imp = db.query(Condiciones_imp).filter(Condiciones_imp.id == id).first()
    
    # Si no existe, lanzamos un error 404
    if not existing_condiciones_imp:
        raise HTTPException(status_code=404, detail="Condicion Impositiva no encontrado")
    
    # Obtener solo los valores que fueron enviados en la solicitud
    update_data = condiciones_imp.model_dump(exclude_unset=True)  # Pydantic v2

    if not update_data:
        raise HTTPException(status_code=400, detail="No se enviaron datos para actualizar")

    # Actualizar solo los campos proporcionados
    for key, value in update_data.items():
        setattr(existing_condiciones_imp, key, value)
    
    # Guardar los cambios solo si hay actualizaciones
    db.commit()
    db.refresh(existing_condiciones_imp)  # Obtener datos actualizados
    
    return existing_condiciones_imp

# Eliminar Condicion Imp.
@router.delete("/{id}")
def delete_condiciones_imp(id: int, db: Session = Depends(get_db)):
    condiciones_imp = db.query(Condiciones_imp).filter(Condiciones_imp.id == id).first()
    if not Condiciones_imp:
        raise HTTPException(status_code=404, detail="Condición Imp. no encontrado")
    db.delete(condiciones_imp)
    db.commit()
    return {"message": "Condición Imp. eliminado exitosamente"}

# Buscar Condición Imp.
@router.post("/buscar", response_model=list[Condiciones_impOut])
def search_condiciones_imp(filters: Condiciones_impSearch,db: Session = Depends(get_db)):
    query = db.query(Condiciones_imp)

    # Construir filtros dinámicamente
    conditions = []

    if filters.siglas:
        conditions.append(Condiciones_imp.siglas.ilike(f"%{filters.siglas}%"))

    if filters.descripcion:
        conditions.append(Condiciones_imp.descripcion.ilike(f"%{filters.descripcion}%"))


    if conditions:
        query = query.filter(and_(*conditions))

    condiciones_imp = query.all()

    if not condiciones_imp:
        raise HTTPException(status_code=404, detail="No se encontro Condicion Imp. indicada")

    return condiciones_imp