"use client"

import React, { useCallback, useEffect, useRef, useState } from "react"
import {
  AlertTriangle,
  ChevronDown,
  ChevronRight,
  Plus,
  RotateCcw,
  Trash2,
} from "lucide-react"
import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils"
import {
  AlarmThreshold,
  ThresholdUpdate,
  ThresholdCreate,
  fetchThresholds,
  updateThreshold,
  createThreshold,
  deleteThreshold,
  resetThresholds,
} from "@/lib/api"

// ── Labels ────────────────────────────────────────────────────────────────────

const SENSOR_TYPE_LABELS: Record<string, string> = {
  temperature:        "Temperature (°C)",
  humidity:           "Humidity (%)",
  power_kw:           "Rack Power (kW)",
  pdu_imbalance:      "Phase Imbalance (%)",
  ups_charge:         "UPS Battery Charge (%)",
  ups_load:           "UPS Load (%)",
  ups_runtime:        "UPS Runtime (min)",
  gen_fuel_pct:       "Generator Fuel (%)",
  gen_load_pct:       "Generator Load (%)",
  gen_coolant_c:      "Generator Coolant (°C)",
  gen_oil_press:      "Generator Oil Pressure (bar)",
  cooling_cap_pct:    "CRAC Capacity (%)",
  cooling_cop:        "CRAC COP",
  cooling_comp_load:  "Compressor Load (%)",
  cooling_high_press: "High-Side Pressure (bar)",
  cooling_low_press:  "Low-Side Pressure (bar)",
  cooling_superheat:  "Discharge Superheat (°C)",
  cooling_filter_dp:  "Filter Delta-P (Pa)",
  cooling_return:     "Return Air Temp (°C)",
  net_pkt_loss_pct:   "Packet Loss (%)",
  net_temp_c:         "Switch Temperature (°C)",
  ats_ua_v:           "Utility A Voltage (V)",
  chiller_cop:        "Chiller COP",
}

// ── Groups ────────────────────────────────────────────────────────────────────

type GroupIcon = "Thermometer" | "Zap" | "Battery" | "Fuel" | "Wind" | "Network"

interface Group {
  label: string
  icon: GroupIcon
  types: string[]
}

const GROUPS: Group[] = [
  { label: "Temperature & Humidity", icon: "Thermometer", types: ["temperature", "humidity"] },
  { label: "Rack Power",             icon: "Zap",         types: ["power_kw", "pdu_imbalance"] },
  { label: "UPS",                    icon: "Battery",      types: ["ups_charge", "ups_load", "ups_runtime"] },
  { label: "Generator",              icon: "Fuel",         types: ["gen_fuel_pct", "gen_load_pct", "gen_coolant_c", "gen_oil_press"] },
  { label: "Cooling / CRAC",         icon: "Wind",         types: ["cooling_cap_pct", "cooling_cop", "cooling_comp_load", "cooling_high_press", "cooling_low_press", "cooling_superheat", "cooling_filter_dp", "cooling_return"] },
  { label: "Network",                icon: "Network",      types: ["net_pkt_loss_pct", "net_temp_c", "ats_ua_v", "chiller_cop"] },
]

// ── Group icon renderer ───────────────────────────────────────────────────────

