/* Shared UI primitives + small components used across the prototype. */

const { useState, useEffect, useRef, useMemo } = React;

/* ---------- Icon (minimal set, inline SVG, currentColor) ---------- */

const ICON_PATHS = {
  arrow: "M5 12h14M13 6l6 6-6 6",
  back: "M19 12H5M11 6l-6 6 6 6",
  check: "M5 12l5 5L20 7",
  plus: "M12 5v14M5 12h14",
  close: "M6 6l12 12M18 6L6 18",
  external: "M14 5h5v5M19 5l-9 9M9 5H5v14h14v-4",
  source: "M4 4h12v16H4zM8 8h4M8 12h4M8 16h4M19 8v8",
  search: "M11 17a6 6 0 1 0 0-12 6 6 0 0 0 0 12zM20 20l-4-4",
  spark: "M3 17l5-5 4 4 8-8",
  check2: "M5 12l4 4L19 6",
  filter: "M4 6h16M7 12h10M10 18h4",
  shield: "M12 3l8 3v6c0 5-4 8-8 9-4-1-8-4-8-9V6l8-3z",
  bell: "M6 8a6 6 0 0 1 12 0v5l2 3H4l2-3V8zM10 19a2 2 0 0 0 4 0",
  refresh: "M4 4v5h5M20 20v-5h-5M5 9a8 8 0 0 1 14-2M19 15a8 8 0 0 1-14 2",
  chart: "M4 20V8M10 20V4M16 20v-8M22 20H2",
  doc: "M7 4h7l4 4v12H7zM14 4v4h4",
  edit: "M4 20h4l10-10-4-4L4 16zM14 6l4 4",
  warn: "M12 4l10 17H2zM12 10v5M12 18h.01",
  caret: "M6 9l6 6 6-6",
};

function Icon({ name, size = 16, stroke = 1.6, style }) {
  const d = ICON_PATHS[name];
  if (!d) return null;
  return (
    <svg
      width={size}
      height={size}
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth={stroke}
      strokeLinecap="round"
      strokeLinejoin="round"
      style={{ flexShrink: 0, ...style }}
    >
      <path d={d} />
    </svg>
  );
}

/* ---------- Brand ---------- */

function BrandMark({ size = 22 }) {
  return (
    <span
      className="brand-mark"
      style={{ width: size, height: size, fontSize: size * 0.5 }}
      aria-hidden="true"
    >
      T
    </span>
  );
}

function Brand({ subtitle }) {
  return (
    <div className="brand">
      <BrandMark />
      <span>Thesis</span>
      {subtitle && (
        <span
          className="mono"
          style={{ fontSize: 11, color: "var(--ink-4)", marginLeft: 4, textTransform: "uppercase", letterSpacing: "0.08em" }}
        >
          {subtitle}
        </span>
      )}
    </div>
  );
}

/* ---------- Score visuals ---------- */

function ScoreBar({ value, height = 4 }) {
  return (
    <div className="score-bar" style={{ height }}>
      <div className="score-bar-fill" style={{ width: `${Math.round(value * 100)}%` }} />
    </div>
  );
}

function FitScore({ value, big = false }) {
  return (
    <div style={{ display: "inline-flex", alignItems: "baseline", gap: 4 }}>
      <span className="mono" style={{ fontSize: big ? 22 : 14, fontWeight: 600, letterSpacing: "-0.02em" }}>
        {value.toFixed(2)}
      </span>
      <span className="mono" style={{ fontSize: big ? 11 : 9, color: "var(--ink-4)", textTransform: "uppercase", letterSpacing: "0.08em" }}>
        fit
      </span>
    </div>
  );
}

function FeasibilityDot({ kind }) {
  const cls = kind === "green" ? "tag-pos" : kind === "yellow" ? "tag-warn" : "tag-neg";
  const label = kind === "green" ? ">30 candidates fit" : kind === "yellow" ? "10–30 fit" : "<10 fit";
  return (
    <span className={`tag ${cls}`}>
      <span className="tag-dot" />
      {label}
    </span>
  );
}

/* ---------- Sparkline ---------- */

function Sparkline({ data, height = 36, stroke = 1.4, color = "var(--ink)", fill = false }) {
  const w = 120;
  const points = data
    .map((v, i) => `${(i / (data.length - 1)) * w},${(1 - v) * height}`)
    .join(" ");
  const last = data[data.length - 1];
  const lastX = w;
  const lastY = (1 - last) * height;
  return (
    <svg className="spark" viewBox={`0 0 ${w} ${height}`} preserveAspectRatio="none" style={{ height }}>
      {fill && (
        <polygon
          points={`0,${height} ${points} ${w},${height}`}
          fill={color}
          opacity="0.08"
        />
      )}
      <polyline points={points} fill="none" stroke={color} strokeWidth={stroke} strokeLinejoin="round" strokeLinecap="round" />
      <circle cx={lastX} cy={lastY} r="1.8" fill={color} />
    </svg>
  );
}

/* ---------- Citation pill ---------- */

