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

// ═══════════════════════════════════════════════════════════════
// SIDEBAR — profile filters
// ═══════════════════════════════════════════════════════════════
function Sidebar({ profile, setProfile, t, lang, dark, onReset, onClose, products }) {
  const isDark = dark;
  const bg = isDark ? "#1A1817" : "#FFFFFF";
  const border = isDark ? "#2A2825" : "#E2E0DF";
  const text = isDark ? "#FAF7F3" : "#393433";
  const muted = isDark ? "#8A827F" : "#6B6361";
  const faint = isDark ? "#6B6361" : "#9A9290";
  const surface = isDark ? "#0D0D0D" : "#FAF7F3";
  const accent = "#4866B2";

  const filled = window.countProfile(profile);
  const total = window.FILTERS.length;

  // Live match counter
  const matchStats = useMemo(() => {
    if (!products) return { prods: 0, projects: 0 };
    if (filled === 0) return { prods: 0, projects: 0, none: true };
    const eligible = products.filter(p => window.checkEligibility(p, profile).eligible);
    const projectSet = new Set(eligible.map(p => p.project));
    return { prods: eligible.length, projects: projectSet.size };
  }, [products, profile, filled]);

  // Group filters
  const groups = window.FILTER_GROUPS.map(g => ({
    ...g,
    filters: window.FILTERS.filter(f => f.group === g.key),
  }));

  return (
    <aside style={{
      width: 288,
      maxWidth: "100%",
      flex: 1,
      background: bg,
      borderRight: `1px solid ${border}`,
      display: "flex",
      flexDirection: "column",
      color: text,
      overflow: "hidden",
    }}>
      {/* Brand */}
      <div style={{ padding: "20px 24px 16px", borderBottom: `1px solid ${border}`, position: "relative" }}>
        {onClose && (
          <button onClick={onClose} aria-label="Close menu" className="r-sb-close" style={{
            display: "none",
            position: "absolute", top: 14, right: 14,
            width: 32, height: 32,
            background: "transparent", border: `1px solid ${border}`,
            color: muted, cursor: "pointer",
            alignItems: "center", justifyContent: "center",
            fontSize: 16, lineHeight: 1,
          }}>×</button>
        )}
        <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
          <ReurbanoMark dark={isDark} />
        </div>
      </div>

      {/* Progress + reset link */}
      <div style={{ padding: "14px 24px 10px", borderBottom: `1px solid ${border}` }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 6 }}>
          <div style={{ fontSize: 10, letterSpacing: "0.12em", textTransform: "uppercase", color: muted }}>
            {t.profile}
          </div>
          <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
            {filled > 0 && (
              <button onClick={onReset} style={{
                background: "transparent", border: "none", padding: 0,
                color: muted, fontSize: 10, letterSpacing: "0.06em", textTransform: "uppercase",
                cursor: "pointer", fontFamily: "var(--font-mono)",
                textDecoration: "underline", textUnderlineOffset: 2, textDecorationColor: faint,
              }}>{t.reset}</button>
            )}
            <div style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: text, fontVariantNumeric: "tabular-nums" }}>
              {String(filled).padStart(2,"0")}<span style={{ color: faint }}>/{String(total).padStart(2,"0")}</span>
            </div>
          </div>
        </div>
        <div style={{ height: 2, background: isDark ? "#26231F" : "#EAE7E4", position: "relative" }}>
          <div style={{ position: "absolute", inset: 0, width: `${(filled / total) * 100}%`, background: accent, transition: "width 280ms cubic-bezier(.4,0,.2,1)" }} />
        </div>
      </div>

      {/* Filters — grouped */}
      <div style={{ flex: 1, overflowY: "auto" }}>
        {groups.map((g, gi) => (
          <GroupSection key={g.key}
            group={g}
            profile={profile}
            setProfile={setProfile}
            lang={lang} dark={isDark} t={t}
            first={gi === 0}
          />
        ))}
        {filled === 0 && (
          <div style={{ padding: "6px 24px 20px", fontSize: 11, color: muted, lineHeight: 1.5, fontStyle: "italic", fontFamily: "Georgia, serif" }}>
            {t.tapToLearn}
          </div>
        )}
      </div>

      {/* Live match + CTA */}
      <div style={{ borderTop: `1px solid ${border}`, background: surface }}>
        <MatchCounter stats={matchStats} t={t} dark={isDark} lang={lang} />
        <div style={{ padding: "12px 24px 16px" }}>
          <button style={{
            width: "100%", padding: "10px 14px", background: accent, color: "#fff",
            border: "none", fontFamily: "var(--font-body)", fontSize: 12.5,
            letterSpacing: "0.02em", cursor: "pointer",
            display: "flex", alignItems: "center", justifyContent: "center", gap: 8,
          }}>
            {t.contact}
            <svg width="10" height="10" viewBox="0 0 10 10" fill="none"><path d="M1 5h8M6 2l3 3-3 3" stroke="currentColor" strokeWidth="1.4"/></svg>
          </button>
          <div style={{ fontSize: 10.5, color: muted, marginTop: 8, lineHeight: 1.5, textAlign: "center" }}>
            {t.ctaText}
          </div>
        </div>
      </div>
    </aside>
  );
}

