// Shared atoms for ClarionVote: party color helpers, chips, source link,
// avatars, buttons, mini-bars, segmented tabs.

const PARTY = {
  Democrat:   { letter: "D", color: "#2C5BA8", soft: "#E3EAF5", name: "Democrat"    },
  Republican: { letter: "R", color: "#A93232", soft: "#F4E3E3", name: "Republican"  },
  Independent:{ letter: "I", color: "#7B5BA3", soft: "#EEE6F4", name: "Independent" },
  Libertarian:{ letter: "L", color: "#C99500", soft: "#F6EBC9", name: "Libertarian" },
};

const partyOf = (p) => PARTY[p] || PARTY.Independent;

// Reusable: tiny SVG that means "linked source / verifiable"
function SourceIcon({ size = 11 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 12 12" fill="none" aria-hidden="true" style={{ flexShrink: 0 }}>
      <path d="M1.5 6.5L5 10L10.5 2.5" stroke="currentColor" strokeWidth="1.5" strokeLinecap="square" />
    </svg>
  );
}

function SourceLink({ label = "source", href = "#", title }) {
  return (
    <a
      href={href}
      onClick={(e) => e.preventDefault()}
      title={title || `View original document: ${label}`}
      className="cv-source"
    >
      <SourceIcon />
      <span>{label}</span>
    </a>
  );
}

function PartyTag({ party }) {
  const p = partyOf(party);
  return (
    <span className="cv-party" data-party={p.letter}>
      <span className="cv-party-chip" style={{ color: p.color, background: p.soft }}>
        <span style={{ background: p.color }} className="cv-party-chip-d" /> {p.letter}
      </span>
      <span className="cv-party-dot" style={{ background: p.color }} title={p.name} aria-label={p.name} />
      <span className="cv-party-mono" style={{ color: p.color, borderColor: p.color }}>
        {p.letter}
      </span>
    </span>
  );
}

// Compact stat block — label above, big mono number below.
function StatBlock({ label, value, suffix, hint, tone, small }) {
  return (
    <div className={`cv-stat ${small ? "cv-stat-sm" : ""} ${tone ? `cv-tone-${tone}` : ""}`}>
      <div className="cv-stat-l">{label}</div>
      <div className="cv-stat-v">
        <span className="cv-stat-num">{value}</span>
        {suffix && <span className="cv-stat-sfx">{suffix}</span>}
      </div>
      {hint && <div className="cv-stat-h">{hint}</div>}
    </div>
  );
}

// Avatar — round/rounded. Falls back to initials block when no photo.
function Avatar({ photo, name, size = 80, shape = "rounded", party }) {
  const initials = name.split(" ").map((s) => s[0]).join("").slice(0, 2);
  const radius = shape === "circle" ? "50%" : shape === "square" ? "6px" : "10px";
  const p = partyOf(party);
  return (
    <div
      className="cv-avatar"
      style={{ width: size, height: size, borderRadius: radius, background: p.soft, color: p.color }}
    >
      {photo
        ? <img src={photo} alt={name} loading="lazy" />
        : <span style={{ fontSize: size * 0.36, fontWeight: 600 }}>{initials}</span>}
    </div>
  );
}

// Yea/Nay/Present/NV badge
function VoteBadge({ position }) {
  const map = {
    Yea:     { c: "#0F6E47", b: "#DCEFE3", l: "Yea" },
    Nay:     { c: "#A93232", b: "#F4E3E3", l: "Nay" },
    Present: { c: "#6E5A14", b: "#F4ECCB", l: "Present" },
    "Not Voting": { c: "#5A5F66", b: "#E8E7E2", l: "NV" },
  };
  const m = map[position] || map["Not Voting"];
  return (
    <span className="cv-vote-badge" style={{ color: m.c, background: m.b }}>
      {m.l}
    </span>
  );
}

// Horizontal stacked bar for ratios (e.g. small/large dollar)
function RatioBar({ left, right, leftLabel, rightLabel, leftColor, rightColor }) {
  return (
    <div className="cv-ratio">
      <div className="cv-ratio-bar">
        <div style={{ width: `${left}%`, background: leftColor || "var(--cv-accent)" }} />
        <div style={{ width: `${right}%`, background: rightColor || "var(--cv-line-strong)" }} />
      </div>
      <div className="cv-ratio-lbl">
        <span><b>{left}%</b> {leftLabel}</span>
        <span>{rightLabel} <b>{right}%</b></span>
      </div>
    </div>
  );
}

// Segmented tabs
function Tabs({ items, value, onChange }) {
  return (
    <div className="cv-tabs" role="tablist">
      {items.map((t) => (
        <button
          key={t.value}
          role="tab"
          aria-selected={value === t.value}
          className={`cv-tab ${value === t.value ? "is-on" : ""}`}
          onClick={() => onChange(t.value)}
        >
          {t.label}
          {t.count != null && <span className="cv-tab-count">{t.count}</span>}
        </button>
      ))}
    </div>
  );
}

