from __future__ import annotations
import uuid
import io
import base64
import socket
from datetime import datetime, date
from fastapi import APIRouter, Depends, HTTPException, Response
from fastapi.responses import HTMLResponse
from sqlalchemy.orm import Session
from pydantic import BaseModel
from typing import Optional, List
from app.database import get_db
from app.models.production import ProductionBatch, SeedLot, GerminationRecord, TransplantRecord
from app.models.plant import Plant, PlantVariety, PlantCategory
from app.models.supplier import Supplier
from app.models.employee import Employee
from app.models.treatment import Treatment, TreatmentDetail, HealthRecord, DiseasePestRecord
from app.services.auth import get_current_user

router = APIRouter(tags=["scan"])


def _get_server_host() -> str:
    try:
        s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        s.connect(("8.8.8.8", 80))
        ip = s.getsockname()[0]
        s.close()
        return ip
    except Exception:
        return "localhost"


def _get_scan_data(code: str, db: Session) -> dict:
    batch = db.query(ProductionBatch).filter(
        (ProductionBatch.id == code) | (ProductionBatch.batch_number == code)
    ).first()
    if not batch:
        return None

    plant = db.query(Plant).filter(Plant.id == batch.plant_id).first() if batch.plant_id else None
    variety = db.query(PlantVariety).filter(PlantVariety.id == plant.variety_id).first() if plant and plant.variety_id else None
    category = db.query(PlantCategory).filter(PlantCategory.id == plant.category_id).first() if plant and plant.category_id else None
    seed_lot = db.query(SeedLot).filter(SeedLot.id == batch.seed_lot_id).first() if batch.seed_lot_id else None
    supplier = db.query(Supplier).filter(Supplier.id == seed_lot.supplier_id).first() if seed_lot and seed_lot.supplier_id else None
    employee = db.query(Employee).filter(Employee.id == batch.employee_id).first() if batch.employee_id else None

    germination = db.query(GerminationRecord).filter(GerminationRecord.batch_id == batch.id).order_by(GerminationRecord.date).all()
    transplants = db.query(TransplantRecord).filter(TransplantRecord.batch_id == batch.id).order_by(TransplantRecord.date).all()
    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()

    timeline = []
    timeline.append({"date": batch.sowing_date.isoformat(), "event": "Sowing", "details": f"{batch.sown_quantity} seeds planted", "icon": "seed"})
    if seed_lot:
        timeline.append({"date": (seed_lot.purchase_date or batch.sowing_date).isoformat(), "event": "Seed Purchase", "details": f"Lot: {seed_lot.lot_number}", "icon": "purchase"})
    for g in germination:
        timeline.append({"date": g.date.isoformat(), "event": "Germination Check", "details": f"{g.germinated_quantity} germinated ({g.success_rate}%)", "icon": "germination"})
    for t in transplants:
        timeline.append({"date": t.date.isoformat(), "event": "Transplant", "details": f"{t.from_container} → {t.to_container} ({t.quantity})", "icon": "transplant"})
    for tr in treatments:
        detail_data = None
        detail_obj = db.query(TreatmentDetail).filter(TreatmentDetail.treatment_id == tr.id).first()
        if detail_obj:
            detail_data = {k: v for k, v in detail_obj.__dict__.items() if v is not None and k != '_sa_instance_state' and k != 'id' and k != 'treatment_id'}
        timeline.append({
            "date": tr.treatment_date.isoformat(),
            "event": tr.treatment_type.replace('_', ' ').title(),
            "details": tr.notes or str(detail_data) if detail_data else "",
            "icon": "treatment",
        })
    for h in health:
        timeline.append({"date": h.record_date.isoformat(), "event": "Health Check", "details": f"Score: {h.health_score}/100" if h.health_score else "", "icon": "health"})
    for d in diseases:
        timeline.append({"date": d.record_date.isoformat(), "event": f"{d.type.title()}: {d.name}", "details": f"Severity: {d.severity} ({d.status})", "icon": "disease"})

    timeline.sort(key=lambda x: x["date"])

    return {
        "batch_id": batch.id,
        "batch_number": batch.batch_number,
        "status": batch.status,
        "sowing_date": batch.sowing_date.isoformat(),
        "expected_ready_date": batch.expected_ready_date.isoformat() if batch.expected_ready_date else None,
        "sown_quantity": batch.sown_quantity,
        "current_quantity": batch.current_quantity,
        "tray_number": batch.tray_number,
        "location": batch.location,
        "plant_name": plant.name if plant else None,
        "plant_scientific": plant.scientific_name if plant else None,
        "variety_name": variety.name if variety else None,
        "category_name": category.name if category else None,
        "seed_lot_number": seed_lot.lot_number if seed_lot else None,
        "seed_supplier": supplier.name if seed_lot and seed_lot.supplier_id else None,
        "employee_name": employee.name if employee else None,
        "germination_records": [{"date": g.date.isoformat(), "quantity": g.germinated_quantity, "rate": g.success_rate} for g in germination],
        "transplant_records": [{"date": t.date.isoformat(), "from": t.from_container, "to": t.to_container, "quantity": t.quantity} for t in transplants],
        "treatments": [{"number": t.treatment_number, "type": t.treatment_type, "date": t.treatment_date.isoformat(), "status": t.status} for t in treatments],
        "health_records": [{"date": h.record_date.isoformat(), "score": h.health_score, "height": h.plant_height_cm, "mortality": h.mortality_rate} for h in health],
        "disease_pest_records": [{"date": d.record_date.isoformat(), "name": d.name, "type": d.type, "severity": d.severity, "status": d.status} for d in diseases],
        "timeline": timeline,
    }


