// App shell — header, footer, simple state-based routing, tweaks panel.

const PALETTES = {
  navy: {
    label: "Federal Navy",
    bg: "#F4F1E8",
    surface: "#FFFFFF",
    ink: "#13202E",
    ink2: "#3A4A5C",
    muted: "#6A7480",
    line: "#E5DFCE",
    lineStrong: "#CFC6AE",
    accent: "#C6913A",
    accentInk: "#5A3F0F",
    accentSoft: "#F2E3C2",
  },
  forest: {
    label: "Almanac",
    bg: "#F7F5EE",
    surface: "#FBFAF4",
    ink: "#1A2A22",
    ink2: "#3D4F45",
    muted: "#76837A",
    line: "#E0DCC8",
    lineStrong: "#C5C1A8",
    accent: "#9B7A28",
    accentInk: "#4A3A10",
    accentSoft: "#EBE0BC",
  },
  slate: {
    label: "Civic Slate",
    bg: "#F2F3F5",
    surface: "#FFFFFF",
    ink: "#101418",
    ink2: "#3A4047",
    muted: "#6B7280",
    line: "#E4E6E9",
    lineStrong: "#C8CCD1",
    accent: "#0B7C72",
    accentInk: "#063C37",
    accentSoft: "#CFEAE6",
  },
  ink: {
    label: "Newsprint",
    bg: "#EDEAE0",
    surface: "#FAF7EC",
    ink: "#1A1816",
    ink2: "#3E3A33",
    muted: "#6E685C",
    line: "#DDD7C5",
    lineStrong: "#B9B19A",
    accent: "#A23E20",
    accentInk: "#5A2210",
    accentSoft: "#EFD7CB",
  },
};

const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "palette": "slate",
  "density": "compact",
  "partyStyle": "chip",
  "conflictTone": "loud"
}/*EDITMODE-END*/;

function applyPalette(name) {
  const p = PALETTES[name] || PALETTES.navy;
  const r = document.documentElement;
  r.style.setProperty("--cv-bg", p.bg);
  r.style.setProperty("--cv-surface", p.surface);
  r.style.setProperty("--cv-ink", p.ink);
  r.style.setProperty("--cv-ink-2", p.ink2);
  r.style.setProperty("--cv-muted", p.muted);
  r.style.setProperty("--cv-line", p.line);
  r.style.setProperty("--cv-line-strong", p.lineStrong);
  r.style.setProperty("--cv-accent", p.accent);
  r.style.setProperty("--cv-accent-ink", p.accentInk);
  r.style.setProperty("--cv-accent-soft", p.accentSoft);
}

function App() {
  const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
  const [route, setRoute] = React.useState({ name: "home", params: {} });
  const [query, setQuery] = React.useState("");

  React.useEffect(() => { applyPalette(t.palette); }, [t.palette]);
  React.useEffect(() => {
    document.documentElement.dataset.cvDensity = t.density;
    window.__CV_PARTY_STYLE = t.partyStyle;
    document.documentElement.dataset.cvParty = t.partyStyle;
    document.documentElement.dataset.cvConflict = t.conflictTone;
  }, [t.density, t.partyStyle, t.conflictTone]);

  const navigate = (name, params = {}) => {
    setRoute({ name, params });
    window.scrollTo({ top: 0, behavior: "instant" });
  };

  return (
    <div className="cv-app" data-density={t.density}>
      <ArcadeMode/>
      <AppHeader query={query} setQuery={setQuery} onNavigate={navigate} route={route} />
      <main className="cv-main">
        {route.name === "home" && <Home onNavigate={navigate} />}
        {route.name === "politician" && (
          <CardWrap>
            <PoliticianCard
              id={route.params.id}
              onCompare={() => navigate("vs", { a: route.params.id, b: "cruz" })}
              onNavigate={navigate}
              density={t.density}
            />
          </CardWrap>
        )}
        {route.name === "vs" && (
          <VSWrap>
            <VSMode
              aId={route.params.a}
              bId={route.params.b}
              ids={route.params.ids}
              onNavigate={navigate}
            />
          </VSWrap>
        )}
        {route.name === "bill" && (
          <BillWrap>
            <BillDetail id={route.params.id} onNavigate={navigate} />
          </BillWrap>
        )}
        {route.name === "contribute" && (
          <ContributeWrap>
            <ContributePage onNavigate={navigate} />
          </ContributeWrap>
        )}
        {route.name === "reps" && (
          <FindMyReps initialAddr={route.params.addr} onNavigate={navigate} />
        )}
      </main>
      <AppFooter onNavigate={navigate} />
      <CVTweaks t={t} setTweak={setTweak} />
    </div>
  );
}

function CardWrap({ children }) { return <div className="cv-card-wrap">{children}</div>; }
function VSWrap({ children })   { return <div className="cv-vs-wrap">{children}</div>; }
function BillWrap({ children }) { return <div className="cv-bill-wrap">{children}</div>; }
function ContributeWrap({ children }) { return <div className="cv-contrib-wrap">{children}</div>; }

