"use client";

import Shell from "@/components/Shell";
import TrafficChart from "@/components/TrafficChart";
import { apiFetch, getCsrfFromCookie, WS_BASE } from "@/lib/api";
import { useEffect, useMemo, useRef, useState } from "react";

type Panel = { id:number; title:string; router_id:number; config:any };

export default function DashboardView({ params }: { params: { id: string } }) {
  const dashboardId = Number(params.id);
  const [panels, setPanels] = useState<Panel[]>([]);
  const [dashName, setDashName] = useState<string>("");
  const [err, setErr] = useState<string | null>(null);

  // create panel form
  const [title, setTitle] = useState("WAN");
  const [routerId, setRouterId] = useState<number>(1);
  const [interfaces, setInterfaces] = useState<string>("ether1");
  const [metrics, setMetrics] = useState<string>("rx_bps,tx_bps");
  const [intervalMs, setIntervalMs] = useState<number>(1000);
  const [windowPts, setWindowPts] = useState<number>(120);

  const [routers, setRouters] = useState<any[]>([]);
  const dataMap = useRef<Map<number, any[]>>(new Map()); // panelId -> points

  async function load() {
    setErr(null);
    try {
      const d = await apiFetch(`/api/dashboards/${dashboardId}`);
      setDashName(d.dashboard.name);
      setPanels(d.panels);
    } catch (e:any) { setErr(e.message || "error"); }
  }

  async function loadRouters() {
    try {
      const r = await apiFetch("/api/routers");
      setRouters(r);
      if (r?.length) setRouterId(r[0].id);
    } catch {}
  }

  useEffect(() => { load(); loadRouters(); }, [dashboardId]);

  async function createPanel() {
    setErr(null);
    try {
      const csrf = getCsrfFromCookie();
      const cfg = {
        interfaces: interfaces.split(",").map(s=>s.trim()).filter(Boolean),
        metrics: metrics.split(",").map(s=>s.trim()).filter(Boolean),
        interval_ms: intervalMs,
        window: windowPts
      };
      await apiFetch(`/api/dashboards/${dashboardId}/panels`, {
        method: "POST",
        headers: { "X-CSRF-Token": csrf || "" },
        body: JSON.stringify({ title, router_id: routerId, config: cfg })
      });
      await load();
    } catch (e:any) { setErr(e.message || "error"); }
  }

  return (
    <Shell>
      <div className="flex items-end justify-between gap-3">
        <div>
          <div className="text-2xl font-semibold">{dashName || "Dashboard"}</div>
          <div className="text-sm text-zinc-400">Live charts</div>
        </div>
      </div>

      {err && <div className="mt-4 text-sm text-red-400">{err}</div>}

      <div className="mt-6 p-4 rounded-xl border border-zinc-800 bg-zinc-950">
        <div className="font-medium">Add panel</div>
        <div className="mt-3 grid grid-cols-1 md:grid-cols-5 gap-2">
          <input className="px-3 py-2 rounded-lg bg-zinc-900 border border-zinc-700" value={title} onChange={e=>setTitle(e.target.value)} placeholder="title"/>
          <select className="px-3 py-2 rounded-lg bg-zinc-900 border border-zinc-700" value={routerId} onChange={e=>setRouterId(Number(e.target.value))}>
            {routers.map(r => <option key={r.id} value={r.id}>{r.name}</option>)}
          </select>
          <input className="px-3 py-2 rounded-lg bg-zinc-900 border border-zinc-700" value={interfaces} onChange={e=>setInterfaces(e.target.value)} placeholder="interfaces: ether1,ether2"/>
          <input className="px-3 py-2 rounded-lg bg-zinc-900 border border-zinc-700" value={metrics} onChange={e=>setMetrics(e.target.value)} placeholder="metrics: rx_bps,tx_bps"/>
          <button onClick={createPanel} className="px-3 py-2 rounded-lg bg-zinc-100 text-zinc-900">Create</button>
        </div>
        <div className="mt-2 grid grid-cols-1 md:grid-cols-5 gap-2 text-sm text-zinc-300">
          <div className="flex items-center gap-2">
            <span className="text-zinc-400">interval ms</span>
            <input className="w-28 px-2 py-1 rounded bg-zinc-900 border border-zinc-700" type="number" value={intervalMs} onChange={e=>setIntervalMs(Number(e.target.value))}/>
          </div>
          <div className="flex items-center gap-2">
            <span className="text-zinc-400">window pts</span>
            <input className="w-28 px-2 py-1 rounded bg-zinc-900 border border-zinc-700" type="number" value={windowPts} onChange={e=>setWindowPts(Number(e.target.value))}/>
          </div>
        </div>
      </div>

      <div className="mt-6 grid grid-cols-1 xl:grid-cols-2 gap-3">
        {panels.map(p => (
          <PanelCard key={p.id} panel={p} dataMapRef={dataMap} />
        ))}
      </div>
    </Shell>
  );
}

function PanelCard({ panel, dataMapRef }: { panel: Panel; dataMapRef: any }) {
  const [data, setData] = useState<any[]>([]);
  const wsRef = useRef<WebSocket | null>(null);

  const series = useMemo(() => {
    const cfg = panel.config || {};
    const ifs: string[] = cfg.interfaces || [];
    const ms: string[] = cfg.metrics || ["rx_bps","tx_bps"];
    const out: string[] = [];
    for (const i of (ifs.length ? ifs : ["*"])) {
      for (const m of ms) out.push(`${i}:${m}`);
    }
    return out;
  }, [panel]);

  useEffect(() => {
    let stop = false;
    const windowPts = Number(panel.config?.window || 120);

    const ws = new WebSocket(`${WS_BASE.replace("http","ws")}/ws/stream`);
    wsRef.current = ws;
    ws.onopen = () => {
      ws.send(JSON.stringify({ panelId: panel.id }));
    };
    ws.onmessage = (ev) => {
      try {
        const msg = JSON.parse(ev.data);
        if (msg.type === "traffic" && msg.panelId === panel.id) {
          const rows = msg.data || [];
          const now = new Date();
          const t = now.toLocaleTimeString();
          const points = (dataMapRef.current.get(panel.id) || []) as any[];

          // multi-series: iface:metric
          const pt: any = { t };
          for (const r of rows) {
            const iface = r.iface;
            pt[`${iface}:rx_bps`] = Number(r.rx_bps || 0);
            pt[`${iface}:tx_bps`] = Number(r.tx_bps || 0);
          }
          points.push(pt);
          while (points.length > windowPts) points.shift();
          dataMapRef.current.set(panel.id, points);
          if (!stop) setData([...points]);
        }
      } catch {}
    };
    const ping = setInterval(() => {
      try { ws.send("ping"); } catch {}
    }, 15000);

    return () => {
      stop = true;
      clearInterval(ping);
      try { ws.close(); } catch {}
    };
  }, [panel.id]);

  return (
    <div className="p-4 rounded-xl border border-zinc-800 bg-zinc-950">
      <div className="flex items-center justify-between">
        <div>
          <div className="font-medium">{panel.title}</div>
          <div className="text-xs text-zinc-400">panelId: {panel.id} • routerId: {panel.router_id}</div>
        </div>
      </div>
      <div className="mt-3">
        <TrafficChart data={data} series={series.filter(s => s !== "*:rx_bps" && s !== "*:tx_bps")} />
      </div>
    </div>
  );
}
