// Solkart — animated counters
// Smooth incrementing live counters that interpolate between snapshot updates.
const { useEffect, useRef, useState } = React;

function useSmoothNumber(target, durationMs = 900) {
  const [value, setValue] = useState(target);
  const fromRef = useRef(target);
  const startRef = useRef(performance.now());
  const targetRef = useRef(target);
  const rafRef = useRef(null);

  useEffect(() => {
    fromRef.current = value;
    targetRef.current = target;
    startRef.current = performance.now();
    cancelAnimationFrame(rafRef.current);
    const tick = (now) => {
      const t = Math.min(1, (now - startRef.current) / durationMs);
      const eased = 1 - Math.pow(1 - t, 3);
      const v = fromRef.current + (targetRef.current - fromRef.current) * eased;
      setValue(v);
      if (t < 1) rafRef.current = requestAnimationFrame(tick);
    };
    rafRef.current = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(rafRef.current);
    // eslint-disable-next-line
  }, [target, durationMs]);

  return value;
}

// Continuously-incrementing kWh counter that grows at a given kW rate.
// Re-syncs whenever `baseKWh` changes (new snapshot from sim).
function useTickingKWh(baseKWh, ratePerSecKWh) {
  const [val, setVal] = useState(baseKWh);
  const baseRef = useRef({ at: performance.now(), kWh: baseKWh, rate: ratePerSecKWh });

  useEffect(() => {
    baseRef.current = { at: performance.now(), kWh: baseKWh, rate: ratePerSecKWh };
  }, [baseKWh, ratePerSecKWh]);

  useEffect(() => {
    let raf;
    const tick = (now) => {
      const { at, kWh, rate } = baseRef.current;
      const dtSec = (now - at) / 1000;
      setVal(kWh + rate * dtSec);
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);

  return val;
}

function formatKWh(v) {
  // Format like 12 345 678 (Norwegian thin-space grouping)
  const rounded = Math.floor(v);
  return rounded.toLocaleString("nb-NO").replace(/,/g, " ");
}

function formatKW(v) {
  if (v >= 1000000) return (v / 1000000).toFixed(2) + " GW";
  if (v >= 1000) return (v / 1000).toFixed(1) + " MW";
  return Math.round(v).toLocaleString("nb-NO") + " kW";
}

// Splits a formatted number into a vector of digit characters so we can render each
// in a fixed-width tabular box (gives the ticker a mechanical feel).
function NumberBoard({ text, size = 84, color = "oklch(0.25 0.05 60)" }) {
  return (
    <div
      style={{
        display: "flex",
        alignItems: "baseline",
        fontFamily: "'Newsreader', Georgia, serif",
        fontSize: size,
        lineHeight: 1,
        fontWeight: 500,
        letterSpacing: "-0.02em",
        color,
        fontVariantNumeric: "tabular-nums",
      }}
    >
      {text.split("").map((ch, i) => {
        const isDigit = /\d/.test(ch);
        return (
          <span
            key={i}
            style={{
              display: "inline-block",
              minWidth: isDigit ? "0.62em" : undefined,
              textAlign: "center",
            }}
          >
            {ch}
          </span>
        );
      })}
    </div>
  );
}

// Big primary ticker: kWh produced today across all of Norway.
function LiveTicker({ baseKWh, currentRateKW, label, sublabel, size = 88 }) {
  const v = useTickingKWh(baseKWh, currentRateKW / 3600); // kW → kWh/sec
  const text = formatKWh(v);
  return (
    <div>
      <div
        style={{
          fontFamily: "'DM Sans', system-ui, sans-serif",
          fontSize: 12,
          letterSpacing: "0.18em",
          fontWeight: 600,
          color: "oklch(0.5 0.05 60)",
          textTransform: "uppercase",
          marginBottom: 12,
          display: "flex",
          alignItems: "center",
          gap: 8,
        }}
      >
        <LivePulse />
        {label}
      </div>
      <NumberBoard text={text} size={size} />
      <div
        style={{
          fontFamily: "'DM Sans', system-ui, sans-serif",
          fontSize: 14,
          color: "oklch(0.4 0.04 60)",
          marginTop: 10,
        }}
      >
        {sublabel}
      </div>
    </div>
  );
}

function LivePulse() {
  return (
    <span style={{ position: "relative", display: "inline-block", width: 10, height: 10 }}>
      <span style={{
        position: "absolute", inset: 0, borderRadius: "50%",
        background: "oklch(0.6 0.22 30)",
      }} />
      <span style={{
        position: "absolute", inset: -2, borderRadius: "50%",
        border: "2px solid oklch(0.6 0.22 30)",
        animation: "solkart-pulse 1.6s ease-out infinite",
      }} />
    </span>
  );
}

// Smaller stat tile (current rate, fylke counts, etc).
function StatTile({ label, value, unit, accent }) {
  const smooth = useSmoothNumber(typeof value === "number" ? value : 0, 700);
  const display = typeof value === "number"
    ? (unit === "kWh" ? formatKWh(smooth) : unit === "kW" ? formatKW(smooth) : smooth.toFixed(0))
    : value;
  return (
    <div style={{
      flex: "1 1 0",
      minWidth: 140,
      padding: "16px 18px",
      background: "oklch(0.99 0.005 80 / 0.7)",
      borderRadius: 14,
      border: "1px solid oklch(0.88 0.03 75)",
      backdropFilter: "blur(6px)",
    }}>
      <div style={{
        fontFamily: "'DM Sans', system-ui, sans-serif",
        fontSize: 11, letterSpacing: "0.14em", fontWeight: 600,
        color: "oklch(0.5 0.05 60)", textTransform: "uppercase", marginBottom: 8,
      }}>{label}</div>
      <div style={{
        fontFamily: "'Newsreader', Georgia, serif",
        fontSize: 26, fontWeight: 600, color: accent || "oklch(0.25 0.05 60)",
        letterSpacing: "-0.01em",
        fontVariantNumeric: "tabular-nums",
      }}>{display}</div>
    </div>
  );
}

window.SOLKART_UI = { LiveTicker, StatTile, NumberBoard, formatKWh, formatKW, LivePulse };