// Button
function CVButton({ children, variant = "primary", onClick, type = "button", icon, full }) {
  return (
    <button type={type} className={`cv-btn cv-btn-${variant} ${full ? "cv-btn-full" : ""}`} onClick={onClick}>
      {icon && <span className="cv-btn-icon">{icon}</span>}
      {children}
    </button>
  );
}

// Pretty key/value row used in many lists
function KV({ label, value, source }) {
  return (
    <div className="cv-kv">
      <span className="cv-kv-l">{label}</span>
      <span className="cv-kv-v">
        <span>{value}</span>
        {source && <SourceLink label="src" />}
      </span>
    </div>
  );
}

// Convert a rating score (letter, percent, or number) to a 0–100 magnitude
// for relative bars and an inline "what does this mean" hint.
function ratingMeta(score) {
  if (!score) return { pct: 0, hint: "" };
  if (score.endsWith && score.endsWith("%")) {
    const n = parseInt(score, 10);
    return { pct: n, hint: `${n} out of 100 on their legislative scorecard` };
  }
  const map = { "A+": 100, "A": 95, "A-": 90, "B+": 85, "B": 80, "B-": 75,
                "C+": 70, "C": 65, "C-": 60, "D+": 55, "D": 50, "D-": 45, "F": 5 };
  if (map[score] != null) {
    return { pct: map[score], hint: `Letter grade on A+ to F scale` };
  }
  return { pct: 50, hint: "" };
}

// Rich rating row used in the accountability tab. Always-visible context.
function RatingRow({ group, category, score }) {
  const groups = window.CV_DATA.RATING_GROUPS || {};
  const meta = groups[group] || { full: group, one: category || "Interest-group rating", scale: "Score range varies by group" };
  const r = ratingMeta(score);
  return (
    <div className="cv-rrow">
      <div className="cv-rrow-l">
        <div className="cv-rrow-name">
          <Term name="interest-group-rating">{group}</Term>
        </div>
        <div className="cv-rrow-one">{meta.one}</div>
        <div className="cv-rrow-scale">{meta.scale}</div>
        {meta.href && (
          <a className="cv-rrow-link" href={meta.href} onClick={(e) => e.preventDefault()}>
            View {group} scorecard →
          </a>
        )}
      </div>
      <div className="cv-rrow-r">
        <div className="cv-rrow-score">{score}</div>
        <div className="cv-rrow-bar">
          <div className="cv-rrow-bar-fill" style={{ width: `${r.pct}%` }}/>
        </div>
        <div className="cv-rrow-hint">{r.hint}</div>
      </div>
    </div>
  );
}

// Comparison rating row (VS mode). Two scores, mirrored bars.
function RatingCompareRow({ group, category, a, b }) {
  const groups = window.CV_DATA.RATING_GROUPS || {};
  const meta = groups[group] || { full: group, one: category || "Interest-group rating", scale: "Score range varies by group" };
  const ra = ratingMeta(a);
  const rb = ratingMeta(b);
  return (
    <div className="cv-rcmp">
      <div className="cv-rcmp-meta">
        <div className="cv-rcmp-name">
          <Term name="interest-group-rating">{group}</Term>
        </div>
        <div className="cv-rcmp-one">{meta.one}</div>
        <div className="cv-rcmp-scale">{meta.scale}</div>
      </div>
      <div className="cv-rcmp-bars">
        <div className="cv-rcmp-side cv-rcmp-side-a">
          <div className="cv-rcmp-bar cv-rcmp-bar-a">
            <div className="cv-rcmp-bar-fill" style={{ width: `${ra.pct}%` }}/>
          </div>
          <div className="cv-rcmp-score">{a}</div>
        </div>
        <div className="cv-rcmp-side cv-rcmp-side-b">
          <div className="cv-rcmp-score">{b}</div>
          <div className="cv-rcmp-bar cv-rcmp-bar-b">
            <div className="cv-rcmp-bar-fill" style={{ width: `${rb.pct}%` }}/>
          </div>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  PARTY, partyOf, SourceIcon, SourceLink, PartyTag,
  StatBlock, Avatar, VoteBadge, RatioBar, Tabs, CVButton, KV,
  ratingMeta, RatingRow, RatingCompareRow, fmtDate,
});

function fmtDate(s) {
  if (!s) return "";
  const d = new Date(s);
  return d.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" });
}

// Scope toggle — Current term / Full career segmented control.
// Sits at the top of each data tab. The API supports ?scope=current|career.
function ScopeToggle({ scope, onChange, hint }) {
  return (
    <div className="cv-scope">
      <div className="cv-scope-l">View</div>
      <div className="cv-scope-seg" role="radiogroup" aria-label="Time scope">
        <button
          type="button"
          role="radio"
          aria-checked={scope === "current"}
          className={`cv-scope-btn ${scope === "current" ? "is-on" : ""}`}
          onClick={() => onChange("current")}
        >Current term</button>
        <button
          type="button"
          role="radio"
          aria-checked={scope === "career"}
          className={`cv-scope-btn ${scope === "career" ? "is-on" : ""}`}
          onClick={() => onChange("career")}
        >Full career</button>
      </div>
      {hint && <div className="cv-scope-hint">{hint}</div>}
    </div>
  );
}

Object.assign(window, { ScopeToggle });
