// Mobile redesign — header + feed.
//
// Header layout matches the v2 design screenshots:
//   row 1: logo · "Opportunities" · spacer · EN/ES seg · USD/MXN seg
//   row 2: three lime filter chips (Residency, Check size, Horizon),
//          each wraps a native <select> for the picker UX
//   row 3: FX rate hint, right-aligned
//   row 4: "N PROJECTS · M FIT YOUR PROFILE" stats bar
//
// No empty state — filters are inline and always visible, so the feed
// always renders cards even with a blank profile.

const { useMemo: _useMemoMF } = React;

function _mfMuted(dark) { return dark ? "#8A827F" : "#6B6361"; }
function _mfBorder(dark) { return dark ? "#2A2825" : "#E2E0DF"; }
function _mfInk(dark) { return dark ? "#FAF7F3" : "#393433"; }
function _mfSurface(dark) { return dark ? "#0D0D0D" : "#FAF7F3"; }

// Lime filter chip wrapping a native <select>. The select is visually
// hidden but covers the chip — taps open the platform picker. The chip
// re-renders with the chosen option's label.
// Shorter chip labels than what the sheet's `Check size (USD)` /
// `Investment horizon` produce — the chip is narrow, the parenthetical/
// long words wrap or truncate. The native select retains the full label
// as aria-label so accessibility stays correct.
const _MOBILE_CHIP_SHORT = {
  en: { residency: "Tax res.", checkSize: "Check size", horizon: "Horizon" },
  es: { residency: "Res. fiscal", checkSize: "Cheque", horizon: "Horizonte" },
};

function MobileFilterChip({ filter, value, onChange, lang, dark }) {
  const fullLbl = window.pickLang(filter.label, lang) || filter.key;
  const lbl = (_MOBILE_CHIP_SHORT[lang] && _MOBILE_CHIP_SHORT[lang][filter.key]) || fullLbl;
  const opts = filter.options || [];
  const current = opts.find(o => o.value === value);
  const currentLabel = current ? window.pickLang(current.label, lang) : null;
  // Same none_opt string the desktop sidebar shows; edit it in content/strings.json.
  const t = (window.STRINGS && window.STRINGS[lang]) || {};
  const placeholder = t.none_opt || "Any";
  // Chip lights lime only once a value is selected; default state sits in a
  // neutral paper/cream surface so the lime reads as "active filter."
  const isActive = !!value;
  const bg = isActive ? "#EDFE38" : (dark ? "#1A1817" : "#FFFFFF");
  const borderColor = isActive ? "#393433" : (dark ? "#2A2825" : "#E2E0DF");
  const fg = isActive ? "#393433" : (dark ? "#FAF7F3" : "#393433");
  return (
    // data-filter-key mirrors the desktop .r-filter-row so the residency
    // coach mark can find one anchor by the same attribute on both layouts.
    <label data-filter-key={filter.key} style={{
      position: "relative",
      flex: "1 1 0",
      minWidth: 0,
      display: "block",
      background: bg,
      border: `1px solid ${borderColor}`,
      // The arrow sits on the label row, so the value line gets the full
      // width: "Cualquiera" (84px) fits from 360px viewports up.
      padding: "10px 9px",
      cursor: "pointer",
      color: fg,
    }}>
      <div style={{
        fontFamily: "var(--font-mono)", fontSize: 9.5,
        letterSpacing: "0.16em", textTransform: "uppercase",
        whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis",
        paddingRight: 14, // keeps the label clear of the arrow
      }}>
        {lbl}
      </div>
      <div style={{
        fontFamily: "var(--font-display)", fontSize: 15,
        letterSpacing: "-0.01em", lineHeight: 1.1, marginTop: 2,
        whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis",
      }}>
        {currentLabel || placeholder}
      </div>
      <span aria-hidden="true" style={{
        // 10px top padding + 1.5 centers the triangle on the label's capitals.
        position: "absolute", right: 10, top: 11.5,
        fontSize: 10, lineHeight: 1, pointerEvents: "none",
      }}>▼</span>
      <select
        value={value || ""}
        onChange={(e) => onChange(e.target.value || null)}
        aria-label={fullLbl}
        style={{
          position: "absolute", inset: 0,
          width: "100%", height: "100%",
          opacity: 0, cursor: "pointer",
          fontSize: 16, // prevents iOS zoom on focus
        }}>
        <option value="">{placeholder}</option>
        {opts.map(o => (
          <option key={o.value} value={o.value}>
            {window.pickLang(o.label, lang) || o.value}
          </option>
        ))}
      </select>
    </label>
  );
}

