"use client";

import { useEffect, useState } from "react";
import {
  fetchRackHistory, fetchRackDevices,
  type RackHistory, type Device,
} from "@/lib/api";
import { Sheet, SheetContent, SheetHeader, SheetTitle } from "@/components/ui/sheet";
import { Skeleton } from "@/components/ui/skeleton";
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
import { TimeRangePicker } from "@/components/ui/time-range-picker";
import { Badge } from "@/components/ui/badge";
import {
  LineChart, Line, AreaChart, Area,
  XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer,
} from "recharts";
import { Thermometer, Zap, Droplets, Bell, Server } from "lucide-react";
import { cn } from "@/lib/utils";

interface Props {
  siteId: string;
  rackId: string | null;
  onClose: () => void;
}

// ── Helpers ───────────────────────────────────────────────────────────────────

function timeAgo(iso: string) {
  const diff = Date.now() - new Date(iso).getTime();
  const m = Math.floor(diff / 60000);
  if (m < 1) return "just now";
  if (m < 60) return `${m}m ago`;
  return `${Math.floor(m / 60)}h ago`;
}

function formatTime(iso: string) {
  return new Date(iso).toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
}

// ── Device type styles ────────────────────────────────────────────────────────

const TYPE_STYLES: Record<string, { bg: string; border: string; text: string; label: string }> = {
  server:      { bg: "bg-blue-500/15",   border: "border-blue-500/40",   text: "text-blue-300",   label: "Server"      },
  switch:      { bg: "bg-green-500/15",  border: "border-green-500/40",  text: "text-green-300",  label: "Switch"      },
  patch_panel: { bg: "bg-slate-500/15",  border: "border-slate-400/40",  text: "text-slate-300",  label: "Patch Panel" },
  pdu:         { bg: "bg-amber-500/15",  border: "border-amber-500/40",  text: "text-amber-300",  label: "PDU"         },
  storage:     { bg: "bg-purple-500/15", border: "border-purple-500/40", text: "text-purple-300", label: "Storage"     },
  firewall:    { bg: "bg-red-500/15",    border: "border-red-500/40",    text: "text-red-300",    label: "Firewall"    },
  kvm:         { bg: "bg-teal-500/15",   border: "border-teal-500/40",   text: "text-teal-300",   label: "KVM"         },
};

const TYPE_DOT: Record<string, string> = {
  server:      "bg-blue-400",
  switch:      "bg-green-400",
  patch_panel: "bg-slate-400",
  pdu:         "bg-amber-400",
  storage:     "bg-purple-400",
  firewall:    "bg-red-400",
  kvm:         "bg-teal-400",
};

// ── U-diagram ─────────────────────────────────────────────────────────────────

const TOTAL_U  = 42;
const U_PX     = 20; // height per U in pixels

type Segment = { u: number; height: number; device: Device | null };

function buildSegments(devices: Device[]): Segment[] {
  const sorted = [...devices].sort((a, b) => a.u_start - b.u_start);
  const segs: Segment[] = [];
  let u = 1;
  let i = 0;
  while (u <= TOTAL_U) {
    if (i < sorted.length && sorted[i].u_start === u) {
      const d = sorted[i];
      segs.push({ u, height: d.u_height, device: d });
      u += d.u_height;
      i++;
    } else {
      const nextU = i < sorted.length ? sorted[i].u_start : TOTAL_U + 1;
      const empty = Math.min(nextU, TOTAL_U + 1) - u;
      if (empty > 0) {
        segs.push({ u, height: empty, device: null });
        u += empty;
      } else {
        break;
      }
    }
  }
  return segs;
}

