/* eslint-disable */
// ============================================================
// DASHBOARD (PartialView: "Dashboard") + KPICardWidget
//
// Loads /api/rbac/related/{actionId}/KPICard → ordered KPI actionIds,
// then instantiates each as its own component with its own actionId.
// Each KPI loads its payload + /api/data/count/{actionId} for the value.
// ============================================================

const { useState: useD_S, useEffect: useD_E, useRef: useD_R } = React;

// -------- Sparkline (tiny inline chart for KPI delta) ---------
const Sparkline = ({ values = [], color, height = 28 }) => {
  if (values.length < 2) return null;
  const min = Math.min(...values), max = Math.max(...values);
  const range = max - min || 1;
  const w = 80;
  const points = values.map((v, i) => {
    const x = (i / (values.length - 1)) * w;
    const y = height - ((v - min) / range) * (height - 6) - 3;
    return [x, y];
  });
  const d = points.map(([x, y], i) => `${i === 0 ? "M" : "L"}${x.toFixed(1)},${y.toFixed(1)}`).join(" ");
  const fillD = `${d} L${w},${height} L0,${height} Z`;
  return (
    <svg width={w} height={height} viewBox={`0 0 ${w} ${height}`} className="overflow-visible">
      <path d={fillD} fill={color} opacity={0.12} />
      <path d={d} fill="none" stroke={color} strokeWidth={1.5} strokeLinecap="round" strokeLinejoin="round" />
      <circle cx={points[points.length - 1][0]} cy={points[points.length - 1][1]} r={2.5} fill={color} />
    </svg>
  );
};

// Generate a plausible sparkline series biased to land near `value`
function fakeSeries(value, dir) {
  const v = Number(value) || 0;
  const drift = dir === "down" ? -1 : dir === "flat" ? 0 : 1;
  const arr = [];
  for (let i = 0; i < 8; i++) {
    const noise = (Math.sin(i * 1.3 + v) + Math.cos(i * 0.7)) * (Math.abs(v) * 0.08 + 1);
    arr.push(v - (7 - i) * drift * (Math.abs(v) * 0.04 + 0.5) + noise);
  }
  arr[arr.length - 1] = v;
  return arr;
}

// -------- Single KPI card (PartialView: "KPICardWidget") ---------
const KPICard = ({ actionId, onToast, density = 1 }) => {
  const [payload, setPayload] = useD_S(null);
  const [value, setValue] = useD_S(null);
  const [loading, setLoading] = useD_S(true);

  useD_E(() => {
    let cancelled = false;
    setLoading(true);
    Promise.all([
      mockApi.getActionPayload(actionId),
      mockApi.countData(actionId),
    ]).then(([p, v]) => {
      if (cancelled) return;
      setPayload(p);
      setValue(v[0] ?? 0);
      setLoading(false);
    }).catch((e) => {
      if (cancelled) return;
      setLoading(false);
      onToast?.({ kind: "err", text: e.message });
    });
    return () => { cancelled = true; };
  }, [actionId]);

  if (loading || !payload) {
    return (
      <div className="card p-5">
        <Skeleton className="h-3 w-24 mb-3" />
        <Skeleton className="h-8 w-20 mb-3" />
        <Skeleton className="h-2.5 w-32" />
      </div>
    );
  }

  const mp = payload.MergedParams || {};
  const display = fmtNumber(value, mp.Format);
  const dir = mp.TrendDir || "flat";
  const trendColor = dir === "up" ? "var(--success)" : dir === "down" ? "var(--danger)" : "var(--muted)";
  const series = fakeSeries(value, dir);
  const isCustom = mp.Aggregation === "custom";

  return (
    <div className="card p-5 group relative overflow-hidden transition-transform hover:-translate-y-0.5" style={{ paddingTop: 14 * density, paddingBottom: 14 * density }}>
      <div className="flex items-start justify-between gap-2">
        <div className="flex items-center gap-2">
          <div className="h-8 w-8 inline-flex items-center justify-center rounded-md" style={{ background: "var(--primary-bg)", color: "var(--primary)" }}>
            <Icon name={mp.Icon || "barChart"} size={15} />
          </div>
          <div className="text-[12.5px] font-medium" style={{ color: "var(--muted)" }}>{mp.Title}</div>
        </div>
        <span className="text-[9.5px] font-mono uppercase tracking-wider px-1.5 py-0.5 rounded" style={{ background: "var(--surface-3)", color: "var(--subtle)" }}>
          {payload.ActionId}
        </span>
      </div>

      <div className="mt-3 flex items-end gap-3 flex-wrap">
        <div className="font-semibold tabular-nums" style={{ color: "var(--ink)", fontSize: 30, lineHeight: 1.0, letterSpacing: "-0.025em" }}>
          {display}
        </div>
        {!isCustom && (
          <div className="inline-flex items-center gap-1 text-[12px] font-medium pb-1" style={{ color: trendColor }}>
            <Icon name={dir === "up" ? "trendingUp" : dir === "down" ? "trendingDown" : "arrowRight"} size={12} />
            {mp.Trend}
          </div>
        )}
        <div className="flex-1" />
        <Sparkline values={series} color={trendColor} />
      </div>

      {/* hover affordance */}
      <div className="absolute inset-x-0 bottom-0 h-0.5" style={{ background: "linear-gradient(90deg, transparent, var(--primary), transparent)", opacity: 0, transition: "opacity 200ms" }}
           onMouseEnter={(e) => e.currentTarget.style.opacity = 1}
      />
    </div>
  );
};