// ─────────────────────────────────────────────────────────────
// GroupSection — a labeled group of filters (You / Capacity / Preferences)
// ─────────────────────────────────────────────────────────────
function GroupSection({ group, profile, setProfile, lang, dark, t, first }) {
  const text = dark ? "#FAF7F3" : "#393433";
  const muted = dark ? "#8A827F" : "#6B6361";
  const border = dark ? "#2A2825" : "#E2E0DF";

  return (
    <div style={{ padding: "14px 24px 6px", borderTop: first ? "none" : `1px solid ${border}` }}>
      <div style={{ marginBottom: 10 }}>
        <div style={{ fontFamily: "var(--font-mono)", fontSize: 9.5, letterSpacing: "0.2em", textTransform: "uppercase", color: text }}>
          {group.label[lang]}
        </div>
        <div style={{ fontSize: 10.5, color: muted, marginTop: 2, letterSpacing: "-0.005em" }}>
          {group.sub[lang]}
        </div>
      </div>
      {group.filters.map(f => (
        <FilterRow
          key={f.key}
          filter={f}
          value={profile[f.key]}
          onChange={(v) => setProfile({ ...profile, [f.key]: v })}
          lang={lang}
          dark={dark}
          t={t}
        />
      ))}
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// FilterRow — renders pills for small option sets, select for large
// ─────────────────────────────────────────────────────────────
function FilterRow({ filter, value, onChange, lang, dark, t }) {
  const filled = value != null && value !== "";
  const border = dark ? "#2A2825" : "#E2E0DF";
  const text = dark ? "#FAF7F3" : "#393433";
  const muted = dark ? "#8A827F" : "#6B6361";
  const faint = dark ? "#6B6361" : "#9A9290";
  const accent = "#4866B2";
  const surface = dark ? "#22201E" : "#F6F2EC";

  const [whyOpen, setWhyOpen] = useState(false);

  return (
    <div style={{ padding: "8px 0 12px" }}>
      <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 8 }}>
        <label style={{
          display: "inline-flex", alignItems: "center", gap: 7,
          fontSize: 10.5, letterSpacing: "0.01em",
          color: text, fontFamily: "var(--font-body)",
        }}>
          <span style={{ display: "inline-block", width: 6, height: 6, background: filled ? accent : "transparent", border: `1px solid ${filled ? accent : faint}`, verticalAlign: 1, borderRadius: 0 }}/>
          {filter.label[lang]}
        </label>
        {filter.why && (
          <button type="button" aria-label={t.whyLabel} aria-expanded={whyOpen} onClick={() => setWhyOpen(o => !o)} style={{
            width: 16, height: 16, borderRadius: "50%",
            border: `1px solid ${whyOpen ? text : border}`,
            background: whyOpen ? text : "transparent",
            color: whyOpen ? (dark ? "#1A1817" : "#FAF7F3") : muted,
            fontFamily: "Georgia, serif", fontStyle: "italic", fontSize: 10,
            cursor: "pointer", lineHeight: 1,
            padding: 0,
            display: "inline-flex", alignItems: "center", justifyContent: "center",
          }}>?</button>
        )}
      </div>

      {whyOpen && filter.why && (
        <div style={{
          fontSize: 11.5, color: muted, lineHeight: 1.5,
          padding: "8px 10px", marginBottom: 8,
          background: surface, borderLeft: `2px solid ${accent}`,
          fontFamily: "Georgia, serif", fontStyle: "italic",
        }}>
          {filter.why[lang]}
        </div>
      )}

      {filter.kind === "pills" ? (
        <PillRow filter={filter} value={value} onChange={onChange} lang={lang} dark={dark} t={t}/>
      ) : (
        <SelectInput filter={filter} value={value} onChange={onChange} lang={lang} dark={dark} t={t}/>
      )}
    </div>
  );
}