function RackDiagram({ devices, loading }: { devices: Device[]; loading: boolean }) {
  const [selected, setSelected] = useState<Device | null>(null);

  if (loading) {
    return (
      <div className="mt-3 space-y-1 flex-1">
        {Array.from({ length: 12 }).map((_, i) => (
          <Skeleton key={i} className="h-5 w-full" />
        ))}
      </div>
    );
  }

  const segments = buildSegments(devices);
  const totalPower = devices.reduce((s, d) => s + d.power_draw_w, 0);

  return (
    <div className="mt-3 flex flex-col flex-1 min-h-0 gap-3">
      {/* Legend */}
      <div className="flex flex-wrap gap-x-3 gap-y-1 shrink-0">
        {Object.entries(TYPE_STYLES).map(([type, style]) => (
          devices.some(d => d.type === type) ? (
            <div key={type} className="flex items-center gap-1">
              <span className={cn("w-2 h-2 rounded-sm", TYPE_DOT[type])} />
              <span className="text-[10px] text-muted-foreground">{style.label}</span>
            </div>
          ) : null
        ))}
      </div>

      {/* Rack diagram */}
      <div className="flex flex-col flex-1 min-h-0 border border-border/50 rounded-lg overflow-hidden">
        {/* Header */}
        <div className="flex bg-muted/40 border-b border-border/50 px-2 py-1 shrink-0">
          <span className="w-8 text-[9px] text-muted-foreground text-right pr-1 shrink-0">U</span>
          <span className="flex-1 text-[9px] text-muted-foreground pl-2">
            {devices[0]?.rack_id.toUpperCase() ?? "Rack"} — 42U
          </span>
          <span className="text-[9px] text-muted-foreground">{totalPower} W total</span>
        </div>

        {/* Slots */}
        <div className="flex-1 overflow-y-auto">
          {segments.map((seg) => {
            const style = seg.device ? (TYPE_STYLES[seg.device.type] ?? TYPE_STYLES.server) : null;
            const isSelected = selected?.device_id === seg.device?.device_id;

            return (
              <div
                key={seg.u}
                style={{ height: seg.height * U_PX }}
                className={cn(
                  "flex items-stretch border-b border-border/20 last:border-0",
                  seg.device && "cursor-pointer",
                )}
                onClick={() => setSelected(seg.device && isSelected ? null : seg.device)}
              >
                {/* U number */}
                <div className="w-8 flex items-start justify-end pt-1 pr-1.5 shrink-0">
                  <span className="text-[9px] text-muted-foreground/50 font-mono leading-none">
                    {seg.u}
                  </span>
                </div>

                {/* Device or empty */}
                <div className="flex-1 flex items-stretch py-px pr-1">
                  {seg.device ? (
                    <div className={cn(
                      "flex-1 rounded border flex items-center px-2 gap-2 transition-colors",
                      style!.bg, style!.border,
                      isSelected && "ring-1 ring-primary/50",
                    )}>
                      <span className={cn("text-xs font-medium truncate flex-1", style!.text)}>
                        {seg.device.name}
                      </span>
                      {seg.height >= 2 && (
                        <span className="text-[9px] text-muted-foreground/60 font-mono shrink-0">
                          {seg.device.ip !== "-" ? seg.device.ip : ""}
                        </span>
                      )}
                      <span className="text-[9px] text-muted-foreground/60 font-mono shrink-0">
                        {seg.device.u_height}U
                      </span>
                    </div>
                  ) : (
                    <div className="flex-1 rounded border border-dashed border-border/25 flex items-center px-2">
                      {seg.height > 1 && (
                        <span className="text-[9px] text-muted-foreground/25">
                          {seg.height}U empty
                        </span>
                      )}
                    </div>
                  )}
                </div>
              </div>
            );
          })}
        </div>
      </div>

      {/* Selected device detail */}
      {selected && (() => { // shrink-0 via parent gap
        const style = TYPE_STYLES[selected.type] ?? TYPE_STYLES.server;
        return (
          <div className={cn("rounded-lg border p-3 space-y-2", style.bg, style.border)}>
            <div className="flex items-start justify-between gap-2">
              <div>
                <p className={cn("text-sm font-semibold", style.text)}>{selected.name}</p>
                <p className="text-[10px] text-muted-foreground mt-0.5">{style.label}</p>
              </div>
              <span className="text-[10px] font-semibold px-2 py-0.5 rounded-full bg-green-500/10 text-green-400">
                ● Online
              </span>
            </div>
            <div className="grid grid-cols-2 gap-x-4 gap-y-1 text-xs">
              <div><span className="text-muted-foreground">Serial: </span><span className="font-mono">{selected.serial}</span></div>
              <div><span className="text-muted-foreground">IP: </span><span className="font-mono">{selected.ip !== "-" ? selected.ip : "—"}</span></div>
              <div><span className="text-muted-foreground">Position: </span><span>U{selected.u_start}–U{selected.u_start + selected.u_height - 1}</span></div>
              <div><span className="text-muted-foreground">Power: </span><span>{selected.power_draw_w} W</span></div>
            </div>
          </div>
        );
      })()}
    </div>
  );
}

// ── History tab ───────────────────────────────────────────────────────────────