function GroupIconEl({ icon }: { icon: GroupIcon }) {
  const cls = "size-4 shrink-0"
  switch (icon) {
    case "Thermometer":
      return (
        <svg className={cls} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2}>
          <path d="M14 14.76V3.5a2.5 2.5 0 0 0-5 0v11.26a4.5 4.5 0 1 0 5 0z" />
        </svg>
      )
    case "Zap":
      return (
        <svg className={cls} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2}>
          <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
        </svg>
      )
    case "Battery":
      return (
        <svg className={cls} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2}>
          <rect x="1" y="6" width="18" height="12" rx="2" ry="2" />
          <line x1="23" y1="13" x2="23" y2="11" />
        </svg>
      )
    case "Fuel":
      return (
        <svg className={cls} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2}>
          <path d="M3 22V8l6-6h6l6 6v14H3z" />
          <rect x="8" y="13" width="8" height="5" />
          <path d="M8 5h8" />
        </svg>
      )
    case "Wind":
      return (
        <svg className={cls} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2}>
          <path d="M9.59 4.59A2 2 0 1 1 11 8H2m10.59 11.41A2 2 0 1 0 14 16H2m15.73-8.27A2.5 2.5 0 1 1 19.5 12H2" />
        </svg>
      )
    case "Network":
      return (
        <svg className={cls} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={2}>
          <rect x="9" y="2" width="6" height="4" rx="1" />
          <rect x="1" y="18" width="6" height="4" rx="1" />
          <rect x="17" y="18" width="6" height="4" rx="1" />
          <path d="M12 6v4M4 18v-4h16v4M12 10h8v4M12 10H4v4" />
        </svg>
      )
  }
}

// ── Status toast ──────────────────────────────────────────────────────────────

interface Toast {
  id: number
  message: string
  type: "success" | "error"
}

// ── Save indicator per row ────────────────────────────────────────────────────

type SaveState = "idle" | "saving" | "saved" | "error"

// ── Row component ─────────────────────────────────────────────────────────────

interface RowProps {
  threshold: AlarmThreshold
  onUpdate: (id: number, patch: ThresholdUpdate) => Promise<void>
  onDelete: (id: number) => void
}

