/* AZIS prototype — shared React components ============================== */
const { useState, useEffect, useRef, useCallback } = React;

/* ---------- Icons (Lucide-style, matches app sprite) ---------- */
const PATHS = {
  play: <polygon points="6 3 20 12 6 21 6 3" fill="currentColor" stroke="none" />,
  stop: <rect x="6" y="6" width="12" height="12" rx="2" fill="currentColor" stroke="none" />,
  calendar: <g><rect x="3" y="4" width="18" height="18" rx="2" /><path d="M16 2v4M8 2v4M3 10h18" /></g>,
  settings: <g><circle cx="12" cy="12" r="3" /><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 1 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 1 1-2.83-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 1 1 2.83-2.83l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 1 1 2.83 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z" /></g>,
  download: <g><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" /><polyline points="7 10 12 15 17 10" /><line x1="12" x2="12" y1="15" y2="3" /></g>,
  chart: <g><path d="M3 3v18h18" /><path d="M18 17V9" /><path d="M13 17V5" /><path d="M8 17v-3" /></g>,
  close: <g><path d="M18 6 6 18M6 6l12 12" /></g>,
  chevron: <polyline points="9 18 15 12 9 6" />,
  check: <polyline points="20 6 9 17 4 12" />,
  clock: <g><circle cx="12" cy="12" r="9" /><polyline points="12 7 12 12 15 14" /></g>,
  zap: <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />,
  sun: <g><circle cx="12" cy="12" r="4" /><path d="M12 2v2M12 20v2M4.9 4.9l1.4 1.4M17.7 17.7l1.4 1.4M2 12h2M20 12h2M4.9 19.1l1.4-1.4M17.7 6.3l1.4-1.4" /></g>,
  briefcase: <g><rect x="2" y="7" width="20" height="14" rx="2" /><path d="M16 21V5a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16" /></g>,
  plane: <path d="M17.8 19.2 16 11l3.5-3.5C21 6 21.5 4 21 3c-1-.5-3 0-4.5 1.5L13 8 4.8 6.2c-.5-.1-.9.1-1.1.5l-.3.5c-.2.5-.1 1 .3 1.3L9 12l-2 3H4l-1 1 3 2 2 3 1-1v-3l3-2 3.5 5.3c.3.4.8.5 1.3.3l.5-.2c.4-.3.6-.7.5-1.2z" />,
  award: <g><circle cx="12" cy="8" r="6" /><path d="M15.5 13.5 17 22l-5-3-5 3 1.5-8.5" /></g>,
  shield: <path d="M12 2 4 5v6c0 5 3.4 8.5 8 10 4.6-1.5 8-5 8-10V5l-8-3z" />,
  wrench: <path d="M14.7 6.3a4 4 0 0 0-5.2 5.2L3 18l3 3 6.5-6.5a4 4 0 0 0 5.2-5.2l-2.4 2.4-2.5-.6-.6-2.5 2.5-2.4z" />,
  bug: <g><path d="M8 2l1.5 1.5M16 2l-1.5 1.5" /><rect x="8" y="6" width="8" height="13" rx="4" /><path d="M8 11H3M21 11h-5M8 16H3M21 16h-5M8 6 6 4M16 6l2-2" /></g>,
  megaphone: <path d="M3 11v2a1 1 0 0 0 1 1h2l5 4V6L6 10H4a1 1 0 0 0-1 1zM15 8a5 5 0 0 1 0 8" />,
  flag: <g><path d="M4 21V4h13l-2 4 2 4H4" /></g>,
  activity: <polyline points="22 12 18 12 15 21 9 3 6 12 2 12" />,
  list: <g><path d="M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01" /></g>,
  lockOpen: <g><rect x="3" y="11" width="18" height="11" rx="2" /><path d="M7 11V7a5 5 0 0 1 9.9-1" /></g>,
  moon: <path d="M21 12.8A9 9 0 1 1 11.2 3 7 7 0 0 0 21 12.8z" />,
  server: <g><rect x="3" y="4" width="18" height="7" rx="2" /><rect x="3" y="13" width="18" height="7" rx="2" /><path d="M7 8h.01M7 17h.01" /></g>,
  sparkle: <path d="M12 3l1.6 5.4L19 10l-5.4 1.6L12 17l-1.6-5.4L5 10l5.4-1.6z" />,
  lock: <g><rect x="3" y="11" width="18" height="11" rx="2" /><path d="M7 11V7a5 5 0 0 1 10 0v4" /></g>,
  arrow: <g><line x1="5" y1="12" x2="19" y2="12" /><polyline points="12 5 19 12 12 19" /></g>,
};
function Icon({ name, className, style }) {
  return (
    <svg className={className} style={style} viewBox="0 0 24 24" fill="none"
      stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      {PATHS[name]}
    </svg>
  );
}