// ─── Header ─────────────────────────────────────────────────────────────
function AppHeader({ query, setQuery, onNavigate, route }) {
  const [searchOpen, setSearchOpen] = React.useState(false);
  return (
    <header className="cv-app-hd">
      <div className="cv-app-hd-inner">
        <button type="button" className="cv-logo" onClick={() => onNavigate("home")} aria-label="ClarionVote home">
          <ClarionMark />
          <span className="cv-logo-word">CLARION<span className="cv-logo-word-em">VOTE</span></span>
        </button>

        <nav className="cv-app-nav">
          <NavLink current={route.name === "home"}        onClick={() => onNavigate("home")}>Home</NavLink>
          <NavLink current={route.name === "reps"}        onClick={() => onNavigate("reps", { addr: "" })}>Your ballot</NavLink>
          <NavLink current={route.name === "vs"}          onClick={() => onNavigate("vs", { a: "fetterman", b: "cruz" })}>VS Mode</NavLink>
          <NavLink current={route.name === "bill"}        onClick={() => onNavigate("bill", { id: "hr7024" })}>Bills</NavLink>
          <NavLink current={route.name === "contribute"}  onClick={() => onNavigate("contribute")}>Help us track</NavLink>
          <NavLink current={false}                        onClick={() => onNavigate("politician", { id: "aoc" })}>Browse</NavLink>
        </nav>

        <div className="cv-app-hd-search">
          <SearchIcon />
          <input
            placeholder="Search politicians, bills, donors…"
            value={query}
            onChange={(e) => setQuery(e.target.value)}
            onFocus={() => setSearchOpen(true)}
            onBlur={() => setTimeout(() => setSearchOpen(false), 150)}
          />
          {searchOpen && query.length === 0 && <SearchHints onPick={(id) => onNavigate("politician", { id })} />}
          {searchOpen && query.length > 0 && <SearchResults query={query} onPick={(id) => onNavigate("politician", { id })} />}
        </div>

        <button className="cv-btn cv-btn-primary cv-app-hd-cta" onClick={() => onNavigate("reps", { addr: "" })}>
          <PinIcon3/> Find my reps
        </button>
      </div>
      <div className="cv-app-hd-ribbon">
        <span className="cv-ribbon-dot"/>
        <span>Updated <strong>{new Date().toLocaleDateString("en-US", { month: "short", day: "numeric" })}</strong> from FEC, House Clerk, Senate Clerk, and LDA filings.</span>
      </div>
    </header>
  );
}

function NavLink({ children, current, onClick }) {
  return (
    <button type="button" className={`cv-navlink ${current ? "is-on" : ""}`} onClick={onClick}>
      {children}
    </button>
  );
}

function SearchHints({ onPick }) {
  const ids = ["aoc", "fetterman", "cruz", "schumer"];
  return (
    <div className="cv-search-dd">
      <div className="cv-search-dd-l">Suggested</div>
      {ids.map(id => {
        const p = window.CV_DATA.POLITICIANS[id];
        return (
          <button key={id} className="cv-search-dd-row" onMouseDown={() => onPick(id)}>
            <Avatar photo={p.photo} name={p.name} size={28} shape="circle" party={p.party} />
            <span>{p.name}</span>
            <span className="cv-search-dd-meta">{p.office} · {p.state}{p.district ? `-${p.district}` : ""}</span>
          </button>
        );
      })}
    </div>
  );
}

function SearchResults({ query, onPick }) {
  const all = Object.values(window.CV_DATA.POLITICIANS);
  const q = query.toLowerCase();
  const matches = all.filter(p => p.name.toLowerCase().includes(q) || (p.state || "").toLowerCase().includes(q)).slice(0, 5);
  if (matches.length === 0) {
    return <div className="cv-search-dd"><div className="cv-search-dd-empty">No matches for "{query}"</div></div>;
  }
  return (
    <div className="cv-search-dd">
      {matches.map(p => (
        <button key={p.id} className="cv-search-dd-row" onMouseDown={() => onPick(p.id)}>
          <Avatar photo={p.photo} name={p.name} size={28} shape="circle" party={p.party}/>
          <span>{p.name}</span>
          <span className="cv-search-dd-meta">{p.office} · {p.state}{p.district ? `-${p.district}` : ""}</span>
        </button>
      ))}
    </div>
  );
}