function ThresholdRow({ threshold, onUpdate, onDelete }: RowProps) {
  const [localValue, setLocalValue] = useState(String(threshold.threshold_value))
  const [saveState, setSaveState] = useState<SaveState>("idle")
  const saveTimer = useRef<ReturnType<typeof setTimeout> | null>(null)

  // Keep local value in sync if parent updates (e.g. after reset)
  useEffect(() => {
    setLocalValue(String(threshold.threshold_value))
  }, [threshold.threshold_value])

  const signalSave = async (patch: ThresholdUpdate) => {
    setSaveState("saving")
    try {
      await onUpdate(threshold.id, patch)
      setSaveState("saved")
    } catch {
      setSaveState("error")
    } finally {
      if (saveTimer.current) clearTimeout(saveTimer.current)
      saveTimer.current = setTimeout(() => setSaveState("idle"), 1800)
    }
  }

  const handleValueBlur = () => {
    const parsed = parseFloat(localValue)
    if (isNaN(parsed)) {
      setLocalValue(String(threshold.threshold_value))
      return
    }
    if (parsed !== threshold.threshold_value) {
      signalSave({ threshold_value: parsed })
    }
  }

  const handleSeverityToggle = () => {
    const next = threshold.severity === "warning" ? "critical" : "warning"
    signalSave({ severity: next })
  }

  const handleEnabledToggle = () => {
    signalSave({ enabled: !threshold.enabled })
  }

  const directionBadge =
    threshold.direction === "above" ? (
      <span className="inline-flex items-center gap-0.5 rounded px-1.5 py-0.5 text-xs font-semibold bg-orange-100 text-orange-700 dark:bg-orange-900/40 dark:text-orange-300">
        ▲ Above
      </span>
    ) : (
      <span className="inline-flex items-center gap-0.5 rounded px-1.5 py-0.5 text-xs font-semibold bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300">
        ▼ Below
      </span>
    )

  const severityBadge =
    threshold.severity === "critical" ? (
      <button
        onClick={handleSeverityToggle}
        title="Click to toggle severity"
        className="inline-flex items-center gap-0.5 rounded px-1.5 py-0.5 text-xs font-semibold bg-red-100 text-red-700 dark:bg-red-900/40 dark:text-red-300 hover:opacity-80 transition-opacity cursor-pointer"
      >
        Critical
      </button>
    ) : (
      <button
        onClick={handleSeverityToggle}
        title="Click to toggle severity"
        className="inline-flex items-center gap-0.5 rounded px-1.5 py-0.5 text-xs font-semibold bg-amber-100 text-amber-700 dark:bg-amber-900/40 dark:text-amber-300 hover:opacity-80 transition-opacity cursor-pointer"
      >
        Warning
      </button>
    )

  const saveIndicator =
    saveState === "saving" ? (
      <span className="text-xs text-muted-foreground animate-pulse">Saving…</span>
    ) : saveState === "saved" ? (
      <span className="text-xs text-emerald-600 dark:text-emerald-400">Saved</span>
    ) : saveState === "error" ? (
      <span className="text-xs text-red-500">Error</span>
    ) : null

  return (
    <tr
      className={cn(
        "border-b border-border/50 last:border-0 transition-colors",
        !threshold.enabled && "opacity-50"
      )}
    >
      {/* Sensor type */}
      <td className="py-2 pl-4 pr-3 text-sm font-medium text-foreground whitespace-nowrap">
        {SENSOR_TYPE_LABELS[threshold.sensor_type] ?? threshold.sensor_type}
      </td>

      {/* Direction */}
      <td className="py-2 px-3 text-sm">
        {directionBadge}
      </td>

      {/* Severity */}
      <td className="py-2 px-3 text-sm">
        {severityBadge}
      </td>

      {/* Value */}
      <td className="py-2 px-3">
        <div className="flex items-center gap-2">
          <input
            type="number"
            step="any"
            value={localValue}
            onChange={(e) => setLocalValue(e.target.value)}
            onBlur={handleValueBlur}
            disabled={threshold.locked}
            className={cn(
              "w-24 rounded-md border border-input bg-background px-2 py-1 text-sm text-right tabular-nums",
              "focus:outline-none focus:ring-2 focus:ring-ring/50",
              "disabled:cursor-not-allowed disabled:opacity-50"
            )}
          />
          <span className="w-12 text-xs">{saveIndicator}</span>
        </div>
      </td>

      {/* Enabled toggle */}
      <td className="py-2 px-3 text-center">
        <button
          onClick={handleEnabledToggle}
          role="switch"
          aria-checked={threshold.enabled}
          title={threshold.enabled ? "Disable threshold" : "Enable threshold"}
          className={cn(
            "relative inline-flex h-5 w-9 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors",
            "focus:outline-none focus:ring-2 focus:ring-ring/50",
            threshold.enabled
              ? "bg-primary"
              : "bg-muted"
          )}
        >
          <span
            className={cn(
              "pointer-events-none inline-block h-4 w-4 transform rounded-full bg-white shadow ring-0 transition-transform",
              threshold.enabled ? "translate-x-4" : "translate-x-0"
            )}
          />
        </button>
      </td>

      {/* Delete */}
      <td className="py-2 pl-3 pr-4 text-right">
        {!threshold.locked && (
          <button
            onClick={() => onDelete(threshold.id)}
            title="Delete threshold"
            className="text-muted-foreground hover:text-destructive transition-colors"
          >
            <Trash2 className="size-4" />
          </button>
        )}
      </td>
    </tr>
  )
}

// ── Group section ─────────────────────────────────────────────────────────────

interface GroupSectionProps {
  group: Group
  thresholds: AlarmThreshold[]
  onUpdate: (id: number, patch: ThresholdUpdate) => Promise<void>
  onDelete: (id: number) => void
}