function HistoryTab({ data, hours, onHoursChange, loading }: {
  data: RackHistory | null;
  hours: number;
  onHoursChange: (h: number) => void;
  loading: boolean;
}) {
  const chartData = (data?.history ?? []).map(p => ({ ...p, time: formatTime(p.bucket) }));
  const latest = chartData[chartData.length - 1];

  return (
    <div>
      <div className="flex justify-end mt-3 mb-4">
        <TimeRangePicker value={hours} onChange={onHoursChange} />
      </div>

      {loading ? (
        <div className="space-y-4">
          <Skeleton className="h-40 w-full" /><Skeleton className="h-40 w-full" />
        </div>
      ) : (
        <div className="space-y-5">
          {latest && (
            <div className="grid grid-cols-3 gap-3">
              <div className="rounded-lg bg-muted/30 p-3 text-center">
                <Thermometer className="w-4 h-4 mx-auto mb-1 text-primary" />
                <p className="text-lg font-bold">{latest.temperature !== undefined ? `${latest.temperature}°C` : "—"}</p>
                <p className="text-[10px] text-muted-foreground">Temperature</p>
              </div>
              <div className="rounded-lg bg-muted/30 p-3 text-center">
                <Zap className="w-4 h-4 mx-auto mb-1 text-amber-400" />
                <p className="text-lg font-bold">{latest.power_kw !== undefined ? `${latest.power_kw} kW` : "—"}</p>
                <p className="text-[10px] text-muted-foreground">Power</p>
              </div>
              <div className="rounded-lg bg-muted/30 p-3 text-center">
                <Droplets className="w-4 h-4 mx-auto mb-1 text-blue-400" />
                <p className="text-lg font-bold">{latest.humidity !== undefined ? `${latest.humidity}%` : "—"}</p>
                <p className="text-[10px] text-muted-foreground">Humidity</p>
              </div>
            </div>
          )}

          <div>
            <p className="text-xs font-medium text-muted-foreground mb-2 flex items-center gap-1">
              <Thermometer className="w-3 h-3" /> Temperature (°C)
            </p>
            <ResponsiveContainer width="100%" height={140}>
              <LineChart data={chartData} margin={{ top: 4, right: 4, left: -20, bottom: 0 }}>
                <CartesianGrid strokeDasharray="3 3" stroke="oklch(1 0 0 / 8%)" />
                <XAxis dataKey="time" tick={{ fontSize: 9, fill: "oklch(0.65 0.04 257)" }} tickLine={false} axisLine={false} />
                <YAxis tick={{ fontSize: 9, fill: "oklch(0.65 0.04 257)" }} tickLine={false} axisLine={false} domain={["auto", "auto"]} />
                <Tooltip
                  contentStyle={{ backgroundColor: "oklch(0.16 0.04 265)", border: "1px solid oklch(1 0 0 / 9%)", borderRadius: "6px", fontSize: "11px" }}
                  formatter={(v) => [`${v}°C`, "Temp"]}
                />
                <Line type="monotone" dataKey="temperature" stroke="oklch(0.62 0.17 212)" strokeWidth={2} dot={false} activeDot={{ r: 3 }} />
              </LineChart>
            </ResponsiveContainer>
          </div>

          <div>
            <p className="text-xs font-medium text-muted-foreground mb-2 flex items-center gap-1">
              <Zap className="w-3 h-3" /> Power Draw (kW)
            </p>
            <ResponsiveContainer width="100%" height={140}>
              <AreaChart data={chartData} margin={{ top: 4, right: 4, left: -20, bottom: 0 }}>
                <defs>
                  <linearGradient id="powerGrad" x1="0" y1="0" x2="0" y2="1">
                    <stop offset="5%"  stopColor="oklch(0.78 0.17 84)" stopOpacity={0.3} />
                    <stop offset="95%" stopColor="oklch(0.78 0.17 84)" stopOpacity={0} />
                  </linearGradient>
                </defs>
                <CartesianGrid strokeDasharray="3 3" stroke="oklch(1 0 0 / 8%)" />
                <XAxis dataKey="time" tick={{ fontSize: 9, fill: "oklch(0.65 0.04 257)" }} tickLine={false} axisLine={false} />
                <YAxis tick={{ fontSize: 9, fill: "oklch(0.65 0.04 257)" }} tickLine={false} axisLine={false} domain={[0, "auto"]} />
                <Tooltip
                  contentStyle={{ backgroundColor: "oklch(0.16 0.04 265)", border: "1px solid oklch(1 0 0 / 9%)", borderRadius: "6px", fontSize: "11px" }}
                  formatter={(v) => [`${v} kW`, "Power"]}
                />
                <Area type="monotone" dataKey="power_kw" stroke="oklch(0.78 0.17 84)" fill="url(#powerGrad)" strokeWidth={2} dot={false} />
              </AreaChart>
            </ResponsiveContainer>
          </div>
        </div>
      )}
    </div>
  );
}