// -------- Dashboard (PartialView: "Dashboard") ---------
const Dashboard = ({ actionPayload, role, onToast }) => {
  const [kpiIds, setKpiIds] = useD_S(null);
  const [loading, setLoading] = useD_S(true);

  useD_E(() => {
    let cancelled = false;
    setLoading(true);
    mockApi.getRelatedActions(actionPayload.ActionId, "KPICard", role).then((arr) => {
      if (cancelled) return;
      setKpiIds(arr.map((a) => a.ActionId));
      setLoading(false);
    }).catch((e) => {
      if (cancelled) return;
      onToast?.({ kind: "err", text: e.message });
      setLoading(false);
    });
    return () => { cancelled = true; };
  }, [actionPayload.ActionId, role]);

  return (
    <div className="space-y-6">
      {/* KPI grid */}
      <div className="grid gap-3 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-3">
        {loading
          ? Array.from({ length: 6 }).map((_, i) => (
              <div key={i} className="card p-5">
                <Skeleton className="h-3 w-24 mb-3" />
                <Skeleton className="h-8 w-20 mb-3" />
                <Skeleton className="h-2.5 w-32" />
              </div>
            ))
          : (kpiIds || []).map((id) => <KPICard key={id} actionId={id} onToast={onToast} />)
        }
        {!loading && (!kpiIds || kpiIds.length === 0) && (
          <div className="col-span-full">
            <Empty
              icon="layoutDashboard"
              title="No KPI cards for this role"
              subtitle="Admins can add KPIs in Settings → Action library."
            />
          </div>
        )}
      </div>

      {/* Secondary panel: framework health (mock) */}
      <div className="grid gap-3 lg:grid-cols-3">
        <div className="card p-5 lg:col-span-2">
          <div className="flex items-center justify-between mb-3">
            <div className="flex items-center gap-2">
              <Icon name="activity" size={14} style={{ color: "var(--primary)" }} />
              <div className="text-[13px] font-semibold" style={{ color: "var(--ink)" }}>Action activity · last 24h</div>
            </div>
            <span className="text-[11px]" style={{ color: "var(--subtle)" }}>Mocked</span>
          </div>
          <DashboardActivityChart />
          <div className="grid grid-cols-3 gap-3 mt-4">
            <MiniStat label="Payload calls"   value="1,284" delta="+8.4%" />
            <MiniStat label="Avg latency"     value="142ms" delta="-12ms" deltaDir="down" />
            <MiniStat label="Cache hit-rate"  value="91.2%" delta="+0.6%" />
          </div>
        </div>
        <div className="card p-5">
          <div className="flex items-center justify-between mb-3">
            <div className="flex items-center gap-2">
              <Icon name="layers" size={14} style={{ color: "var(--accent)" }} />
              <div className="text-[13px] font-semibold" style={{ color: "var(--ink)" }}>Action registry</div>
            </div>
          </div>
          <ActionRegistryGlance />
        </div>
      </div>
    </div>
  );
};