function GroupSection({ group, thresholds, onUpdate, onDelete }: GroupSectionProps) {
  const [expanded, setExpanded] = useState(true)
  const rows = thresholds.filter((t) => group.types.includes(t.sensor_type))

  return (
    <div className="rounded-lg border border-border bg-card overflow-hidden">
      {/* Header */}
      <button
        onClick={() => setExpanded((v) => !v)}
        className="w-full flex items-center justify-between px-4 py-3 bg-muted/40 hover:bg-muted/60 transition-colors text-left"
      >
        <div className="flex items-center gap-2 font-semibold text-sm text-foreground">
          <GroupIconEl icon={group.icon} />
          {group.label}
          <span className="ml-1 text-xs font-normal text-muted-foreground">
            ({rows.length} rule{rows.length !== 1 ? "s" : ""})
          </span>
        </div>
        {expanded ? (
          <ChevronDown className="size-4 text-muted-foreground" />
        ) : (
          <ChevronRight className="size-4 text-muted-foreground" />
        )}
      </button>

      {/* Table */}
      {expanded && (
        <div className="overflow-x-auto">
          {rows.length === 0 ? (
            <p className="px-4 py-4 text-sm text-muted-foreground italic">
              No rules configured for this group.
            </p>
          ) : (
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b border-border/50 text-xs text-muted-foreground">
                  <th className="py-2 pl-4 pr-3 text-left font-medium">Sensor Type</th>
                  <th className="py-2 px-3 text-left font-medium">Direction</th>
                  <th className="py-2 px-3 text-left font-medium">Severity</th>
                  <th className="py-2 px-3 text-left font-medium">Value</th>
                  <th className="py-2 px-3 text-center font-medium">Enabled</th>
                  <th className="py-2 pl-3 pr-4 text-right font-medium">Delete</th>
                </tr>
              </thead>
              <tbody>
                {rows.map((t) => (
                  <ThresholdRow
                    key={t.id}
                    threshold={t}
                    onUpdate={onUpdate}
                    onDelete={onDelete}
                  />
                ))}
              </tbody>
            </table>
          )}
        </div>
      )}
    </div>
  )
}

// ── Add custom rule form ──────────────────────────────────────────────────────

interface AddRuleFormProps {
  siteId: string
  onCreated: (t: AlarmThreshold) => void
  onError: (msg: string) => void
}

const EMPTY_FORM: ThresholdCreate = {
  sensor_type:       "",
  threshold_value:   0,
  direction:         "above",
  severity:          "warning",
  message_template:  "",
}

function AddRuleForm({ siteId, onCreated, onError }: AddRuleFormProps) {
  const [form, setForm] = useState<ThresholdCreate>(EMPTY_FORM)
  const [busy, setBusy] = useState(false)

  const set = <K extends keyof ThresholdCreate>(k: K, v: ThresholdCreate[K]) =>
    setForm((f) => ({ ...f, [k]: v }))

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault()
    if (!form.sensor_type.trim()) return
    setBusy(true)
    try {
      const created = await createThreshold(siteId, form)
      onCreated(created)
      setForm(EMPTY_FORM)
    } catch {
      onError("Failed to create threshold rule.")
    } finally {
      setBusy(false)
    }
  }

  return (
    <div className="rounded-lg border border-dashed border-border bg-card p-4">
      <h3 className="flex items-center gap-2 text-sm font-semibold text-foreground mb-3">
        <Plus className="size-4" />
        Add Custom Rule
      </h3>

      <form onSubmit={handleSubmit}>
        <div className="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3">
          {/* Sensor type */}
          <div className="flex flex-col gap-1">
            <label className="text-xs font-medium text-muted-foreground">Sensor Type</label>
            <input
              type="text"
              placeholder="e.g. temperature"
              value={form.sensor_type}
              onChange={(e) => set("sensor_type", e.target.value)}
              className="rounded-md border border-input bg-background px-2 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-ring/50"
              required
            />
          </div>

          {/* Direction */}
          <div className="flex flex-col gap-1">
            <label className="text-xs font-medium text-muted-foreground">Direction</label>
            <select
              value={form.direction}
              onChange={(e) => set("direction", e.target.value)}
              className="rounded-md border border-input bg-background px-2 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-ring/50"
            >
              <option value="above">Above</option>
              <option value="below">Below</option>
            </select>
          </div>

          {/* Threshold value */}
          <div className="flex flex-col gap-1">
            <label className="text-xs font-medium text-muted-foreground">Threshold Value</label>
            <input
              type="number"
              step="any"
              value={form.threshold_value}
              onChange={(e) => set("threshold_value", parseFloat(e.target.value) || 0)}
              className="rounded-md border border-input bg-background px-2 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-ring/50"
              required
            />
          </div>

          {/* Severity */}
          <div className="flex flex-col gap-1">
            <label className="text-xs font-medium text-muted-foreground">Severity</label>
            <select
              value={form.severity}
              onChange={(e) => set("severity", e.target.value)}
              className="rounded-md border border-input bg-background px-2 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-ring/50"
            >
              <option value="warning">Warning</option>
              <option value="critical">Critical</option>
            </select>
          </div>

          {/* Message template */}
          <div className="flex flex-col gap-1 sm:col-span-2 lg:col-span-2">
            <label className="text-xs font-medium text-muted-foreground">
              Message Template{" "}
              <span className="font-normal opacity-70">
                — use <code className="text-xs">{"{sensor_id}"}</code> and <code className="text-xs">{"{value:.1f}"}</code>
              </span>
            </label>
            <input
              type="text"
              placeholder="{sensor_id} value {value:.1f} exceeded threshold"
              value={form.message_template}
              onChange={(e) => set("message_template", e.target.value)}
              className="rounded-md border border-input bg-background px-2 py-1.5 text-sm focus:outline-none focus:ring-2 focus:ring-ring/50"
            />
          </div>
        </div>

        <div className="mt-3 flex justify-end">
          <Button type="submit" size="sm" disabled={busy || !form.sensor_type.trim()}>
            <Plus className="size-4" />
            {busy ? "Adding…" : "Add Rule"}
          </Button>
        </div>
      </form>
    </div>
  )
}

