from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from app.db.session import SessionLocal
from app.schemas.client import ClientCreate, ClientOut, ClientUpdate
from app.crud.clients import get_client, get_client_by_cedula, get_clients, create_client, update_client, delete_client

router = APIRouter()

# Dependency
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

@router.post("/", response_model=ClientOut)
def create_client_endpoint(client_in: ClientCreate, db: Session = Depends(get_db)):
    cedula = client_in.cedula.strip()
    existing = get_client_by_cedula(db, cedula)
    if existing:
        raise HTTPException(status_code=409, detail="Ya existe un cliente registrado con esa cédula.")

    payload = client_in.model_dump()
    payload["cedula"] = cedula
    client = create_client(db, client_data=payload)
    return client

@router.get("/search/{cedula}", response_model=ClientOut)
def search_client_by_cedula(cedula: str, db: Session = Depends(get_db)):
    client = get_client_by_cedula(db, cedula)
    if not client:
        raise HTTPException(status_code=404, detail="Cliente no registrado")
    return client

@router.get("/", response_model=list[ClientOut])
def list_clients(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
    return get_clients(db, skip=skip, limit=limit)

@router.get("/{client_id}", response_model=ClientOut)
def get_client_endpoint(client_id: int, db: Session = Depends(get_db)):
    client = get_client(db, client_id)
    if not client:
        raise HTTPException(status_code=404, detail="Client not found")
    return client

@router.put("/{client_id}", response_model=ClientOut)
def update_client_endpoint(client_id: int, updates: ClientUpdate, db: Session = Depends(get_db)):
    client = get_client(db, client_id)
    if not client:
        raise HTTPException(status_code=404, detail="Client not found")
    data = updates.model_dump(exclude_unset=True)
    if not data:
        return client

    if "cedula" in data and data["cedula"] is not None:
        cedula = data["cedula"].strip()
        existing = get_client_by_cedula(db, cedula)
        if existing and existing.id != client_id:
            raise HTTPException(status_code=409, detail="Ya existe otro cliente con esa cédula.")
        data["cedula"] = cedula

    return update_client(db, client, data)

@router.patch("/{client_id}", response_model=ClientOut)
def patch_client_endpoint(client_id: int, updates: ClientUpdate, db: Session = Depends(get_db)):
    client = get_client(db, client_id)
    if not client:
        raise HTTPException(status_code=404, detail="Client not found")
    data = updates.model_dump(exclude_unset=True)
    if not data:
        return client
    if "cedula" in data and data["cedula"] is not None:
        cedula = data["cedula"].strip()
        existing = get_client_by_cedula(db, cedula)
        if existing and existing.id != client_id:
            raise HTTPException(status_code=409, detail="Ya existe otro cliente con esa cédula.")
        data["cedula"] = cedula
    return update_client(db, client, data)

@router.delete("/{client_id}")
def delete_client_endpoint(client_id: int, db: Session = Depends(get_db)):
    client = get_client(db, client_id)
    if not client:
        raise HTTPException(status_code=404, detail="Client not found")
    delete_client(db, client)
    return {"ok": True}