def _generate_qr_base64(data: str) -> str:
    import qrcode
    qr = qrcode.QRCode(version=1, error_correction=qrcode.constants.ERROR_CORRECT_H, box_size=8, border=2)
    qr.add_data(data)
    qr.make(fit=True)
    img = qr.make_image(fill_color="#166534", back_color="white")
    buf = io.BytesIO()
    img.save(buf, format="PNG")
    return base64.b64encode(buf.getvalue()).decode()


def _generate_qr_svg(data: str) -> str:
    import qrcode
    import qrcode.image.svg
    qr = qrcode.QRCode(version=1, error_correction=qrcode.constants.ERROR_CORRECT_M, box_size=10, border=2)
    qr.add_data(data)
    qr.make(fit=True)
    factory = qrcode.image.svg.SvgPathImage
    img = qr.make_image(image_factory=factory)
    buf = io.BytesIO()
    img.save(buf)
    return buf.getvalue().decode()


def _scan_html(data: dict) -> str:
    status_colors = {
        "sowing": ("#f59e0b", "Sowing"),
        "germination": ("#3b82f6", "Germination"),
        "growing": ("#22c55e", "Growing"),
        "ready": ("#a855f7", "Ready"),
        "sold": ("#6b7280", "Sold"),
    }
    s_color, s_label = status_colors.get(data["status"], ("#6b7280", data["status"]))
    survival = round((data["current_quantity"] / data["sown_quantity"]) * 100, 1) if data["sown_quantity"] > 0 else 0

    germination_rate = None
    if data["germination_records"]:
        germination_rate = data["germination_records"][-1]["rate"]

    timeline_html = ""
    icon_map = {
        "seed": ("#f59e0b", "#fef3c7"),
        "purchase": ("#3b82f6", "#dbeafe"),
        "germination": ("#22c55e", "#dcfce7"),
        "transplant": ("#a855f7", "#f3e8ff"),
        "treatment": ("#14b8a6", "#ccfbf1"),
        "health": ("#10b981", "#d1fae5"),
        "disease": ("#ef4444", "#fee2e2"),
    }
    for item in data["timeline"]:
        ic, bg = icon_map.get(item["icon"], ("#6b7280", "#f3f4f6"))
        timeline_html += f'''
        <div style="display:flex;gap:12px;align-items:flex-start">
          <div style="width:36px;height:36px;border-radius:50%;background:{bg};display:flex;align-items:center;justify-content:center;flex-shrink:0">
            <div style="width:10px;height:10px;border-radius:50%;background:{ic}"></div>
          </div>
          <div style="flex:1;min-width:0;padding-bottom:16px;border-bottom:1px solid #f3f4f6">
            <div style="display:flex;justify-content:space-between;align-items:center">
              <span style="font-weight:600;color:#111827;font-size:14px">{item["event"]}</span>
              <span style="font-size:11px;color:#9ca3af;white-space:nowrap;margin-left:8px">{item["date"]}</span>
            </div>
            {f'<p style="font-size:13px;color:#6b7280;margin:2px 0 0">{item["details"]}</p>' if item.get("details") else ""}
          </div>
        </div>'''

    health_html = ""
    if data["health_records"]:
        cards = ""
        for h in data["health_records"]:
            score = h.get("score")
            score_color = "#22c55e" if score and score >= 80 else "#f59e0b" if score and score >= 50 else "#ef4444"
            cards += f'''
            <div style="background:#f9fafb;border-radius:10px;padding:12px;display:flex;justify-content:space-between;align-items:center">
              <span style="font-size:13px;color:#6b7280">{h["date"]}</span>
              <div style="display:flex;gap:12px;align-items:center">
                {f'<span style="font-weight:700;color:{score_color};font-size:14px">{score}/100</span>' if score else ""}
                {f'<span style="font-size:12px;color:#6b7280">{h["height"]}cm</span>' if h.get("height") else ""}
              </div>
            </div>'''
        health_html = f'''
        <div style="background:#fff;border:1px solid #e5e7eb;border-radius:14px;padding:16px;margin-bottom:16px">
          <h3 style="font-size:15px;font-weight:700;color:#111827;margin:0 0 12px;display:flex;align-items:center;gap:6px">
            <span style="color:#ef4444">♥</span> Health Records
          </h3>
          <div style="display:flex;flex-direction:column;gap:8px">{cards}</div>
        </div>'''

    disease_html = ""
    if data["disease_pest_records"]:
        cards = ""
        for d in data["disease_pest_records"]:
            sev_bg = "#fee2e2" if d["severity"] == "high" else "#ffedd5" if d["severity"] == "medium" else "#fef9c3"
            sev_color = "#dc2626" if d["severity"] == "high" else "#ea580c" if d["severity"] == "medium" else "#ca8a04"
            status_bg = "#d1fae5" if d["status"] == "resolved" else "#fee2e2"
            status_color = "#059669" if d["status"] == "resolved" else "#dc2626"
            cards += f'''
            <div style="background:#f9fafb;border-radius:10px;padding:12px;display:flex;justify-content:space-between;align-items:center">
              <div>
                <span style="font-weight:600;color:#111827;font-size:13px">{d["name"]}</span>
                <span style="font-size:12px;color:#9ca3af;margin-left:4px">({d["type"]})</span>
              </div>
              <div style="display:flex;gap:6px">
                <span style="background:{sev_bg};color:{sev_color};padding:2px 8px;border-radius:9999px;font-size:11px;font-weight:600">{d["severity"]}</span>
                <span style="background:{status_bg};color:{status_color};padding:2px 8px;border-radius:9999px;font-size:11px;font-weight:600">{d["status"]}</span>
              </div>
            </div>'''
        disease_html = f'''
        <div style="background:#fff;border:1px solid #e5e7eb;border-radius:14px;padding:16px;margin-bottom:16px">
          <h3 style="font-size:15px;font-weight:700;color:#111827;margin:0 0 12px;display:flex;align-items:center;gap:6px">
            <span style="color:#f97316">⚠</span> Disease & Pest Log
          </h3>
          <div style="display:flex;flex-direction:column;gap:8px">{cards}</div>
        </div>'''

    return f'''<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
  <title>{data["batch_number"]} - Traceability Report</title>
  <style>
    * {{ margin:0; padding:0; box-sizing:border-box; }}
    body {{ font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif; background:linear-gradient(135deg,#f0fdf4 0%,#ecfdf5 50%,#f0f9ff 100%); min-height:100vh; color:#111827; -webkit-font-smoothing:antialiased; }}
  </style>
</head>
<body>
  <div style="max-width:480px;margin:0 auto;padding:16px">
    <div style="background:linear-gradient(135deg,#166534,#059669);border-radius:18px;padding:24px;color:#fff;margin-bottom:16px;box-shadow:0 8px 30px rgba(22,101,52,0.25)">
      <p style="font-size:11px;text-transform:uppercase;letter-spacing:1.2px;color:#bbf7d0;margin-bottom:4px;font-weight:600">Seedling Traceability Report</p>
      <h1 style="font-size:24px;font-weight:800;margin-bottom:12px">{data["batch_number"]}</h1>
      <div style="display:inline-block;background:rgba(255,255,255,0.2);backdrop-filter:blur(4px);padding:4px 14px;border-radius:9999px;font-size:12px;font-weight:700">{s_label}</div>
      <div style="background:rgba(255,255,255,0.15);border-radius:10px;padding:10px;margin-top:14px">
        <div style="display:flex;justify-content:space-between;font-size:11px;color:#bbf7d0;margin-bottom:4px">
          <span>Growth Progress</span><span>{survival}%</span>
        </div>
        <div style="background:rgba(255,255,255,0.2);border-radius:9999px;height:8px">
          <div style="background:#fff;border-radius:9999px;height:8px;width:{survival}%"></div>
        </div>
      </div>
      <div style="display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin-top:16px;text-align:center">
        <div><p style="font-size:22px;font-weight:800">{data["sown_quantity"]}</p><p style="font-size:10px;color:#bbf7d0">Sown</p></div>
        <div><p style="font-size:22px;font-weight:800">{data["current_quantity"]}</p><p style="font-size:10px;color:#bbf7d0">Current</p></div>
        <div><p style="font-size:22px;font-weight:800">{survival}%</p><p style="font-size:10px;color:#bbf7d0">Survival</p></div>
      </div>
    </div>

    <div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:16px">
      <div style="background:#fff;border:1px solid #e5e7eb;border-radius:14px;padding:14px">
        <p style="font-size:11px;color:#9ca3af;text-transform:uppercase;letter-spacing:0.5px;margin-bottom:6px">🌱 Plant</p>
        <p style="font-size:14px;font-weight:700">{data["plant_name"] or "N/A"}</p>
        <p style="font-size:12px;color:#6b7280;font-style:italic">{data["plant_scientific"] or ""}</p>
        {f'<p style="font-size:11px;color:#6b7280;margin-top:4px">Variety: {data["variety_name"]}</p>' if data.get("variety_name") else ""}
        {f'<p style="font-size:11px;color:#6b7280">Category: {data["category_name"]}</p>' if data.get("category_name") else ""}
      </div>
      <div style="background:#fff;border:1px solid #e5e7eb;border-radius:14px;padding:14px">
        <p style="font-size:11px;color:#9ca3af;text-transform:uppercase;letter-spacing:0.5px;margin-bottom:6px">卡车 Seed Source</p>
        <p style="font-size:14px;font-weight:700">{data["seed_lot_number"] or "N/A"}</p>
        <p style="font-size:12px;color:#6b7280">Supplier: {data["seed_supplier"] or "N/A"}</p>
      </div>
    </div>

    <div style="background:#fff;border:1px solid #e5e7eb;border-radius:14px;padding:16px;margin-bottom:16px">
      <h3 style="font-size:15px;font-weight:700;color:#111827;margin:0 0 14px;display:flex;align-items:center;gap:6px">
        <span style="color:#059669">⏱</span> Complete Timeline
      </h3>
      <div>{timeline_html}</div>
    </div>

    {health_html}
    {disease_html}

    <div style="display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-bottom:16px">
      <div style="background:#fff;border:1px solid #e5e7eb;border-radius:14px;padding:12px;text-align:center">
        <p style="font-size:20px;font-weight:800;color:#111827">{len(data["treatments"])}</p>
        <p style="font-size:10px;color:#9ca3af">Treatments</p>
      </div>
      <div style="background:#fff;border:1px solid #e5e7eb;border-radius:14px;padding:12px;text-align:center">
        <p style="font-size:20px;font-weight:800;color:#111827">{germination_rate if germination_rate is not None else "N/A"}{"%" if germination_rate is not None else ""}</p>
        <p style="font-size:10px;color:#9ca3af">Germination</p>
      </div>
      <div style="background:#fff;border:1px solid #e5e7eb;border-radius:14px;padding:12px;text-align:center">
        <p style="font-size:20px;font-weight:800;color:#111827">{len(data["transplant_records"])}</p>
        <p style="font-size:10px;color:#9ca3af">Transplants</p>
      </div>
    </div>

    <div style="text-align:center;padding:16px 0 24px">
      <p style="font-size:11px;color:#9ca3af">Generated by NurseryOps</p>
      <p style="font-size:11px;color:#d1d5db;margin-top:2px">Batch: {data["batch_number"]} · {data["sowing_date"]}</p>
    </div>
  </div>
</body>
</html>'''