// ── Alarms tab ────────────────────────────────────────────────────────────────

const severityColors: Record<string, string> = {
  critical: "bg-destructive/15 text-destructive border-destructive/30",
  warning:  "bg-amber-500/15 text-amber-400 border-amber-500/30",
  info:     "bg-blue-500/15 text-blue-400 border-blue-500/30",
};
const stateColors: Record<string, string> = {
  active:       "bg-destructive/10 text-destructive",
  acknowledged: "bg-amber-500/10 text-amber-400",
  resolved:     "bg-green-500/10 text-green-400",
};

function AlarmsTab({ data }: { data: RackHistory | null }) {
  return (
    <div className="mt-3">
      {!data || data.alarms.length === 0 ? (
        <p className="text-xs text-muted-foreground text-center py-8">
          No alarms on record for this rack.
        </p>
      ) : (
        <div className="space-y-2">
          {data.alarms.map((alarm) => (
            <div
              key={alarm.id}
              className={cn("rounded-lg border px-3 py-2 text-xs", severityColors[alarm.severity] ?? severityColors.info)}
            >
              <div className="flex items-center justify-between gap-2">
                <span className="font-medium">{alarm.message}</span>
                <Badge className={cn("text-[9px] border-0 shrink-0", stateColors[alarm.state] ?? stateColors.active)}>
                  {alarm.state}
                </Badge>
              </div>
              <p className="mt-0.5 opacity-70">{timeAgo(alarm.triggered_at)}</p>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

// ── Sheet ─────────────────────────────────────────────────────────────────────

export function RackDetailSheet({ siteId, rackId, onClose }: Props) {
  const [data, setData]             = useState<RackHistory | null>(null);
  const [devices, setDevices]       = useState<Device[]>([]);
  const [hours, setHours]           = useState(6);
  const [histLoading, setHistLoad]  = useState(false);
  const [devLoading, setDevLoad]    = useState(false);

  useEffect(() => {
    if (!rackId) { setData(null); setDevices([]); return; }

    setHistLoad(true);
    setDevLoad(true);

    fetchRackHistory(siteId, rackId, hours)
      .then(setData).catch(() => setData(null))
      .finally(() => setHistLoad(false));

    fetchRackDevices(siteId, rackId)
      .then(setDevices).catch(() => setDevices([]))
      .finally(() => setDevLoad(false));
  }, [siteId, rackId, hours]);

  const alarmCount = data?.alarms.filter(a => a.state === "active").length ?? 0;

  return (
    <Sheet open={!!rackId} onOpenChange={open => { if (!open) onClose(); }}>
      <SheetContent side="right" className="w-full sm:max-w-lg flex flex-col h-dvh overflow-hidden">
        <SheetHeader className="mb-2 shrink-0">
          <SheetTitle className="flex items-center gap-2">
            <Server className="w-4 h-4 text-primary" />
            {rackId?.toUpperCase() ?? ""}
          </SheetTitle>
          <p className="text-xs text-muted-foreground">Singapore DC01</p>
        </SheetHeader>

        <Tabs defaultValue="layout" className="flex flex-col flex-1 min-h-0">
          <TabsList className="w-full shrink-0">
            <TabsTrigger value="layout"  className="flex-1">Layout</TabsTrigger>
            <TabsTrigger value="history" className="flex-1">History</TabsTrigger>
            <TabsTrigger value="alarms"  className="flex-1">
              Alarms
              {alarmCount > 0 && (
                <span className="ml-1.5 text-[9px] font-bold text-destructive">{alarmCount}</span>
              )}
            </TabsTrigger>
          </TabsList>

          <TabsContent value="layout" className="flex flex-col flex-1 min-h-0 overflow-hidden mt-0">
            <RackDiagram devices={devices} loading={devLoading} />
          </TabsContent>

          <TabsContent value="history" className="flex-1 overflow-y-auto">
            <HistoryTab
              data={data}
              hours={hours}
              onHoursChange={setHours}
              loading={histLoading}
            />
          </TabsContent>

          <TabsContent value="alarms" className="flex-1 overflow-y-auto">
            <AlarmsTab data={data} />
          </TabsContent>
        </Tabs>
      </SheetContent>
    </Sheet>
  );
}