function PillRow({ filter, value, onChange, lang, dark, t }) {
  const text = dark ? "#FAF7F3" : "#393433";
  const muted = dark ? "#8A827F" : "#6B6361";
  const border = dark ? "#2A2825" : "#E2E0DF";
  const accent = "#4866B2";
  const inputBg = dark ? "#26231F" : "#FFFFFF";

  const pills = filter.options.map(o => ({ v: String(o.value), label: (o.short && o.short[lang]) || o.label[lang] }));
  // Add an "Any" choice first (clears value)
  const isUnset = value == null || value === "";

  return (
    <div style={{ display: "flex", gap: 6, flexWrap: "wrap" }}>
      <PillButton
        active={isUnset}
        onClick={() => onChange(null)}
        dark={dark}
        placeholder>
        — {t.none_opt || "Any"}
      </PillButton>
      {pills.map(p => (
        <PillButton key={p.v}
          active={value === p.v}
          onClick={() => onChange(p.v === value ? null : p.v)}
          dark={dark}>
          {p.label}
        </PillButton>
      ))}
    </div>
  );
}

function PillButton({ active, onClick, dark, children, placeholder }) {
  const text = dark ? "#FAF7F3" : "#393433";
  const muted = dark ? "#8A827F" : "#6B6361";
  const faint = dark ? "#6B6361" : "#9A9290";
  const border = dark ? "#2A2825" : "#E2E0DF";
  const inputBg = dark ? "#26231F" : "#FFFFFF";
  const accent = "#4866B2";

  // Placeholder pill (the "Any" clear-state) is smaller / more muted
  if (placeholder) {
    return (
      <button type="button" onClick={onClick} style={{
        padding: "6px 10px",
        background: active ? (dark ? "#1A1817" : "#FAF7F3") : "transparent",
        border: `1px dashed ${active ? (dark ? "#5A5654" : "#A9A3A0") : border}`,
        color: active ? muted : faint,
        fontFamily: "var(--font-mono)", fontSize: 10, letterSpacing: "0.12em", textTransform: "uppercase",
        cursor: "pointer",
        transition: "background 160ms, border-color 160ms, color 160ms",
      }}>
        {children}
      </button>
    );
  }

  return (
    <button type="button" onClick={onClick} style={{
      padding: "6px 11px",
      background: active ? text : inputBg,
      border: `1px solid ${active ? text : border}`,
      color: active ? (dark ? "#1A1817" : "#FAF7F3") : text,
      fontFamily: "var(--font-body)", fontSize: 12, letterSpacing: "-0.005em",
      cursor: "pointer",
      fontWeight: active ? 500 : 400,
      transition: "background 160ms, border-color 160ms, color 160ms",
    }}>
      {children}
    </button>
  );
}