// ── Main component ────────────────────────────────────────────────────────────

interface Props {
  siteId: string
}

export function ThresholdEditor({ siteId }: Props) {
  const [thresholds, setThresholds]       = useState<AlarmThreshold[]>([])
  const [loading, setLoading]             = useState(true)
  const [error, setError]                 = useState<string | null>(null)
  const [confirmReset, setConfirmReset]   = useState(false)
  const [resetting, setResetting]         = useState(false)
  const [toasts, setToasts]               = useState<Toast[]>([])
  const toastId                           = useRef(0)

  // ── Toast helpers ───────────────────────────────────────────────────────────

  const pushToast = useCallback((message: string, type: Toast["type"]) => {
    const id = ++toastId.current
    setToasts((prev) => [...prev, { id, message, type }])
    setTimeout(() => setToasts((prev) => prev.filter((t) => t.id !== id)), 3000)
  }, [])

  // ── Data loading ────────────────────────────────────────────────────────────

  const load = useCallback(async () => {
    setLoading(true)
    setError(null)
    try {
      const data = await fetchThresholds(siteId)
      setThresholds(data)
    } catch {
      setError("Failed to load alarm thresholds.")
    } finally {
      setLoading(false)
    }
  }, [siteId])

  useEffect(() => { load() }, [load])

  // ── Update handler ──────────────────────────────────────────────────────────

  const handleUpdate = useCallback(async (id: number, patch: ThresholdUpdate) => {
    // Optimistic update
    setThresholds((prev) =>
      prev.map((t) =>
        t.id === id
          ? {
              ...t,
              ...(patch.threshold_value !== undefined && { threshold_value: patch.threshold_value }),
              ...(patch.severity !== undefined && { severity: patch.severity as AlarmThreshold["severity"] }),
              ...(patch.enabled !== undefined && { enabled: patch.enabled }),
            }
          : t
      )
    )
    await updateThreshold(id, patch)
  }, [])

  // ── Delete handler ──────────────────────────────────────────────────────────

  const handleDelete = useCallback(async (id: number) => {
    setThresholds((prev) => prev.filter((t) => t.id !== id))
    try {
      await deleteThreshold(id)
      pushToast("Threshold deleted.", "success")
    } catch {
      pushToast("Failed to delete threshold.", "error")
      // Reload to restore
      load()
    }
  }, [load, pushToast])

  // ── Create handler ──────────────────────────────────────────────────────────

  const handleCreated = useCallback((t: AlarmThreshold) => {
    setThresholds((prev) => [...prev, t])
    pushToast("Rule added successfully.", "success")
  }, [pushToast])

  // ── Reset handler ───────────────────────────────────────────────────────────

  const handleReset = async () => {
    setResetting(true)
    try {
      await resetThresholds(siteId)
      setConfirmReset(false)
      pushToast("Thresholds reset to defaults.", "success")
      await load()
    } catch {
      pushToast("Failed to reset thresholds.", "error")
    } finally {
      setResetting(false)
    }
  }

  // ── Render ──────────────────────────────────────────────────────────────────

  return (
    <div className="relative space-y-4">
      {/* Toast container */}
      {toasts.length > 0 && (
        <div className="fixed bottom-6 right-6 z-50 flex flex-col gap-2 pointer-events-none">
          {toasts.map((toast) => (
            <div
              key={toast.id}
              className={cn(
                "rounded-lg px-4 py-2.5 text-sm font-medium shadow-lg animate-in fade-in slide-in-from-bottom-2",
                toast.type === "success"
                  ? "bg-emerald-600 text-white"
                  : "bg-destructive text-white"
              )}
            >
              {toast.message}
            </div>
          ))}
        </div>
      )}

      {/* Header */}
      <div className="flex items-center justify-between gap-4">
        <div>
          <h2 className="text-lg font-semibold text-foreground flex items-center gap-2">
            <AlertTriangle className="size-5 text-amber-500" />
            Alarm Thresholds
          </h2>
          <p className="text-sm text-muted-foreground mt-0.5">
            Configure threshold values that trigger alarms. Click a severity badge to toggle it; blur the value field to save.
          </p>
        </div>

        {/* Reset controls */}
        <div className="flex items-center gap-2 shrink-0">
          {confirmReset ? (
            <>
              <span className="text-sm text-muted-foreground">Are you sure?</span>
              <Button
                size="sm"
                variant="destructive"
                onClick={handleReset}
                disabled={resetting}
              >
                <RotateCcw className="size-4" />
                {resetting ? "Resetting…" : "Confirm Reset"}
              </Button>
              <Button
                size="sm"
                variant="outline"
                onClick={() => setConfirmReset(false)}
                disabled={resetting}
              >
                Cancel
              </Button>
            </>
          ) : (
            <Button
              size="sm"
              variant="outline"
              onClick={() => setConfirmReset(true)}
              className="border-destructive/40 text-destructive hover:bg-destructive/10 hover:text-destructive"
            >
              <RotateCcw className="size-4" />
              Reset to Defaults
            </Button>
          )}
        </div>
      </div>

      {/* Loading / Error */}
      {loading && (
        <div className="flex items-center justify-center py-16 text-sm text-muted-foreground">
          <svg className="animate-spin size-5 mr-2 text-muted-foreground" viewBox="0 0 24 24" fill="none">
            <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4" />
            <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z" />
          </svg>
          Loading thresholds…
        </div>
      )}

      {!loading && error && (
        <div className="rounded-lg border border-destructive/30 bg-destructive/10 px-4 py-3 text-sm text-destructive flex items-center gap-2">
          <AlertTriangle className="size-4 shrink-0" />
          {error}
          <Button size="xs" variant="outline" onClick={load} className="ml-auto">
            Retry
          </Button>
        </div>
      )}

      {/* Groups */}
      {!loading && !error && (
        <div className="space-y-3">
          {GROUPS.map((group) => (
            <GroupSection
              key={group.label}
              group={group}
              thresholds={thresholds}
              onUpdate={handleUpdate}
              onDelete={handleDelete}
            />
          ))}
        </div>
      )}

      {/* Add custom rule */}
      {!loading && !error && (
        <AddRuleForm
          siteId={siteId}
          onCreated={handleCreated}
          onError={(msg) => pushToast(msg, "error")}
        />
      )}
    </div>
  )
}
