from __future__ import annotations
import uuid
from datetime import datetime, date
from typing import Optional, List
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy.orm import Session
from sqlalchemy import func as sqlfunc
from pydantic import BaseModel
from app.database import get_db
from app.models.treatment import Treatment, TreatmentDetail, HealthRecord, DiseasePestRecord, TreatmentSchedule
from app.models.production import ProductionBatch
from app.models.plant import Plant
from app.services.auth import get_current_user

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


def _gen_number(db: Session, prefix: str) -> str:
    last = db.query(Treatment.treatment_number).order_by(Treatment.treatment_number.desc()).first()
    if last and last[0]:
        try:
            num = int(last[0].split("-")[-1]) + 1
        except (ValueError, IndexError):
            num = 1
    else:
        num = 1
    return f"{prefix}-{date.today().year}-{num:06d}"


# ────────────────── Treatment Schemas ──────────────────

class TreatmentDetailData(BaseModel):
    watering_method: Optional[str] = None
    duration_minutes: Optional[float] = None
    quantity_liters: Optional[float] = None
    fertilizer_name: Optional[str] = None
    npk_ratio: Optional[str] = None
    dose: Optional[str] = None
    unit: Optional[str] = None
    application_method: Optional[str] = None
    next_application_date: Optional[date] = None
    product_name: Optional[str] = None
    active_ingredient: Optional[str] = None
    target_pest_disease: Optional[str] = None
    dosage: Optional[str] = None
    spray_method: Optional[str] = None
    weather_conditions: Optional[str] = None
    operator: Optional[str] = None
    hormone_name: Optional[str] = None
    purpose: Optional[str] = None
    expected_effect: Optional[str] = None
    pruning_reason: Optional[str] = None
    weeding_method: Optional[str] = None
    area_treated: Optional[str] = None
    time_spent_minutes: Optional[float] = None
    from_tray: Optional[str] = None
    to_polybag_pot: Optional[str] = None
    quantity_transplanted: Optional[int] = None
    survival_count: Optional[int] = None
    health_score: Optional[float] = None
    pest_observed: Optional[str] = None
    disease_observed: Optional[str] = None
    growth_status: Optional[str] = None
    photo_urls: Optional[str] = None
    corrective_type: Optional[str] = None

class TreatmentCreate(BaseModel):
    batch_id: str
    variety_id: Optional[str] = None
    block_bed: Optional[str] = None
    treatment_type: str
    treatment_date: Optional[date] = None
    treatment_time: Optional[str] = None
    growth_stage: Optional[str] = None
    employee_id: Optional[str] = None
    status: Optional[str] = "completed"
    notes: Optional[str] = None
    cost: Optional[float] = 0.0
    detail: Optional[TreatmentDetailData] = None

class TreatmentUpdate(BaseModel):
    batch_id: Optional[str] = None
    variety_id: Optional[str] = None
    block_bed: Optional[str] = None
    treatment_type: Optional[str] = None
    treatment_date: Optional[date] = None
    growth_stage: Optional[str] = None
    employee_id: Optional[str] = None
    status: Optional[str] = None
    notes: Optional[str] = None
    cost: Optional[float] = None

class TreatmentOut(BaseModel):
    id: str
    treatment_number: str
    batch_id: str
    variety_id: Optional[str] = None
    block_bed: Optional[str] = None
    treatment_type: str
    treatment_date: date
    treatment_time: Optional[str] = None
    growth_stage: Optional[str] = None
    employee_id: Optional[str] = None
    status: str
    notes: Optional[str] = None
    cost: float
    created_by: Optional[str] = None
    created_at: datetime
    detail: Optional[dict] = None
    model_config = {"from_attributes": True}


# ────────────────── Health Record Schemas ──────────────────

class HealthRecordCreate(BaseModel):
    batch_id: str
    record_date: Optional[date] = None
    plant_height_cm: Optional[float] = None
    leaf_count: Optional[int] = None
    stem_thickness_mm: Optional[float] = None
    plant_color: Optional[str] = None
    root_status: Optional[str] = None
    moisture_level: Optional[float] = None
    health_score: Optional[float] = None
    mortality_rate: Optional[float] = None
    notes: Optional[str] = None

class HealthRecordOut(BaseModel):
    id: str
    batch_id: str
    record_date: date
    plant_height_cm: Optional[float] = None
    leaf_count: Optional[int] = None
    stem_thickness_mm: Optional[float] = None
    plant_color: Optional[str] = None
    root_status: Optional[str] = None
    moisture_level: Optional[float] = None
    health_score: Optional[float] = None
    mortality_rate: Optional[float] = None
    notes: Optional[str] = None
    recorded_by: Optional[str] = None
    created_at: datetime
    model_config = {"from_attributes": True}


