// Mobile redesign — one card per project.
//
// Matches the v2 design screenshots:
//   - status pip (• OPEN) top-left + collapse arrow top-right
//   - big project name + "CITY · N UNITS" subtitle
//   - 16:10 image
//   - description blurb
//   - "WAYS TO PARTICIPATE" heading
//   - vertical stack of full-width horizontal lime tier rows
//   - progress bar footer + raised% / closes-in-Nd

const { useState: _useStateMC } = React;

function _mcMuted(dark) { return dark ? "#8A827F" : "#6B6361"; }
function _mcBorder(dark) { return dark ? "#2A2825" : "#E2E0DF"; }
function _mcSurface(dark) { return dark ? "#1A1817" : "#FFFFFF"; }
function _mcInk(dark) { return dark ? "#FAF7F3" : "#393433"; }

function _mcStatusLabel(status, lang) {
  const map = {
    "open": { en: "Open", es: "Abierto" },
    "coming-soon": { en: "Coming soon", es: "Próximamente" },
    "closed": { en: "Closed", es: "Cerrado" },
    "funded": { en: "Fully funded", es: "Totalmente fondeado" },
  };
  const m = map[status] || map.open;
  return m[lang] || m.en;
}

function MobileStatusPip({ status, label, lang, dark }) {
  const muted = _mcMuted(dark);
  const ink = _mcInk(dark);
  const colors = window.SETTINGS?.statusColors || {};
  const c = colors[status] || muted;
  return (
    <div style={{
      display: "inline-flex", alignItems: "center", gap: 7,
      fontFamily: "var(--font-mono)", fontSize: 10.5,
      letterSpacing: "0.16em", textTransform: "uppercase",
      color: ink,
    }}>
      <span style={{ width: 8, height: 8, borderRadius: "50%", background: c }}/>
      {label || _mcStatusLabel(status, lang)}
    </div>
  );
}