function MobileTypePills({ profile, setProfile, lang, dark }) {
  const f = window.buildTypeInterestFilter ? window.buildTypeInterestFilter() : null;
  if (!f) return null;
  const border = _mfBorder(dark);
  const ink = _mfInk(dark);
  const value = profile.typeInterest;
  const sel = Array.isArray(value) ? value : (value == null ? (f.default || []) : [String(value)]);
  const has = (v) => sel.includes(v);
  const toggle = (v) => {
    const base = Array.isArray(value) ? value.slice() : (f.default || []).slice();
    const i = base.indexOf(v);
    if (i >= 0) base.splice(i, 1); else base.push(v);
    setProfile(prev => ({ ...prev, typeInterest: base }));
  };
  return (
    <div style={{ display: "flex", gap: 6, flexWrap: "wrap", marginTop: 8 }}>
      {f.options.map(o => {
        const v = String(o.value);
        const on = has(v);
        return (
          <button key={v} type="button" aria-pressed={on} onClick={() => toggle(v)} style={{
            padding: "6px 11px",
            background: on ? "#EDFE38" : (dark ? "#26231F" : "#FFFFFF"),
            border: `1px solid ${on ? "#EDFE38" : border}`,
            color: ink, fontFamily: "var(--font-body)", fontSize: 12,
            fontWeight: on ? 500 : 400, cursor: "pointer",
          }}>
            {o.label[lang] || o.label.en}
          </button>
        );
      })}
    </div>
  );
}

function MobileTopBar({ t, lang, setLang, currency, setCurrency, dark, profile, setProfile }) {
  const ink = _mfInk(dark);
  const muted = _mfMuted(dark);
  const border = _mfBorder(dark);
  const surface = _mfSurface(dark);

  const filters = window.FILTERS || [];
  const visibleKeys = ["residency", "checkSize", "horizon"];
  const visibleFilters = visibleKeys
    .map(k => filters.find(f => f.key === k))
    .filter(Boolean);

  return (
    // Sticks under the fixed site header (story-page.jsx, 48px), which carries the logo, the
    // navigation (its Menu) and the one EN/ES switch.
    <header className="r-mtopbar" style={{
      position: "sticky", top: 48, zIndex: 10,
      background: surface,
      borderBottom: `1px solid ${border}`,
      padding: "var(--safe-top, 0px) 14px 10px",
    }}>
      <div className="r-mtopbar-row" style={{
        height: 56,
        display: "flex", alignItems: "center", gap: 10,
      }}>
        <div style={{
          display: "flex", alignItems: "center", gap: 10, minWidth: 0, flex: 1,
        }}>
          <span style={{
            fontFamily: "var(--font-display)", fontSize: 18,
            letterSpacing: "-0.01em", color: ink, whiteSpace: "nowrap",
            overflow: "hidden", textOverflow: "ellipsis",
          }}>
            {lang === "es" ? "Oportunidades" : "Opportunities"}
          </span>
        </div>
      </div>

      <div className="r-mtopbar-filterlbl" style={{
        marginTop: 12, marginBottom: 6,
        fontFamily: "var(--font-mono)", fontSize: 10.5, letterSpacing: "0.08em",
        textTransform: "uppercase", color: muted,
      }}>
        {lang === "es" ? "Filtrar oportunidades" : "Filter opportunities"}
      </div>

      <div style={{
        display: "flex", gap: 8,
      }}>
        {visibleFilters.map(f => (
          <MobileFilterChip
            key={f.key}
            filter={f}
            value={profile[f.key] || ""}
            onChange={(v) => setProfile(prev => ({ ...prev, [f.key]: v }))}
            lang={lang}
            dark={dark}
          />
        ))}
      </div>

      <MobileTypePills profile={profile} setProfile={setProfile} lang={lang} dark={dark} />

    </header>
  );
}