# ────────────────── Disease/Pest Schemas ──────────────────

class DiseasePestCreate(BaseModel):
    batch_id: str
    record_date: Optional[date] = None
    name: str
    type: str
    severity: Optional[str] = "low"
    symptoms: Optional[str] = None
    treatment_applied: Optional[str] = None
    product_used: Optional[str] = None
    follow_up_date: Optional[date] = None
    before_photo: Optional[str] = None
    after_photo: Optional[str] = None

class DiseasePestUpdate(BaseModel):
    severity: Optional[str] = None
    symptoms: Optional[str] = None
    treatment_applied: Optional[str] = None
    product_used: Optional[str] = None
    follow_up_date: Optional[date] = None
    after_photo: Optional[str] = None
    status: Optional[str] = None

class DiseasePestOut(BaseModel):
    id: str
    batch_id: str
    record_date: date
    name: str
    type: str
    severity: str
    symptoms: Optional[str] = None
    treatment_applied: Optional[str] = None
    product_used: Optional[str] = None
    follow_up_date: Optional[date] = None
    before_photo: Optional[str] = None
    after_photo: Optional[str] = None
    status: str
    recorded_by: Optional[str] = None
    created_at: datetime
    model_config = {"from_attributes": True}


# ────────────────── Schedule Schemas ──────────────────

class ScheduleCreate(BaseModel):
    batch_id: str
    treatment_type: str
    frequency_days: int
    next_due_date: date
    employee_id: Optional[str] = None
    notes: Optional[str] = None

class ScheduleUpdate(BaseModel):
    treatment_type: Optional[str] = None
    frequency_days: Optional[int] = None
    next_due_date: Optional[date] = None
    employee_id: Optional[str] = None
    notes: Optional[str] = None
    is_active: Optional[bool] = None

class ScheduleOut(BaseModel):
    id: str
    batch_id: str
    treatment_type: str
    frequency_days: int
    next_due_date: date
    employee_id: Optional[str] = None
    notes: Optional[str] = None
    is_active: bool
    created_by: Optional[str] = None
    created_at: datetime
    model_config = {"from_attributes": True}


# ══════════════════════════════════════════════════════
#  TREATMENT CRUD
# ══════════════════════════════════════════════════════

@router.get("")
def list_treatments(
    batch_id: Optional[str] = None,
    treatment_type: Optional[str] = None,
    status: Optional[str] = None,
    db: Session = Depends(get_db),
    _=Depends(get_current_user),
):
    q = db.query(Treatment)
    if batch_id:
        q = q.filter(Treatment.batch_id == batch_id)
    if treatment_type:
        q = q.filter(Treatment.treatment_type == treatment_type)
    if status:
        q = q.filter(Treatment.status == status)
    items = q.order_by(Treatment.treatment_date.desc()).all()
    result = []
    for t in items:
        d = t.__dict__.copy()
        detail_obj = db.query(TreatmentDetail).filter(TreatmentDetail.treatment_id == t.id).first()
        d["detail"] = detail_obj.__dict__ if detail_obj else None
        d.pop("_sa_instance_state", None)
        if d.get("detail"):
            d["detail"].pop("_sa_instance_state", None)
        result.append(d)
    return result


@router.post("")
def create_treatment(data: TreatmentCreate, db: Session = Depends(get_db), user=Depends(get_current_user)):
    batch = db.query(ProductionBatch).filter(ProductionBatch.id == data.batch_id).first()
    if not batch:
        raise HTTPException(status_code=404, detail="Batch not found")

    variety_id = data.variety_id
    if not variety_id and batch.plant_id:
        plant = db.query(Plant).filter(Plant.id == batch.plant_id).first()
        if plant:
            variety_id = plant.variety_id

    treatment = Treatment(
        treatment_number=_gen_number(db, "TRT"),
        batch_id=data.batch_id,
        variety_id=variety_id,
        block_bed=data.block_bed,
        treatment_type=data.treatment_type,
        treatment_date=data.treatment_date or date.today(),
        growth_stage=data.growth_stage or batch.status,
        employee_id=data.employee_id,
        status=data.status or "completed",
        notes=data.notes,
        cost=data.cost or 0.0,
        created_by=user.id,
    )
    db.add(treatment)
    db.flush()

    if data.detail:
        detail = TreatmentDetail(treatment_id=treatment.id, **data.detail.model_dump(exclude_unset=True))
        db.add(detail)

    db.commit()
    db.refresh(treatment)
    return {"id": treatment.id, "treatment_number": treatment.treatment_number, "status": "created"}