// One full-width horizontal row for a tier. Lime background; left has
// tier name + code; middle has metric label + value; right has meta
// facts and a chevron. Tap anywhere on the row → opens DetailPanel for
// the product behind this tier.
function MobileTierRow({ tier, cell, lang, dark, onTap, rowIndex = 0, isMuted }) {
  const muted = _mcMuted(dark);
  const ink = _mcInk(dark);
  const product = cell?.product;
  if (!product) return null;

  const t = (window.STRINGS && window.STRINGS[lang]) || {};
  // Strategic-only offerings (OpCo / DevCo) are fully funded and open only to
  // selective additional participation. Desktop renders that treatment in
  // matrix/TowerFloor.jsx:79-89 and detail.jsx:771. Without the same branch
  // here, a phone fell through to the generic stat block and showed
  // "MINIMUM INVESTMENT $250,000" with a live chevron, which reads as an open
  // offering. Same cell flags desktop uses (matrix/Tower.jsx:162-166).
  const isStrategic = !!(cell.strategicActive || cell.strategicOnly);

  // Prefer the per-offering header_label override (e.g. DevCo's "Rev Share")
  // when set in the sheet, else fall back to the generic tier label.
  const headerLabel = product.headerLabel && window.pickLang(product.headerLabel, lang);
  const tierLabelObj = window.TIER_LABELS?.[tier] || { en: tier, es: tier };
  const tierName = headerLabel || tierLabelObj[lang] || tierLabelObj.en || tier;

  // Metric label/value — prefer the first detailStat (which is the headline
  // return for this product), else fall back to formatRange + the kind label.
  // Debt is special: there is no numeric headline (interest rate is negotiated
  // per structure per Dirk's feedback), so render the yieldLabelOverride as
  // the metric label and skip the big-number value entirely. The other stats
  // (hold period, min) still surface in the meta lines on the right.
  const isDebt = product.riskClass === "debt";
  const stats = product.detailStats || [];
  const labelKey = "label" + (lang === "es" ? "Es" : "En");
  const valueKey = "value" + (lang === "es" ? "Es" : "En");
  const main = isDebt ? {} : (stats[0] || {});
  const debtOverride = isDebt
    ? (window.pickLang ? window.pickLang(product.yieldLabelOverride, lang) : "")
    : "";
  const metricLabel = isDebt
    ? (debtOverride || (lang === "es" ? "Personalizado por estructura" : "Customized by structure"))
    : (main[labelKey] || (lang === "es" ? "Rendimiento objetivo" : "Target return"));
  let metricValue = isDebt
    ? ""
    : (main[valueKey] || (window.formatRangeStr ? window.formatRangeStr(product) : "—"));

  // Meta facts on the right — for non-debt: second + third detailStat (hold
  // period, min investment etc.). For debt: pull from the start of stats since
  // we didn't consume stats[0] for the headline. Stack two lines max.
  const metaSlice = isDebt ? stats.slice(0, 2) : stats.slice(1, 3);
  const metaLines = metaSlice.map(s => {
    const lab = s[labelKey] || "";
    const val = s[valueKey] || "";
    if (!val) return null;
    return `${val}`.toUpperCase() === val ? val : `${val}`;
  }).filter(Boolean);

  // Residency restriction badge: surfaces when the eligibility lookup
  // flagged a residency reason for this cell.
  const reasons = Array.isArray(cell?.reasons) ? cell.reasons : [];
  const residencyBlocked = reasons.some(
    r => r && typeof r === "object" && r.filterKey === "residency"
  );
  const restrictedLabel = lang === "es" ? "Restricción de residencia" : "Residency restriction";

  // When the product is residency-restricted for this user (or not yet
  // applicable), still show the row but with a softer lime + restriction
  // badge — matches the design's behavior.
  // Strategic-only offerings (OpCo / DevCo equity) are always highlighted
  // on mobile so users see them as worth tapping, even before any profile
  // input — they're always "open to a conversation".
  const lit = cell.eligible || cell.strategicActive || cell.strategicOnly;
  // Match desktop: lit → light lime wash; ineligible → transparent with faded
  // text (desktop's .r-floor-state-gray treatment).
  const bg = lit ? (dark ? "#2D3A1F" : "#FAFFCE") : "transparent";
  const faint = dark ? "#5A5654" : "#C1C1C1";
  const textColor = lit ? ink : faint;
  const labelColor = lit ? muted : faint;
  const litDelay = rowIndex * 90;

  return (
    <button
      type="button"
      onClick={() => onTap(product)}
      className={(lit ? "r-floor-lit" : "") + (isMuted ? " r-floor-muted" : "")}
      style={{
        position: "relative",
        width: "100%",
        textAlign: "left",
        background: bg,
        color: textColor,
        border: "none",
        borderTop: `1px solid ${_mcBorder(dark)}`,
        padding: "14px 16px",
        cursor: "pointer",
        display: "grid",
        gridTemplateColumns: "108px minmax(0, 1fr) auto",
        columnGap: 12,
        alignItems: "center",
        overflow: "hidden",
      }}>
      {lit && (
        <div className="r-lit-bar" aria-hidden="true" style={{
          background: "#EDFE38",
          animation: `litBarIn 420ms cubic-bezier(.22,.61,.36,1) ${litDelay}ms both`,
        }}/>
      )}
      <div style={{ minWidth: 0 }}>
        <div style={{
          fontFamily: "var(--font-display)", fontSize: 17,
          letterSpacing: "-0.01em", lineHeight: 1.1,
        }}>
          {tierName}
        </div>
        {residencyBlocked && (
          <div style={{
            marginTop: 4,
            fontFamily: "var(--font-mono)", fontSize: 9,
            letterSpacing: "0.14em", textTransform: "uppercase",
            color: labelColor,
            lineHeight: 1.2,
          }}>
            {restrictedLabel}
          </div>
        )}
      </div>

      <div style={{ minWidth: 0 }}>
        {isStrategic ? (
          <>
            <div style={{
              fontFamily: "var(--font-display)", fontSize: 17,
              letterSpacing: "-0.01em", lineHeight: 1.1,
            }}>
              {t.strategicOpenTitle}
            </div>
            <div style={{
              marginTop: 4,
              fontFamily: "var(--font-mono)", fontSize: 9.5,
              letterSpacing: "0.14em", textTransform: "uppercase",
              color: labelColor, lineHeight: 1.35,
            }}>
              {t.fundedSelective}
            </div>
          </>
        ) : (
          <>
            <div style={{
              fontFamily: "var(--font-mono)", fontSize: 9.5,
              letterSpacing: "0.16em", textTransform: "uppercase",
              color: labelColor,
            }}>
              {metricLabel}
            </div>
            {metricValue && (
              <div style={{
                marginTop: 2,
                fontFamily: "var(--font-display)", fontSize: 18,
                letterSpacing: "-0.01em", lineHeight: 1.1,
                whiteSpace: "nowrap",
              }}>
                {metricValue}
              </div>
            )}
          </>
        )}
      </div>

      <div style={{
        display: "flex", alignItems: "center", gap: 10,
        justifySelf: "end",
        textAlign: "right",
      }}>
        <div style={{
          fontFamily: "var(--font-mono)", fontSize: 9.5,
          letterSpacing: "0.14em", textTransform: "uppercase",
          color: labelColor, lineHeight: 1.4,
          maxWidth: 110,
        }}>
          {!isStrategic && metaLines.map((line, i) => (
            <div key={i}>{line}</div>
          ))}
        </div>
        {/* Tap affordance — bordered pill so each row reads as an
            obviously-tappable button, not a static info card. Lit rows get
            an ink-on-paper pill; ineligible rows get a faded variant so
            the affordance is still visible but lower-contrast. */}
        <span
          aria-hidden="true"
          style={{
            display: "inline-flex", alignItems: "center", gap: 4,
            padding: "5px 8px 5px 9px",
            border: `1px solid ${lit ? ink : faint}`,
            color: lit ? ink : faint,
            background: lit ? (dark ? "rgba(255,255,255,0.04)" : "rgba(255,255,255,0.6)") : "transparent",
            fontFamily: "var(--font-mono)", fontSize: 9.5,
            letterSpacing: "0.16em", textTransform: "uppercase",
            lineHeight: 1, whiteSpace: "nowrap",
          }}>
          <span style={{ fontSize: 13, lineHeight: 1, marginTop: -1 }}>›</span>
        </span>
      </div>
    </button>
  );
}