/* ---------- AZIS mark (military-cross + clock, geometric) ---------- */
function AzisMark() {
  return (
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.6" strokeLinecap="round" strokeLinejoin="round">
      <circle cx="12" cy="12" r="6.2" />
      <path d="M12 8.4V12l2.4 1.4" />
      <path d="M12 1.5v3M12 19.5v3M1.5 12h3M19.5 12h3" strokeWidth="2.2" />
    </svg>
  );
}

/* ---------- count-up number (mono) ---------- */
function useCountUp(target, deps, reduced) {
  const [val, setVal] = useState(target);
  const raf = useRef(0);
  useEffect(() => {
    if (reduced) { setVal(target); return; }
    const from = val, to = target, dur = 700, t0 = performance.now();
    cancelAnimationFrame(raf.current);
    const step = (t) => {
      const p = Math.min(1, (t - t0) / dur);
      const e = 1 - Math.pow(1 - p, 3);
      setVal(from + (to - from) * e);
      if (p < 1) raf.current = requestAnimationFrame(step);
    };
    raf.current = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf.current);
    // eslint-disable-next-line
  }, deps);
  return val;
}

/* count-up that renders an h:mm value */
function SaldoCount({ minutes, plus, reduced, className }) {
  const v = useCountUp(minutes, [minutes], reduced);
  const cls = minutes > 0 ? "val-pos" : minutes < 0 ? "val-neg" : "val-zero";
  return <span className={(className || "") + " " + cls}>{AZIS.fmt(v, { plus })}</span>;
}

/* ---------- progress ring ---------- */
function ProgressRing({ ist, soll, reduced }) {
  const pct = soll > 0 ? Math.min(1.18, ist / soll) : (ist > 0 ? 1 : 0);
  const C = 2 * Math.PI * 34;
  const [off, setOff] = useState(C);
  useEffect(() => {
    const target = C * (1 - Math.min(1, pct));
    if (reduced) { setOff(target); return; }
    const id = setTimeout(() => setOff(target), 60);
    return () => clearTimeout(id);
  }, [pct, C, reduced]);
  return (
    <div className="ring">
      <svg viewBox="0 0 80 80">
        <circle className="ring__bg" cx="40" cy="40" r="34" />
        <circle className="ring__fg" cx="40" cy="40" r="34"
          strokeDasharray={C} strokeDashoffset={off} />
      </svg>
      <div className="ring__label">
        <strong>{AZIS.fmt(ist)}</strong>
        <span>/ {AZIS.fmt(soll)}</span>
      </div>
    </div>
  );
}

/* ---------- month sparkline (daily saldi) ---------- */
function Sparkline({ days, reduced }) {
  const work = days.filter((d) => !d.weekend);
  const max = Math.max(60, ...work.map((d) => Math.abs(d.saldo)));
  return (
    <div className="spark">
      <div className="spark__bars">
        {days.map((d, i) => {
          if (d.weekend) return <div key={i} className="spark__bar" style={{ opacity: 0.12, height: "6px", animationDelay: (i * 12) + "ms" }} />;
          const h = Math.max(3, (Math.abs(d.saldo) / max) * 44);
          const cls = d.isToday ? "today" : d.saldo > 0 ? "pos" : d.saldo < 0 ? "neg" : "";
          return (
            <div key={i} className={"spark__bar " + cls}
              title={d.dom + ". · " + AZIS.fmt(d.saldo, { plus: true })}
              style={{ height: h + "px", animationDelay: reduced ? "0ms" : (i * 16) + "ms" }} />
          );
        })}
      </div>
      <div className="spark__axis">
        <span>01.</span><span>{AZIS.MONTHS[AZIS.MONTH]}</span><span>{days.length}.</span>
      </div>
    </div>
  );
}

Object.assign(window, { Icon, AzisMark, useCountUp, SaldoCount, ProgressRing, Sparkline });