# ══════════════════════════════════════════════════════
#  HEALTH RECORDS
# ══════════════════════════════════════════════════════

@router.get("/health")
def list_health_records(
    batch_id: Optional[str] = None,
    db: Session = Depends(get_db),
    _=Depends(get_current_user),
):
    q = db.query(HealthRecord)
    if batch_id:
        q = q.filter(HealthRecord.batch_id == batch_id)
    return q.order_by(HealthRecord.record_date.desc()).all()


@router.post("/health")
def create_health_record(data: HealthRecordCreate, db: Session = Depends(get_db), user=Depends(get_current_user)):
    batch = db.query(ProductionBatch).filter(ProductionBatch.id == data.batch_id).first()
    if not batch:
        raise HTTPException(status_code=404, detail="Batch not found")
    rec = HealthRecord(
        batch_id=data.batch_id,
        record_date=data.record_date or date.today(),
        plant_height_cm=data.plant_height_cm,
        leaf_count=data.leaf_count,
        stem_thickness_mm=data.stem_thickness_mm,
        plant_color=data.plant_color,
        root_status=data.root_status,
        moisture_level=data.moisture_level,
        health_score=data.health_score,
        mortality_rate=data.mortality_rate,
        notes=data.notes,
        recorded_by=user.id,
    )
    db.add(rec)
    db.commit()
    db.refresh(rec)
    return {"id": rec.id, "status": "created"}


@router.delete("/health/{record_id}")
def delete_health_record(record_id: str, db: Session = Depends(get_db), _=Depends(get_current_user)):
    rec = db.query(HealthRecord).filter(HealthRecord.id == record_id).first()
    if not rec:
        raise HTTPException(status_code=404, detail="Record not found")
    db.delete(rec)
    db.commit()
    return {"status": "deleted"}


# ══════════════════════════════════════════════════════
#  DISEASE & PEST RECORDS
# ══════════════════════════════════════════════════════

@router.get("/disease-pest")
def list_disease_pest(
    batch_id: Optional[str] = None,
    status: Optional[str] = None,
    db: Session = Depends(get_db),
    _=Depends(get_current_user),
):
    q = db.query(DiseasePestRecord)
    if batch_id:
        q = q.filter(DiseasePestRecord.batch_id == batch_id)
    if status:
        q = q.filter(DiseasePestRecord.status == status)
    return q.order_by(DiseasePestRecord.record_date.desc()).all()


@router.post("/disease-pest")
def create_disease_pest(data: DiseasePestCreate, db: Session = Depends(get_db), user=Depends(get_current_user)):
    batch = db.query(ProductionBatch).filter(ProductionBatch.id == data.batch_id).first()
    if not batch:
        raise HTTPException(status_code=404, detail="Batch not found")
    rec = DiseasePestRecord(
        batch_id=data.batch_id,
        record_date=data.record_date or date.today(),
        name=data.name,
        type=data.type,
        severity=data.severity or "low",
        symptoms=data.symptoms,
        treatment_applied=data.treatment_applied,
        product_used=data.product_used,
        follow_up_date=data.follow_up_date,
        before_photo=data.before_photo,
        after_photo=data.after_photo,
        recorded_by=user.id,
    )
    db.add(rec)
    db.commit()
    db.refresh(rec)
    return {"id": rec.id, "status": "created"}


@router.put("/disease-pest/{record_id}")
def update_disease_pest(record_id: str, data: DiseasePestUpdate, db: Session = Depends(get_db), _=Depends(get_current_user)):
    rec = db.query(DiseasePestRecord).filter(DiseasePestRecord.id == record_id).first()
    if not rec:
        raise HTTPException(status_code=404, detail="Record not found")
    for k, v in data.model_dump(exclude_unset=True).items():
        setattr(rec, k, v)
    db.commit()
    return {"status": "updated"}


@router.delete("/disease-pest/{record_id}")
def delete_disease_pest(record_id: str, db: Session = Depends(get_db), _=Depends(get_current_user)):
    rec = db.query(DiseasePestRecord).filter(DiseasePestRecord.id == record_id).first()
    if not rec:
        raise HTTPException(status_code=404, detail="Record not found")
    db.delete(rec)
    db.commit()
    return {"status": "deleted"}


