"""
CRUD for the lamp catalog. Each Aid references a lamp by id; the lamp's
voltage_min / voltage_max determine that aid's battery warning/alarm
thresholds (see compute_thresholds).
"""
from fastapi import APIRouter, Depends, HTTPException
from pydantic import BaseModel, Field
from sqlalchemy.orm import Session
from typing import Optional
import uuid

from database import get_db
from models.lamp import Lamp
from models.aid import Aid

router = APIRouter(prefix="/lamps", tags=["lamps"])


class LampIn(BaseModel):
    manufacturer:  str
    model:         str
    lamp_count:    int = 1
    voltage_min:   float = Field(..., gt=0)
    voltage_max:   float = Field(..., gt=0)
    warn_pct:      float = Field(20.0, ge=1, le=50)   # % of range → warning
    alarm_pct:     float = Field(10.0, ge=1, le=50)   # % of range → alarm
    notes:         Optional[str] = None


def compute_thresholds(vmin: float, vmax: float,
                       warn_pct: float = 20.0, alarm_pct: float = 10.0) -> dict:
    rng = vmax - vmin
    return {
        "warn_v":  round(vmin + rng * (warn_pct  / 100), 3),
        "alarm_v": round(vmin + rng * (alarm_pct / 100), 3),
    }


def _lamp_dict(l: Lamp) -> dict:
    th = compute_thresholds(l.voltage_min, l.voltage_max,
                            l.warn_pct or 20.0, l.alarm_pct or 10.0)
    return {
        "id":            l.id,
        "manufacturer":  l.manufacturer,
        "model":         l.model,
        "lamp_count":    l.lamp_count,
        "voltage_min":   l.voltage_min,
        "voltage_max":   l.voltage_max,
        "warn_pct":      l.warn_pct  or 20.0,
        "alarm_pct":     l.alarm_pct or 10.0,
        "notes":         l.notes,
        "warn_v":        th["warn_v"],
        "alarm_v":       th["alarm_v"],
    }


@router.get("/")
def list_lamps(db: Session = Depends(get_db)):
    return [_lamp_dict(l) for l in db.query(Lamp).order_by(Lamp.manufacturer, Lamp.model).all()]


@router.post("/")
def create_lamp(data: LampIn, db: Session = Depends(get_db)):
    if data.voltage_max <= data.voltage_min:
        raise HTTPException(400, "voltage_max must be greater than voltage_min")
    lamp = Lamp(id=str(uuid.uuid4()), **data.model_dump())
    db.add(lamp)
    db.commit(); db.refresh(lamp)
    return _lamp_dict(lamp)


@router.put("/{lamp_id}")
def update_lamp(lamp_id: str, data: LampIn, db: Session = Depends(get_db)):
    lamp = db.query(Lamp).filter(Lamp.id == lamp_id).first()
    if not lamp:
        raise HTTPException(404, "Lamp not found")
    if data.voltage_max <= data.voltage_min:
        raise HTTPException(400, "voltage_max must be greater than voltage_min")
    for k, v in data.model_dump().items():
        setattr(lamp, k, v)
    db.commit(); db.refresh(lamp)
    return _lamp_dict(lamp)


@router.delete("/{lamp_id}")
def delete_lamp(lamp_id: str, force: bool = False, db: Session = Depends(get_db)):
    in_use = db.query(Aid).filter(Aid.lamp_id == lamp_id).count()
    if in_use and not force:
        # Frontend will retry with force=true after user confirms
        raise HTTPException(409, f"Lamp is in use by {in_use} aid(s)")
    if in_use and force:
        # Unassign all aids that point at this lamp
        db.query(Aid).filter(Aid.lamp_id == lamp_id).update({"lamp_id": None})
    db.query(Lamp).filter(Lamp.id == lamp_id).delete()
    db.commit()
    return {"deleted": lamp_id, "unassigned_from": in_use}