// ─── Footer ─────────────────────────────────────────────────────────────
function AppFooter({ onNavigate }) {
  return (
    <footer className="cv-app-ft">
      <div className="cv-app-ft-inner">
        <div className="cv-app-ft-mission">
          <ClarionMark size={28}/>
          <div>
            <div className="cv-app-ft-tag">A reference, not a campaign.</div>
            <p className="cv-app-ft-mission-p">
              Powered by public data. No opinion. Just facts. Every number on every card links
              back to the original government document — verify any claim in two clicks.
            </p>
          </div>
        </div>
        <div className="cv-app-ft-cols">
          <div className="cv-app-ft-col">
            <h5>Product</h5>
            <a onClick={() => onNavigate("reps", { addr: "" })}>Your ballot</a>
            <a onClick={() => onNavigate("vs", { a: "fetterman", b: "cruz" })}>VS Mode</a>
            <a onClick={() => onNavigate("politician", { id: "aoc" })}>Browse politicians</a>
            <a onClick={(e) => e.preventDefault()}>Bills</a>
          </div>
          <div className="cv-app-ft-col">
            <h5>Data sources</h5>
            <a onClick={(e) => e.preventDefault()}>FEC filings</a>
            <a onClick={(e) => e.preventDefault()}>House &amp; Senate clerks</a>
            <a onClick={(e) => e.preventDefault()}>LDA disclosures</a>
            <a onClick={(e) => e.preventDefault()}>STOCK Act PTRs</a>
            <a onClick={(e) => e.preventDefault()}>Methodology</a>
          </div>
          <div className="cv-app-ft-col">
            <h5>Legal</h5>
            <a onClick={(e) => e.preventDefault()}>FEC disclaimer</a>
            <a onClick={(e) => e.preventDefault()}>Conflict-flag rules</a>
            <a onClick={(e) => e.preventDefault()}>Privacy</a>
            <a onClick={(e) => e.preventDefault()}>Corrections policy</a>
          </div>
        </div>
      </div>
      <div className="cv-app-ft-bottom">
        <span>© 2026 ClarionVote · A nonprofit project · Not affiliated with any campaign, party, or candidate.</span>
        <span className="cv-app-ft-fec">Paid for by no one. Endorsed by no one.</span>
      </div>
    </footer>
  );
}

// ─── Tweaks panel ───────────────────────────────────────────────────────
function CVTweaks({ t, setTweak }) {
  return (
    <TweaksPanel>
      <TweakSection label="Palette" />
      <TweakSelect
        label="Theme"
        value={t.palette}
        options={[
          { value: "navy",   label: "Federal Navy" },
          { value: "forest", label: "Almanac"      },
          { value: "slate",  label: "Civic Slate"  },
          { value: "ink",    label: "Newsprint"    },
        ]}
        onChange={(v) => setTweak("palette", v)}
      />
      <TweakSection label="Layout" />
      <TweakRadio
        label="Density"
        value={t.density}
        options={[
          { value: "compact",  label: "Tight"   },
          { value: "regular",  label: "Regular" },
          { value: "spacious", label: "Roomy"   },
        ]}
        onChange={(v) => setTweak("density", v)}
      />
      <TweakSection label="Party indicator" />
      <TweakSelect
        label="Style"
        value={t.partyStyle}
        options={[
          { value: "chip",   label: "Chip (default)" },
          { value: "dot",    label: "Dot only"       },
          { value: "border", label: "Left border"    },
          { value: "none",   label: "Off"            },
        ]}
        onChange={(v) => setTweak("partyStyle", v)}
      />
      <TweakSection label="Conflict banner" />
      <TweakRadio
        label="Tone"
        value={t.conflictTone}
        options={[
          { value: "subtle", label: "Subtle" },
          { value: "loud",   label: "Loud"   },
          { value: "hidden", label: "Hide"   },
        ]}
        onChange={(v) => setTweak("conflictTone", v)}
      />
    </TweaksPanel>
  );
}

// ─── Brand mark ─────────────────────────────────────────────────────────
function ClarionMark({ size = 22 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" aria-hidden="true">
      <rect x="0.5" y="0.5" width="23" height="23" rx="3.5" fill="var(--cv-ink)" stroke="var(--cv-ink)"/>
      <path d="M5 12L10 7V10.5L19 10.5V13.5L10 13.5V17L5 12Z" fill="var(--cv-accent)"/>
    </svg>
  );
}
function SearchIcon() { return <svg width="14" height="14" viewBox="0 0 14 14" fill="none" aria-hidden="true"><circle cx="6" cy="6" r="4.5" stroke="currentColor" strokeWidth="1.4"/><line x1="9.3" y1="9.3" x2="12.5" y2="12.5" stroke="currentColor" strokeWidth="1.4" strokeLinecap="square"/></svg>; }
function PinIcon3()   { return <svg width="13" height="13" viewBox="0 0 14 14" fill="none" aria-hidden="true"><path d="M7 12.5C7 12.5 11.5 8.5 11.5 5.5C11.5 3 9.5 1 7 1C4.5 1 2.5 3 2.5 5.5C2.5 8.5 7 12.5 7 12.5Z" fill="currentColor"/><circle cx="7" cy="5.5" r="1.5" fill="var(--cv-bg)"/></svg>; }

ReactDOM.createRoot(document.getElementById("root")).render(<App/>);