# ══════════════════════════════════════════════════════
#  TREATMENT SCHEDULES
# ══════════════════════════════════════════════════════

@router.get("/schedules")
def list_schedules(
    batch_id: Optional[str] = None,
    is_active: Optional[bool] = None,
    db: Session = Depends(get_db),
    _=Depends(get_current_user),
):
    q = db.query(TreatmentSchedule)
    if batch_id:
        q = q.filter(TreatmentSchedule.batch_id == batch_id)
    if is_active is not None:
        q = q.filter(TreatmentSchedule.is_active == is_active)
    return q.order_by(TreatmentSchedule.next_due_date).all()


@router.post("/schedules")
def create_schedule(data: ScheduleCreate, db: Session = Depends(get_db), user=Depends(get_current_user)):
    batch = db.query(ProductionBatch).filter(ProductionBatch.id == data.batch_id).first()
    if not batch:
        raise HTTPException(status_code=404, detail="Batch not found")
    sched = TreatmentSchedule(
        batch_id=data.batch_id,
        treatment_type=data.treatment_type,
        frequency_days=data.frequency_days,
        next_due_date=data.next_due_date,
        notes=data.notes,
        created_by=user.id,
    )
    db.add(sched)
    db.commit()
    db.refresh(sched)
    return {"id": sched.id, "status": "created"}


@router.put("/schedules/{schedule_id}")
def update_schedule(schedule_id: str, data: ScheduleUpdate, db: Session = Depends(get_db), _=Depends(get_current_user)):
    sched = db.query(TreatmentSchedule).filter(TreatmentSchedule.id == schedule_id).first()
    if not sched:
        raise HTTPException(status_code=404, detail="Schedule not found")
    for k, v in data.model_dump(exclude_unset=True).items():
        setattr(sched, k, v)
    db.commit()
    return {"status": "updated"}


@router.delete("/schedules/{schedule_id}")
def delete_schedule(schedule_id: str, db: Session = Depends(get_db), _=Depends(get_current_user)):
    sched = db.query(TreatmentSchedule).filter(TreatmentSchedule.id == schedule_id).first()
    if not sched:
        raise HTTPException(status_code=404, detail="Schedule not found")
    db.delete(sched)
    db.commit()
    return {"status": "deleted"}


@router.get("/schedules/due")
def get_due_schedules(db: Session = Depends(get_db), _=Depends(get_current_user)):
    today = date.today()
    return db.query(TreatmentSchedule).filter(
        TreatmentSchedule.is_active == True,
        TreatmentSchedule.next_due_date <= today,
    ).order_by(TreatmentSchedule.next_due_date).all()


# ══════════════════════════════════════════════════════
#  ANALYTICS
# ══════════════════════════════════════════════════════

@router.get("/analytics/summary")
def treatment_analytics(
    batch_id: Optional[str] = None,
    start_date: Optional[date] = None,
    end_date: Optional[date] = None,
    db: Session = Depends(get_db),
    _=Depends(get_current_user),
):
    q = db.query(Treatment)
    if batch_id:
        q = q.filter(Treatment.batch_id == batch_id)
    if start_date:
        q = q.filter(Treatment.treatment_date >= start_date)
    if end_date:
        q = q.filter(Treatment.treatment_date <= end_date)
    treatments = q.all()

    total_cost = sum(t.cost or 0 for t in treatments)
    total_count = len(treatments)

    type_counts = {}
    for t in treatments:
        type_counts[t.treatment_type] = type_counts.get(t.treatment_type, 0) + 1

    batch_ids = list(set(t.batch_id for t in treatments))
    cost_per_batch = {}
    if batch_ids:
        batches = db.query(ProductionBatch).filter(ProductionBatch.id.in_(batch_ids)).all()
        batch_map = {b.id: b for b in batches}
        for bid in batch_ids:
            batch_treatments = [t for t in treatments if t.batch_id == bid]
            batch_cost = sum(t.cost or 0 for t in batch_treatments)
            batch = batch_map.get(bid)
            batch_num = batch.batch_number if batch else bid[:8]
            cost_per_batch[batch_num] = {
                "batch_id": bid,
                "total_cost": batch_cost,
                "treatment_count": len(batch_treatments),
                "cost_per_plant": round(batch_cost / (batch.sown_quantity or 1), 2) if batch else 0,
            }

    # Survival rate from health records
    health_recs = db.query(HealthRecord).filter(HealthRecord.batch_id.in_(batch_ids)).all() if batch_ids else []
    avg_survival = 100.0
    mortality_records = [h for h in health_recs if h.mortality_rate is not None]
    if mortality_records:
        avg_survival = 100.0 - sum(h.mortality_rate for h in mortality_records) / len(mortality_records)

    # Disease/pest stats
    dp_recs = db.query(DiseasePestRecord).filter(DiseasePestRecord.batch_id.in_(batch_ids)).all() if batch_ids else []
    disease_count = len([d for d in dp_recs if d.type == "disease"])
    pest_count = len([d for d in dp_recs if d.type == "pest"])
    resolved_count = len([d for d in dp_recs if d.status == "resolved"])

    return {
        "total_treatments": total_count,
        "total_cost": round(total_cost, 2),
        "type_distribution": type_counts,
        "cost_per_batch": cost_per_batch,
        "survival_rate": round(avg_survival, 1),
        "disease_incidents": disease_count,
        "pest_incidents": pest_count,
        "incidents_resolved": resolved_count,
    }