function MobileStatsBar({ columns, lang, dark, onCollapseAll }) {
  const muted = _mfMuted(dark);
  const ink = _mfInk(dark);

  const total = columns.length;
  const fit = columns.filter(c => {
    for (const cell of c.cells.values()) {
      if (cell.eligible || cell.strategicActive) return true;
    }
    return false;
  }).length;

  const projectsLabel = lang === "es"
    ? (total === 1 ? "PROYECTO" : "PROYECTOS")
    : (total === 1 ? "PROJECT" : "PROJECTS");
  const fitLabel = lang === "es" ? "ENCAJAN" : "FIT YOUR PROFILE";

  return (
    <div className="r-mstatsbar" style={{
      padding: "14px 16px 10px",
      display: "flex", alignItems: "center", justifyContent: "space-between",
      gap: 12,
      fontFamily: "var(--font-mono)", fontSize: 10.5,
      letterSpacing: "0.14em", textTransform: "uppercase",
      color: ink,
    }}>
      <div>
        <span>{total} {projectsLabel}</span>
      </div>
      {onCollapseAll && (
        <button
          type="button"
          onClick={onCollapseAll}
          style={{
            background: "transparent", border: "none", padding: 0,
            color: "#4866B2",
            fontFamily: "var(--font-mono)", fontSize: 10.5,
            letterSpacing: "0.14em", textTransform: "uppercase",
            cursor: "pointer",
            textDecoration: "underline", textUnderlineOffset: 3,
          }}>
          {lang === "es" ? "Colapsar todo" : "Collapse all"}
        </button>
      )}
    </div>
  );
}

function MobileFeed({ columns, profile, t, lang, dark, currency, onSelectProduct }) {
  const ranked = _useMemoMF(() => {
    const withScore = columns.map((c, i) => {
      let score = 0;
      for (const cell of c.cells.values()) {
        if (cell.eligible || cell.strategicActive) score++;
      }
      return { c, i, score };
    });
    withScore.sort((a, b) => {
      if (b.score !== a.score) return b.score - a.score;
      return a.i - b.i;
    });
    return withScore.map(x => x.c);
  }, [columns]);

  const mutedColor = dark ? "#8A827F" : "#6B6361";
  return (
    <div className="r-mfeed-list" style={{
      padding: "0 14px 32px",
      display: "flex", flexDirection: "column", gap: 14,
    }}>
      {ranked.map((col) => (
        <window.MobileProjectCard
          key={col.name}
          column={col}
          profile={profile}
          t={t}
          lang={lang}
          dark={dark}
          currency={currency}
          onSelectProduct={onSelectProduct}
        />
      ))}
      {/* The confidentiality note (in the site header on a desktop, and in the phone's Menu) and the
          currency note the desktop offerings header shows. On phones neither header has room for
          them, so they sit at the bottom of the feed. */}
      {(t.confidentialityNote || t.denominationNote) && (
        <p style={{
          margin: "16px 6px 0",
          fontSize: 11, lineHeight: 1.4, color: mutedColor,
          fontStyle: "italic", textAlign: "center",
          whiteSpace: "pre-line",
        }}>
          {[t.confidentialityNote, t.denominationNote].filter(Boolean).join("\n")}
        </p>
      )}
    </div>
  );
}

Object.assign(window, { MobileTopBar, MobileStatsBar, MobileFeed, MobileFilterChip });