function Cite({ label = "10-K", num, href }) {
  const linked = Boolean(href);
  const props = linked
    ? { href, target: "_blank", rel: "noopener noreferrer", title: href }
    : { href: "#", onClick: (e) => e.preventDefault(), title: `Source ${num ?? ""}`.trim() };
  return (
    <a className="cite" {...props}>
      <Icon name="doc" size={9} />
      {label}
      {num !== undefined && num !== null && <span style={{ opacity: 0.6 }}>·{num}</span>}
    </a>
  );
}

/* ---------- Tabs ---------- */

function Tabs({ tabs, active, onChange }) {
  return (
    <div className="tabs" role="tablist">
      {tabs.map((t) => (
        <button
          key={t.id}
          role="tab"
          aria-selected={active === t.id}
          className={"tab" + (active === t.id ? " active" : "")}
          onClick={() => onChange(t.id)}
        >
          {t.label}
          {t.count !== undefined && (
            <span className="mono" style={{ marginLeft: 6, fontSize: 11, color: "var(--ink-4)" }}>
              {t.count}
            </span>
          )}
        </button>
      ))}
    </div>
  );
}

/* ---------- Disclaimer (compliance) ---------- */

function Disclaimer({ compact = false }) {
  return (
    <div className="disclaimer" style={compact ? { padding: "6px 16px" } : undefined}>
      <span className="disclaimer-dot" aria-hidden="true" />
      <span>
        Research output, not investment advice. Verify all data and consult a licensed advisor before investing.
      </span>
    </div>
  );
}

/* ---------- Section header ---------- */

function SectionHead({ eyebrow, title, sub, right }) {
  return (
    <div style={{ display: "flex", alignItems: "flex-end", justifyContent: "space-between", gap: 16, marginBottom: 18, flexWrap: "wrap" }}>
      <div>
        {eyebrow && <div className="label" style={{ marginBottom: 6 }}>{eyebrow}</div>}
        <h2 style={{ margin: 0, fontFamily: "var(--font-serif)", fontWeight: 500, fontSize: 26, letterSpacing: "-0.015em", lineHeight: 1.15 }}>
          {title}
        </h2>
        {sub && <div style={{ marginTop: 4, fontSize: 14, color: "var(--ink-3)", maxWidth: 640 }}>{sub}</div>}
      </div>
      {right}
    </div>
  );
}

/* ---------- Topbar ---------- */

function TopBar({ crumbs = [], center, right, onBack }) {
  return (
    <div className="topbar">
      <div style={{ display: "flex", alignItems: "center", gap: 18, flex: 1, minWidth: 0 }}>
        {onBack && (
          <button className="btn btn-ghost btn-sm" onClick={onBack} title="Back">
            <Icon name="back" size={14} /> Back
          </button>
        )}
        <Brand />
        {crumbs.length > 0 && (
          <div className="crumbs" aria-label="Breadcrumb">
            <span className="crumb-sep">/</span>
            {crumbs.map((c, i) => (
              <React.Fragment key={i}>
                <span className={i === crumbs.length - 1 ? "crumb-active" : undefined}>{c}</span>
                {i < crumbs.length - 1 && <span className="crumb-sep">/</span>}
              </React.Fragment>
            ))}
          </div>
        )}
      </div>
      {center && (
        <div style={{ display: "flex", alignItems: "center", justifyContent: "center", flex: "0 0 auto" }}>
          {center}
        </div>
      )}
      <div style={{ display: "flex", alignItems: "center", gap: 8, flex: 1, justifyContent: "flex-end" }}>{right}</div>
    </div>
  );
}

/* ---------- WIP banner (sticky on every screen) ---------- */

function WipBanner() {
  return (
    <div
      role="status"
      style={{
        position: "sticky",
        top: 0,
        zIndex: 100,
        background: "#FFE9A8",
        color: "#3a2a00",
        borderBottom: "1px solid #d9b34a",
        fontSize: 12,
        padding: "6px 16px",
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        gap: 10,
        textAlign: "center",
        fontFamily: "var(--font-sans)",
      }}
    >
      <span
        className="mono"
        style={{
          fontSize: 10,
          letterSpacing: "0.12em",
          textTransform: "uppercase",
          background: "#3a2a00",
          color: "#FFE9A8",
          padding: "2px 8px",
          borderRadius: 999,
          fontWeight: 600,
        }}
      >
        WIP
      </span>
      <span>
        Work-in-progress prototype. Demo data is partly model-authored; numbers and rationale are illustrative until each criterion is wired to live data.
      </span>
    </div>
  );
}

/* ---------- Empty / loading shimmer block ---------- */

function ShimmerBlock({ h = 14, w = "100%", mt = 0 }) {
  return <div className="shimmer" style={{ height: h, width: w, marginTop: mt }} />;
}

/* ---------- Export ---------- */

Object.assign(window, {
  Icon,
  BrandMark,
  Brand,
  ScoreBar,
  FitScore,
  FeasibilityDot,
  Sparkline,
  Cite,
  Tabs,
  Disclaimer,
  SectionHead,
  TopBar,
  ShimmerBlock,
  WipBanner,
});
