// onboard-step-modules.jsx — Wizard step: pick modules to enable.
//
// R03 / T0007. The user picks which trial-able modules to switch on.
// Selections are turned into `workspaces/{wid}/modules/{moduleId}` docs
// via the `enableModule` callable (which resolves the user's primary
// workspace server-side if not specified).
//
// Visual design mirrors site-a.jsx's BundlePickerSection — same .dirA-mod-*
// classes but locally scoped so the marketing CSS stays decoupled.
//
// Skippable — users can also enable modules later from Settings →
// Modules. If skipped, no modules are enabled (always-on still work).

(function (window) {
  'use strict';

  const { useAuth } = window.exoteamAuth || {};
  if (!useAuth) {
    console.error('onboard-step-modules.jsx: window.exoteamAuth missing — load order issue');
    return;
  }

  // Initials for the colored pip in the top-left of each card.
  function initials(label) {
    return (label || '')
      .split(/\s+/)
      .map((w) => w[0])
      .filter(Boolean)
      .slice(0, 2)
      .join('')
      .toUpperCase();
  }

  // Convert the catalog's trial_quota object into chip strings shown
  // along the card's bottom row — e.g. {dossiers: 5} → "5 dossiers".
  function quotaChips(trialQuota) {
    if (!trialQuota) return [];
    return Object.entries(trialQuota).map(([metric, n]) => {
      const word = metric.replace(/_/g, ' ');
      return `${n} ${word}`;
    });
  }

  function StepModules({ onAdvance, onSkip, onBack }) {
    useAuth();
    const mods = window.exoteamModules || {};
    const alwaysOn = (mods.alwaysOnModules && mods.alwaysOnModules()) || [];
    const catalog = (mods.selectableModules && mods.selectableModules()) || [];
    const basePrice = typeof mods.BASE_PRICE_GBP_MONTHLY === 'number'
      ? mods.BASE_PRICE_GBP_MONTHLY
      : 0;
    const [picked, setPicked] = React.useState(() => new Set(['outreach']));
    const [busy, setBusy] = React.useState(false);
    const [err, setErr] = React.useState(null);
    // R10T03 — read org_kind from workspace doc (set if user came back
    // after running Learn on the work step). Drives the "Recommended"
    // badge on add-on modules. Empty/missing → no nudges, neutral grid.
    const [orgKindForNudges, setOrgKindForNudges] = React.useState('');
    React.useEffect(() => {
      const a = window.exoteamAuth;
      if (!a || !a.user || !a.db) return;
      a.db.collection('memberships')
        .where('user_id', '==', a.user.uid)
        .limit(1).get().then((snap) => {
          if (snap.empty) return;
          const wid = snap.docs[0].data().workspace_id;
          return a.db.collection('workspaces').doc(wid).get();
        })
        .then((ws) => {
          if (ws && ws.exists) {
            const d = ws.data() || {};
            if (d.org_kind) setOrgKindForNudges(d.org_kind);
          }
        })
        .catch((e) => console.warn('StepModules: org_kind read failed', e));
    }, []);
    const recommendedSet = React.useMemo(() => {
      if (!orgKindForNudges || !window.ExoteamOrgKind) return new Set();
      return new Set(window.ExoteamOrgKind.modulesFor(orgKindForNudges));
    }, [orgKindForNudges]);

    // Total = base subscription (always-on modules) + sum of picked
    // add-ons. Always-on modules don't carry a per-module price; the
    // base covers them collectively.
    const addOnsMonthly = catalog
      .filter((m) => picked.has(m.id))
      .reduce((sum, m) => sum + (m.price_gbp_monthly || 0), 0);
    const totalMonthly = basePrice + addOnsMonthly;

    function toggle(id) {
      setPicked((prev) => {
        const next = new Set(prev);
        if (next.has(id)) next.delete(id);
        else next.add(id);
        return next;
      });
    }

    async function submit() {
      if (picked.size === 0) {
        onSkip();
        return;
      }
      setBusy(true);
      setErr(null);
      try {
        const callable = window.exoteamAuth.fns.httpsCallable('enableModule');
        // Enable sequentially so the global trial baseline is
        // established by the first call before subsequent ones inherit.
        // No workspace_id sent — the callable resolves the user's
        // primary workspace from the auth uid. For "+ Add Workspace"
        // mode the wrapping wizard will pre-set the active workspace.
        for (const id of picked) {
          await callable({ module_id: id });
        }
        onAdvance();
      } catch (e) {
        setErr(e.message || String(e));
      } finally {
        setBusy(false);
      }
    }

    return (
      <div className="exo-onboard-step exo-mod-step">
        <style>{`
.exo-mod-step .exo-step-title { font-size: 38px; letter-spacing: -0.025em; font-weight: 600; line-height: 1.08; color: #1d1d1f; margin: 0 0 14px; }
.exo-mod-step .exo-step-body { font-size: 16px; color: #6e6e73; line-height: 1.55; max-width: 720px; margin: 0 0 28px; }
.exo-mod-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; }
.exo-mod-section-h { font-size: 13px; color: #86868b; font-weight: 600; text-transform: uppercase; letter-spacing: 0.08em; margin: 28px 0 12px; }
.exo-mod-section-h:first-child { margin-top: 0; }
.exo-mod-section-sub { font-size: 13px; color: #86868b; font-weight: 400; text-transform: none; letter-spacing: 0; margin-left: 8px; }
/* Foundation grid: 4-up on wide screens (≥1024px), 2x2 at intermediate
   widths, single column on mobile. Tracks the 4 included modules
   (Overview, Inbox, Calendar, Contacts) — one row at desktop sizes
   so they read as a single horizontal "what you always get" band. */
.exo-mod-foundation-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
.exo-mod-foundation-card {
  background: rgba(0,0,0,0.025); border: 1px solid rgba(0,0,0,0.05); border-radius: 16px;
  padding: 18px 18px 16px; display: flex; flex-direction: column; gap: 8px;
}
.exo-mod-foundation-row { display: flex; align-items: center; gap: 10px; }
.exo-mod-foundation-pip { width: 26px; height: 26px; border-radius: 8px; background: var(--ba, #1d1d1f); color: #fff; display: grid; place-items: center; font-weight: 700; font-size: 10px; letter-spacing: 0.02em; }
.exo-mod-foundation-h { font-size: 15px; font-weight: 600; letter-spacing: -0.01em; color: #1d1d1f; flex: 1; }
.exo-mod-foundation-included { font-size: 10px; color: #5db98a; font-weight: 600; text-transform: uppercase; letter-spacing: 0.06em; }
.exo-mod-foundation-blurb { font-size: 13px; color: #424245; line-height: 1.55; margin: 0; }
@media (max-width: 1023px) {
  .exo-mod-foundation-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
  .exo-mod-foundation-grid { grid-template-columns: 1fr; }
}
.exo-mod-card {
  background: #fff; border: 1.5px solid rgba(0,0,0,0.06); border-radius: 22px;
  padding: 22px 22px 20px; cursor: pointer; text-align: left;
  font: inherit; font-family: inherit; color: inherit;
  display: flex; flex-direction: column; gap: 0; position: relative;
  transition: border-color 0.18s ease, transform 0.18s ease, box-shadow 0.18s ease;
}
.exo-mod-card:hover { transform: translateY(-2px); box-shadow: 0 12px 32px rgba(0,0,0,0.06); }
.exo-mod-card.on {
  border-color: var(--ba, #1d1d1f);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ba, #1d1d1f) 14%, transparent), 0 12px 32px rgba(0,0,0,0.06);
}
.exo-mod-row { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.exo-mod-pip {
  width: 30px; height: 30px; border-radius: 9px;
  background: var(--ba, #1d1d1f); color: #fff;
  display: grid; place-items: center;
  font-weight: 700; font-size: 11px; letter-spacing: 0.02em;
  box-shadow: inset 0 0 0 0.5px rgba(255,255,255,0.2);
}
.exo-mod-h { font-size: 17px; font-weight: 600; letter-spacing: -0.015em; color: #1d1d1f; flex: 1; }
.exo-mod-body { font-size: 13px; color: #424245; line-height: 1.55; margin-bottom: 14px; }
.exo-mod-price { font-size: 13px; color: #1d1d1f; margin-bottom: 14px; display: flex; align-items: baseline; gap: 6px; }
.exo-mod-price-n { font-weight: 600; font-size: 15px; letter-spacing: -0.01em; }
.exo-mod-price-after { color: #86868b; font-size: 12px; }
.exo-mod-chips { display: flex; flex-wrap: wrap; gap: 5px; padding-top: 14px; border-top: 1px solid rgba(0,0,0,0.06); margin-top: auto; }
.exo-mod-chip { font-size: 11.5px; padding: 3px 9px; border-radius: 999px; background: rgba(0,0,0,0.04); color: #424245; font-weight: 500; white-space: nowrap; }
.exo-mod-card.on .exo-mod-chip { background: color-mix(in srgb, var(--ba, #1d1d1f) 8%, transparent); color: var(--ba, #1d1d1f); }
.exo-mod-chips-label { font-size: 10.5px; color: #86868b; text-transform: uppercase; letter-spacing: 0.06em; margin-right: 4px; align-self: center; font-weight: 500; }
.exo-mod-tick {
  width: 22px; height: 22px; border-radius: 50%; border: 1.5px solid rgba(0,0,0,0.15);
  background: #fff; flex-shrink: 0; display: grid; place-items: center; transition: all 0.15s ease;
}
.exo-mod-card.on .exo-mod-tick { background: var(--ba, #1d1d1f); border-color: var(--ba, #1d1d1f); }
.exo-mod-card.on .exo-mod-tick svg { color: #fff; }
.exo-mod-total {
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin-top: 32px;
  padding: 18px 0;
  border-top: 1px solid rgba(0,0,0,0.08);
  border-bottom: 1px solid rgba(0,0,0,0.08);
}
.exo-mod-total-amount { font-size: 28px; font-weight: 600; letter-spacing: -0.02em; color: #1d1d1f; line-height: 1; }
.exo-mod-total-suffix { font-size: 14px; color: #6e6e73; }
.exo-mod-total-break { margin-left: auto; font-size: 12.5px; color: #86868b; }
.exo-mod-total.is-zero .exo-mod-total-amount { color: #86868b; font-weight: 500; }
.exo-mod-actions { display: flex; gap: 18px; align-items: center; margin-top: 24px; }
.exo-mod-cta {
  padding: 12px 22px; border-radius: 999px;
  background: #1d1d1f; color: #fff;
  font-size: 13.5px; font-weight: 500; border: none; cursor: pointer;
  transition: opacity 0.15s ease;
}
.exo-mod-cta:disabled { opacity: 0.5; cursor: default; }
.exo-mod-skip {
  background: transparent; border: none;
  font-size: 13.5px; color: #5b8def;
  cursor: pointer; padding: 0;
}
.exo-mod-skip:hover { text-decoration: underline; }
.exo-mod-err {
  background: #fdecea; color: #b3261e;
  padding: 10px 14px; border-radius: 10px;
  font-size: 13.5px; margin-bottom: 16px;
}
@media (max-width: 920px) {
  .exo-mod-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 600px) {
  .exo-mod-grid { grid-template-columns: 1fr; }
  .exo-mod-step .exo-step-title { font-size: 28px; }
}
        `}</style>

        <h1 className="exo-step-title">What do you want exoteam to do for you?</h1>
        <p className="exo-step-body">
          Every Workspace gets the{' '}
          <strong style={{ color: '#1d1d1f', fontWeight: 600 }}>foundation</strong>{' '}
          — inbox, calendar, contacts, daily overview —{' '}
          for <strong style={{ color: '#1d1d1f', fontWeight: 600 }}>£{basePrice}/mo</strong>.
          Add the modules you need on top: each is{' '}
          <strong style={{ color: '#1d1d1f', fontWeight: 600 }}>free for 14 days</strong>,
          then <strong style={{ color: '#1d1d1f', fontWeight: 600 }}>£30/mo</strong>{' '}
          if you decide to keep it. No card needed to start.
        </p>

        {err && <p className="exo-mod-err">{err}</p>}

        <h2 className="exo-mod-section-h">
          Foundation
          <span className="exo-mod-section-sub">— always on, included in your base £{basePrice}/mo</span>
        </h2>
        <div className="exo-mod-foundation-grid">
          {alwaysOn.map((m) => (
            <div
              key={m.id}
              className="exo-mod-foundation-card"
              style={{ '--ba': m.colour || '#1d1d1f' }}
            >
              <div className="exo-mod-foundation-row">
                <div className="exo-mod-foundation-pip">{initials(m.label)}</div>
                <div className="exo-mod-foundation-h">{m.label}</div>
                <span className="exo-mod-foundation-included">Included</span>
              </div>
              <p className="exo-mod-foundation-blurb">{m.blurb}</p>
            </div>
          ))}
        </div>

        <h2 className="exo-mod-section-h">
          Add-on modules
          <span className="exo-mod-section-sub">— pick the ones you want, £30/mo each after 14-day trial</span>
        </h2>
        <div className="exo-mod-grid">
          {catalog.map((m) => {
            const on = picked.has(m.id);
            const recommended = recommendedSet.has(m.id);
            const chips = quotaChips(m.trial_quota);
            return (
              <button
                key={m.id}
                type="button"
                className={'exo-mod-card' + (on ? ' on' : '')}
                style={{ '--ba': m.colour || '#1d1d1f' }}
                onClick={() => toggle(m.id)}
              >
                <div className="exo-mod-row">
                  <div className="exo-mod-pip">{initials(m.label)}</div>
                  <div className="exo-mod-h">{m.label}</div>
                  {recommended && (
                    <span style={{
                      fontSize: 10, fontWeight: 600, letterSpacing: '0.06em',
                      textTransform: 'uppercase',
                      padding: '2px 7px', borderRadius: 4,
                      background: 'rgba(91,141,239,0.10)', color: '#3a6fd6',
                      marginRight: 4,
                    }}>Recommended</span>
                  )}
                  <div className="exo-mod-tick">
                    {on && (
                      <svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round">
                        <polyline points="20 6 9 17 4 12" />
                      </svg>
                    )}
                  </div>
                </div>
                <div className="exo-mod-body">{m.blurb}</div>
                {m.price_gbp_monthly && (
                  <div className="exo-mod-price">
                    <span className="exo-mod-price-n">£{m.price_gbp_monthly}/mo</span>
                    <span className="exo-mod-price-after">after 14-day trial</span>
                  </div>
                )}
                {chips.length > 0 && (
                  <div className="exo-mod-chips">
                    <span className="exo-mod-chips-label">Trial</span>
                    {chips.map((c) => (
                      <span key={c} className="exo-mod-chip">{c}</span>
                    ))}
                  </div>
                )}
              </button>
            );
          })}
        </div>

        <div className="exo-mod-total">
          <span className="exo-mod-total-amount">£{totalMonthly}</span>
          <span className="exo-mod-total-suffix">/ month after 14-day trial</span>
          <span className="exo-mod-total-break">
            {picked.size === 0
              ? `£${basePrice} foundation`
              : `£${basePrice} foundation + ${picked.size} module${picked.size === 1 ? '' : 's'} × £30/mo`}
          </span>
        </div>

        <div className="exo-mod-actions" style={{ display: 'flex', alignItems: 'center', gap: 14 }}>
          {onBack && (
            <button
              type="button"
              onClick={onBack}
              disabled={busy}
              className="exo-step-back"
              aria-label="Go to previous step"
            >
              ← Back
            </button>
          )}
          <div style={{ marginLeft: 'auto', display: 'flex', alignItems: 'center', gap: 14 }}>
            <button
              type="button"
              className="exo-mod-cta"
              onClick={submit}
              disabled={busy}
            >
              {busy
                ? 'Enabling…'
                : picked.size === 0
                  ? 'Skip for now'
                  : `Enable ${picked.size} module${picked.size === 1 ? '' : 's'} →`}
            </button>
            {picked.size > 0 && (
              <button type="button" className="exo-mod-skip" onClick={onSkip} disabled={busy}>
                Skip for now
              </button>
            )}
          </div>
        </div>
      </div>
    );
  }

  window.StepModules = StepModules;
})(window);