function SelectInput({ filter, value, onChange, lang, dark, t }) {
  const filled = value != null && value !== "";
  const border = dark ? "#2A2825" : "#E2E0DF";
  const text = dark ? "#FAF7F3" : "#393433";
  const faint = dark ? "#6B6361" : "#9A9290";
  const inputBg = dark ? "#26231F" : "#FFFFFF";

  return (
    <div style={{ position: "relative" }}>
      <select
        value={filled ? value : ""}
        onChange={(e) => onChange(e.target.value || null)}
        style={{
          width: "100%",
          appearance: "none", WebkitAppearance: "none",
          background: inputBg,
          border: filled ? `1px solid ${text}` : `1px solid ${border}`,
          color: filled ? text : faint,
          fontFamily: "var(--font-body)",
          fontSize: 13,
          padding: "8px 28px 8px 10px",
          borderRadius: 0,
          cursor: "pointer",
          outline: "none",
          letterSpacing: "-0.005em",
        }}
      >
        <option value="">— {t.none_opt}</option>
        {filter.options.map(o => (
          <option key={String(o.value)} value={String(o.value)}>
            {o.label[lang]}
          </option>
        ))}
      </select>
      <svg width="10" height="10" viewBox="0 0 10 10" fill="none"
        style={{ position: "absolute", right: 10, top: "50%", transform: "translateY(-50%)", pointerEvents: "none", color: filled ? text : faint }}>
        <path d="M2 3.5L5 6.5L8 3.5" stroke="currentColor" strokeWidth="1.3" fill="none"/>
      </svg>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────
// MatchCounter — live stats at bottom of sidebar
// ─────────────────────────────────────────────────────────────
function MatchCounter({ stats, t, dark, lang }) {
  const text = dark ? "#FAF7F3" : "#393433";
  const muted = dark ? "#8A827F" : "#6B6361";
  const border = dark ? "#2A2825" : "#E2E0DF";
  const accent = "#4866B2";
  const lime = "#EDFE38";

  // Bump animation when numbers change
  const [pulse, setPulse] = useState(0);
  const lastP = useRef(stats.prods);
  useEffect(() => {
    if (lastP.current !== stats.prods) { setPulse(p => p + 1); lastP.current = stats.prods; }
  }, [stats.prods]);

  if (stats.none) {
    return (
      <div style={{
        padding: "12px 24px",
        borderBottom: `1px solid ${border}`,
        display: "flex", alignItems: "center", gap: 10,
      }}>
        <svg width="14" height="14" viewBox="0 0 14 14" fill="none" aria-hidden="true">
          <circle cx="7" cy="7" r="6" stroke={muted} strokeWidth="1.2" strokeDasharray="2 2"/>
        </svg>
        <div style={{ fontSize: 11, color: muted, lineHeight: 1.4, fontStyle: "italic", fontFamily: "Georgia, serif" }}>
          {t.emptyProfileHint}
        </div>
      </div>
    );
  }

  const zero = stats.prods === 0;

  return (
    <div style={{
      padding: "12px 24px",
      borderBottom: `1px solid ${border}`,
    }}>
      <div style={{ fontFamily: "var(--font-mono)", fontSize: 9, letterSpacing: "0.18em", textTransform: "uppercase", color: muted, marginBottom: 6 }}>
        {t.yourMatch}
      </div>
      <div key={pulse} style={{
        display: "flex", alignItems: "baseline", gap: 16,
        animation: "matchBump 400ms cubic-bezier(.22,.61,.36,1)",
      }}>
        <div>
          <span style={{
            fontFamily: "var(--font-display)",
            fontSize: 28,
            letterSpacing: "-0.025em",
            color: zero ? muted : text,
            lineHeight: 1,
            display: "inline-block",
            verticalAlign: "baseline",
          }}>
            {stats.prods}
          </span>
          {!zero && (
            <span style={{ display: "inline-block", width: 6, height: 6, background: lime, marginLeft: 8, verticalAlign: 5, border: `1px solid ${dark ? "#8A8A18" : "#9C9A18"}` }}/>
          )}
          <div style={{ fontSize: 10.5, color: muted, marginTop: 2, letterSpacing: "0.02em" }}>
            {t.productsFit}
          </div>
        </div>
        <div style={{ width: 1, height: 30, background: border, alignSelf: "center" }}/>
        <div>
          <div style={{
            fontFamily: "var(--font-display)", fontSize: 28, letterSpacing: "-0.025em",
            color: zero ? muted : text, lineHeight: 1,
          }}>
            {stats.projects}
          </div>
          <div style={{ fontSize: 10.5, color: muted, marginTop: 2, letterSpacing: "0.02em" }}>
            {t.projectsHit}
          </div>
        </div>
      </div>
    </div>
  );
}

function ReurbanoMark({ dark }) {
  const c = dark ? "#FAF7F3" : "#393433";
  // simplified "r" mark
  return (
    <svg width="22" height="22" viewBox="0 0 22 22" fill="none">
      <rect x="0.5" y="0.5" width="21" height="21" stroke={c} strokeWidth="1"/>
      <path d="M6 16V8h4.2c1.8 0 2.9 1 2.9 2.5 0 1.3-.8 2.2-2 2.4L13.8 16H12l-2.5-3H7.5v3H6zm1.5-4.3h2.5c1.1 0 1.7-.5 1.7-1.3s-.6-1.3-1.7-1.3H7.5v2.6z" fill={c}/>
    </svg>
  );
}

window.Sidebar = Sidebar;