const MiniStat = ({ label, value, delta, deltaDir = "up" }) => (
  <div className="rounded-lg p-2.5" style={{ background: "var(--surface-2)", border: "1px solid var(--border)" }}>
    <div className="text-[11px]" style={{ color: "var(--muted)" }}>{label}</div>
    <div className="font-semibold mt-0.5 tabular-nums" style={{ color: "var(--ink)", fontSize: 18, letterSpacing: "-0.02em" }}>{value}</div>
    <div className="text-[11px] mt-0.5 inline-flex items-center gap-1" style={{ color: deltaDir === "down" ? "var(--danger)" : "var(--success)" }}>
      <Icon name={deltaDir === "down" ? "trendingDown" : "trendingUp"} size={10} /> {delta}
    </div>
  </div>
);

// Fake activity bars
const DashboardActivityChart = () => {
  const seed = [13, 22, 18, 31, 27, 44, 38, 52, 47, 61, 55, 68, 71, 64, 73, 81, 78, 92, 86, 79, 73, 84, 69, 58];
  const max = Math.max(...seed);
  return (
    <div className="flex items-end gap-1 h-24" aria-label="Activity">
      {seed.map((v, i) => {
        const h = (v / max) * 100;
        const isLast = i === seed.length - 1;
        return (
          <div key={i} className="flex-1 flex flex-col justify-end relative group">
            <div
              className="rounded-sm"
              style={{
                height: `${h}%`,
                background: isLast ? "var(--primary)" : "var(--surface-3)",
                border: isLast ? "1px solid var(--primary)" : "1px solid var(--border)",
                transition: "height 200ms",
              }}
            />
            {/* Hour ticks every 6 */}
            {i % 6 === 0 && (
              <div className="absolute -bottom-4 left-1/2 -translate-x-1/2 text-[9px] font-mono" style={{ color: "var(--subtle)" }}>
                {i === 0 ? "−24h" : i === 6 ? "−18h" : i === 12 ? "−12h" : "−6h"}
              </div>
            )}
          </div>
        );
      })}
    </div>
  );
};

// Glance at the action registry counts (mock derived from registry directly)
const ActionRegistryGlance = () => {
  const all = mockApi.state.getAllActions();
  const byKind = {};
  Object.values(all).forEach((a) => {
    byKind[a.PartialView] = (byKind[a.PartialView] || 0) + 1;
  });
  const items = Object.entries(byKind).sort(([, a], [, b]) => b - a);
  const total = Object.values(byKind).reduce((s, n) => s + n, 0);
  return (
    <div>
      <div className="font-semibold tabular-nums mb-2" style={{ color: "var(--ink)", fontSize: 22, letterSpacing: "-0.02em" }}>
        {total} <span className="text-[12px] font-normal" style={{ color: "var(--muted)" }}>actions wired</span>
      </div>
      <div className="space-y-1.5">
        {items.map(([k, n]) => {
          const pct = (n / total) * 100;
          return (
            <div key={k}>
              <div className="flex items-center justify-between text-[11.5px]">
                <span style={{ color: "var(--ink-2)" }}>{k}</span>
                <span className="font-mono" style={{ color: "var(--subtle)" }}>{n}</span>
              </div>
              <div className="h-1 rounded-full overflow-hidden mt-0.5" style={{ background: "var(--surface-3)" }}>
                <div className="h-full" style={{ width: `${pct}%`, background: "var(--primary)" }} />
              </div>
            </div>
          );
        })}
      </div>
      <div className="mt-3 text-[11px] leading-relaxed pt-3 border-t" style={{ color: "var(--muted)", borderColor: "var(--border)" }}>
        In production this would reach <span className="font-mono">{`>500`}</span> actions across <span className="font-mono">{`~30`}</span> views.
      </div>
    </div>
  );
};

Object.assign(window, { Dashboard, KPICard, Sparkline });