function MobileProjectCard({ column, profile, t, lang, dark, currency, onSelectProduct }) {
  const ink = _mcInk(dark);
  const muted = _mcMuted(dark);
  const border = _mcBorder(dark);
  const surface = _mcSurface(dark);

  const [collapsed, setCollapsed] = _useStateMC(false);

  const products0 = column.products?.[0] || {};
  const status = products0.status || column.status || "open";

  const cells = column.cells || new Map();
  const tiers = window.TIER_ORDER || [];
  const presentTiers = tiers.filter(tk => cells.get(tk)?.product);
  const mutedTiers = window.mutedTypeTiers ? window.mutedTypeTiers(profile) : null;

  // Same precedence as desktop (matrix/Tower.jsx:75): projectAboutShort first,
  // projectCardBlurb as the fallback. These were inverted, and because both
  // fields are populated on all three real projects, each surface always got
  // its own first choice — so a phone and a laptop described the same project
  // differently, every time. projectAboutShort wins because it is the field
  // that is populated on ALL five columns (OpCo and DevCo have no
  // projectCardBlurb at all) and it is the richer copy.
  const blurb =
    window.pickLang(column.projectAboutShort, lang)
    || window.pickLang(column.projectCardBlurb, lang)
    || window.pickLang(column.projectOverview, lang)
    || "";

  const units = column.unitsPlanned;
  const unitsLabel = units && units > 0
    ? (lang === "es" ? `${units} UNIDADES` : `${units} UNITS`)
    : null;
  const cityText = column.city || "";
  const subhead = [cityText.toUpperCase(), unitsLabel].filter(Boolean).join(" · ");

  // Progress + days-left — use the SAME source as the desktop plinth
  // (window.plinthStats), which derives pct from col.percentFundedOverride and
  // daysLeft from the earliest projectCloseDate. The old per-card math read
  // displayPercentFunded/projectPercentFunded, which are absent in the served
  // bundle (→ 0%) and diverged from desktop.
  const _stats = (window.plinthStats && window.plinthStats(column)) || { pct: 0, daysLeft: null };
  const pct = Math.max(0, Math.min(100, _stats.pct || 0));
  const daysLeft = _stats.daysLeft;
  // Funded/strategic towers are exempt from type-filter muting (parity with
  // desktop Tower.jsx) — never partially dim a fully-funded project's rows.
  const isFunded = pct >= 100 && status !== "closed";
  const raisedLabel = `${Math.round(pct)}% ${lang === "es" ? "RECAUDADO" : "RAISED"}`;
  const closesLabel = (daysLeft != null && pct < 100)
    ? (lang === "es" ? `CIERRA EN ${daysLeft}D` : `CLOSES IN ${daysLeft}D`)
    : null;

  return (
    <article style={{
      background: surface,
      border: `1px solid ${border}`,
      color: ink,
      fontFamily: "var(--font-body)",
      overflow: "hidden",
    }}>
      <div style={{
        padding: "14px 16px 0",
        display: "flex", alignItems: "flex-start", justifyContent: "space-between",
        gap: 12,
      }}>
        {/* Relabel a 100%-raised project as "funded" — parity with desktop
            Tower.jsx, which derives the pill from the plinth pct rather than
            the raw status field (every product ships status:"open"). Without
            this the same offering reads FUNDED on desktop and OPEN on a phone. */}
        <MobileStatusPip status={isFunded ? "funded" : status} label={isFunded ? null : window.pickLang(column.statusLabel, lang)} lang={lang} dark={dark}/>
        <button
          type="button"
          onClick={() => setCollapsed(!collapsed)}
          aria-label={collapsed ? "Expand" : "Collapse"}
          style={{
            background: "transparent", border: "none", padding: 4,
            color: muted, cursor: "pointer",
            fontFamily: "var(--font-mono)", fontSize: 12, lineHeight: 1,
          }}>
          {collapsed ? "▼" : "▲"}
        </button>
      </div>

      <div style={{ padding: "8px 16px 14px" }}>
        <h3 style={{
          margin: 0,
          fontFamily: "var(--font-display)", fontSize: 26, letterSpacing: "-0.02em",
          lineHeight: 1.05, fontWeight: 400, color: ink,
        }}>
          {column.name}
        </h3>
        {subhead && (
          <div style={{
            marginTop: 6,
            fontFamily: "var(--font-mono)", fontSize: 10.5,
            letterSpacing: "0.16em",
            color: muted,
          }}>
            {subhead}
          </div>
        )}
      </div>

      {!collapsed && (
        <>
          {column.image && (
            <div style={{
              width: "100%", aspectRatio: "16 / 10",
              background: dark
                ? "linear-gradient(135deg, #221F1E, #3A3534)"
                : "linear-gradient(135deg, #E8E3DC, #C7C0B6)",
              overflow: "hidden",
            }}>
              <img src={column.image} alt={column.name} style={{
                width: "100%", height: "100%", objectFit: "cover", display: "block",
              }}/>
            </div>
          )}

          {blurb && (
            <p style={{
              margin: 0, padding: "14px 16px 12px",
              fontSize: 13.5, lineHeight: 1.5, color: ink,
            }}>
              {blurb}
            </p>
          )}

          {(window.canOpenProject ? window.canOpenProject(column) : (window.hasProjectContent && window.hasProjectContent(column.name))) && (
            <div style={{ padding: "0 16px 20px" }}>
              <button
                className="r-m-viewproject"
                aria-label={`${lang === "es" ? "Ver detalles del proyecto" : "View project details"}: ${column.name}`}
                onClick={() => window.openProject && window.openProject(column)}
              >
                {lang === "es" ? "Ver detalles del proyecto" : "View project details"} →
              </button>
            </div>
          )}

          {presentTiers.length > 0 && (
            <div>
              <div style={{
                padding: "0 16px 8px",
                fontFamily: "var(--font-mono)", fontSize: 10,
                letterSpacing: "0.2em", textTransform: "uppercase",
                color: muted,
              }}>
                {lang === "es" ? "Formas de participar" : "Ways to participate"}
              </div>
              <div>
                {presentTiers.map((tk, i) => (
                  <MobileTierRow
                    key={tk}
                    tier={tk}
                    rowIndex={i}
                    cell={cells.get(tk)}
                    lang={lang}
                    dark={dark}
                    onTap={onSelectProduct}
                    isMuted={!isFunded && !!(mutedTiers && mutedTiers.has(tk))}
                  />
                ))}
              </div>
            </div>
          )}

          {(pct > 0 || closesLabel) && (
            <div style={{
              padding: "12px 16px 14px",
              borderTop: `1px solid ${border}`,
            }}>
              <div style={{
                height: 4, background: dark ? "#2A2825" : "#E2E0DF",
                position: "relative", marginBottom: 8,
              }}>
                <div style={{
                  position: "absolute", left: 0, top: 0, bottom: 0,
                  width: `${pct}%`,
                  background: "#4866B2",
                }}/>
              </div>
              <div style={{
                display: "flex", justifyContent: "space-between", gap: 10,
                fontFamily: "var(--font-mono)", fontSize: 10,
                letterSpacing: "0.14em", textTransform: "uppercase",
                color: muted,
              }}>
                <span>{raisedLabel}</span>
                {closesLabel && <span>{closesLabel}</span>}
              </div>
            </div>
          )}
        </>
      )}
    </article>
  );
}

Object.assign(window, { MobileProjectCard, MobileStatusPip, MobileTierRow });