@router.get("/scan/{code}")
def scan_batch(code: str, db: Session = Depends(get_db)):
    data = _get_scan_data(code, db)
    if not data:
        raise HTTPException(status_code=404, detail="Batch not found")
    return data


@router.get("/scan-page/{code}", response_class=HTMLResponse)
def scan_page(code: str, db: Session = Depends(get_db)):
    data = _get_scan_data(code, db)
    if not data:
        return HTMLResponse(
            content="<!DOCTYPE html><html><head><meta charset='utf-8'><meta name='viewport' content='width=device-width,initial-scale=1'><title>Not Found</title></head><body style='font-family:sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;background:#f9fafb'><div style='text-align:center'><h1 style='font-size:48px;margin:0'>🔍</h1><h2 style='margin:12px 0 8px'>Batch Not Found</h2><p style='color:#6b7280'>The batch code <b>{code}</b> does not exist.</p></div></body></html>",
            status_code=404,
        )
    return HTMLResponse(content=_scan_html(data), status_code=200)


@router.get("/qr/{batch_id}")
def get_batch_qr(batch_id: str, request_url: str = None, db: Session = Depends(get_db)):
    batch = db.query(ProductionBatch).filter(
        (ProductionBatch.id == batch_id) | (ProductionBatch.batch_number == batch_id)
    ).first()
    if not batch:
        raise HTTPException(status_code=404, detail="Batch not found")
    host = _get_server_host()
    scan_url = f"http://{host}:8000/s/{batch.batch_number}"
    qr_b64 = _generate_qr_base64(scan_url)
    return {
        "batch_number": batch.batch_number,
        "qr_base64": qr_b64,
        "scan_url": scan_url,
    }


@router.get("/qr/batch/{batch_id}/print")
def get_batch_qr_print(batch_id: str, db: Session = Depends(get_db)):
    batch = db.query(ProductionBatch).filter(ProductionBatch.id == batch_id).first()
    if not batch:
        raise HTTPException(status_code=404, detail="Batch not found")
    plant = db.query(Plant).filter(Plant.id == batch.plant_id).first() if batch.plant_id else None
    host = _get_server_host()
    scan_url = f"http://{host}:8000/s/{batch.batch_number}"
    qr_b64 = _generate_qr_base64(scan_url)
    return {
        "batch_number": batch.batch_number,
        "plant_name": plant.name if plant else "N/A",
        "sowing_date": batch.sowing_date.isoformat(),
        "status": batch.status,
        "quantity": batch.sown_quantity,
        "qr_base64": qr_b64,
        "scan_url": scan_url,
    }