@router.get("/analytics/batch-history/{batch_id}")
def batch_treatment_history(batch_id: str, db: Session = Depends(get_db), _=Depends(get_current_user)):
    treatments = db.query(Treatment).filter(Treatment.batch_id == batch_id).order_by(Treatment.treatment_date).all()
    health = db.query(HealthRecord).filter(HealthRecord.batch_id == batch_id).order_by(HealthRecord.record_date).all()
    diseases = db.query(DiseasePestRecord).filter(DiseasePestRecord.batch_id == batch_id).order_by(DiseasePestRecord.record_date).all()

    history = []
    for t in treatments:
        emp_name = None
        if t.employee_id:
            from app.models.employee import Employee
            emp = db.query(Employee).filter(Employee.id == t.employee_id).first()
            emp_name = emp.name if emp else None
        history.append({
            "date": t.treatment_date.isoformat(),
            "stage": t.growth_stage or "",
            "treatment": f"{t.treatment_type.replace('_', ' ').title()}{': ' + (t.notes or '') if t.notes else ''}",
            "performed_by": emp_name or "System",
            "result": t.status,
        })

    return {
        "batch_id": batch_id,
        "total_treatments": len(treatments),
        "total_health_records": len(health),
        "total_disease_pest_records": len(diseases),
        "history": history,
        "health_trend": [
            {
                "date": h.record_date.isoformat(),
                "health_score": h.health_score,
                "height_cm": h.plant_height_cm,
                "mortality": h.mortality_rate,
            }
            for h in health
        ],
        "disease_pest_log": [
            {
                "date": d.record_date.isoformat(),
                "name": d.name,
                "type": d.type,
                "severity": d.severity,
                "status": d.status,
            }
            for d in diseases
        ],
    }


# ══════════════════════════════════════════════════════
#  TREATMENT BY ID (must be last - catches {treatment_id})
# ══════════════════════════════════════════════════════

@router.get("/{treatment_id}")
def get_treatment(treatment_id: str, db: Session = Depends(get_db), _=Depends(get_current_user)):
    t = db.query(Treatment).filter(Treatment.id == treatment_id).first()
    if not t:
        raise HTTPException(status_code=404, detail="Treatment not found")
    d = t.__dict__.copy()
    detail_obj = db.query(TreatmentDetail).filter(TreatmentDetail.treatment_id == t.id).first()
    d["detail"] = detail_obj.__dict__ if detail_obj else None
    d.pop("_sa_instance_state", None)
    if d.get("detail"):
        d["detail"].pop("_sa_instance_state", None)
    return d


@router.put("/{treatment_id}")
def update_treatment(treatment_id: str, data: TreatmentUpdate, db: Session = Depends(get_db), _=Depends(get_current_user)):
    t = db.query(Treatment).filter(Treatment.id == treatment_id).first()
    if not t:
        raise HTTPException(status_code=404, detail="Treatment not found")
    for k, v in data.model_dump(exclude_unset=True).items():
        setattr(t, k, v)
    db.commit()
    return {"status": "updated"}


@router.delete("/{treatment_id}")
def delete_treatment(treatment_id: str, db: Session = Depends(get_db), _=Depends(get_current_user)):
    t = db.query(Treatment).filter(Treatment.id == treatment_id).first()
    if not t:
        raise HTTPException(status_code=404, detail="Treatment not found")
    db.query(TreatmentDetail).filter(TreatmentDetail.treatment_id == t.id).delete()
    db.delete(t)
    db.commit()
    return {"status": "deleted"}
