/* Village Governance Body — Brand theme, Burmese-first labels with English glosses.
   Persona rule: this user looks after ONE village. The app surface never offers other
   villages — the switcher below is prototype-only chrome for demoing different states.

   Page structure (per Fred): understanding first, then actions branch from it.
     1. Overview      — how are we doing right now, in plain language
     2. Signals & Data — WHY it's happening: full indicator charts per domain
     3. Get support   — apply to protocols / distress signal / track requests
     4. Community Fund — balance, reporting duty, usage history                     */

const DAY_MS = 24 * 60 * 60 * 1000;

/* Plain-language reading of the synthesis, so a non-analyst can act on it. */
function statusSummary(synthesis) {
  const domain = DOMAIN_LABEL[synthesis.topDomain].toLowerCase();
  switch (synthesis.level) {
    case 'severe':
      return 'Conditions are serious. ' + DOMAIN_LABEL[synthesis.topDomain] + ' signals are the main concern, with an estimated ' + synthesis.leadTime + ' before impact. Act on the recommended steps now.';
    case 'warning':
      return 'Risk is elevated and mainly driven by ' + domain + ' signals. You have roughly ' + synthesis.leadTime + ' of lead time — a good window to prepare and consider support.';
    case 'watch':
      return 'Conditions need watching — ' + domain + ' signals are moving, but there is no immediate threat. Review at your next governance meeting.';
    default:
      return 'Conditions look stable. No action is needed this cycle beyond routine monitoring.';
  }
}

/* Why-sentence for one domain, built from its score, 4-week movement and driver. */
function domainWhy(domain, signal, trend) {
  const delta = fourWeekDelta(trend);
  const move = delta >= 3 ? 'has risen ' + delta + ' points over the last month'
    : delta <= -3 ? 'has eased ' + Math.abs(delta) + ' points over the last month'
    : 'has held steady over the last month';
  return DOMAIN_LABEL[domain] + ' risk ' + move + '. Main driver: ' + signal.driver.charAt(0).toLowerCase() + signal.driver.slice(1) + '.';
}

/* Change vs ~4 weeks ago, from the 12-week trend series. */
function fourWeekDelta(points) {
  if (!points || points.length < 5) return 0;
  return points[points.length - 1] - points[points.length - 5];
}
function DeltaChip({ delta }) {
  if (Math.abs(delta) < 3) return <span style={{ font: '11px var(--font-text)', color: 'var(--text-subtle)' }}>±0 vs last month</span>;
  const up = delta > 0;
  return (
    <span style={{ display: 'inline-flex', alignItems: 'center', gap: 3, font: '600 11px var(--font-text)', color: up ? 'var(--severe-strong)' : 'var(--calm-strong)' }}>
      {Ic(up ? 'arrow-up-right' : 'arrow-down-right', { width: 12, height: 12 })}{(up ? '+' : '') + delta} vs last month
    </span>
  );
}

/* Overview row for one domain — clicking it opens the full data view in Signals & Data. */
function DomainSignalRow({ domain, signal, trend, onOpen }) {
  const hot = signal.score >= 50;
  return (
    <button className="ap-row" onClick={onOpen} style={{
      width: '100%', display: 'flex', alignItems: 'center', gap: 12, padding: '11px 6px',
      border: 'none', borderTop: '1px solid var(--border-subtle)', background: 'none', cursor: 'pointer', textAlign: 'left',
    }}>
      <span style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', width: 30, height: 30, borderRadius: 'var(--radius-card)', background: hot ? 'var(--warning-soft)' : 'var(--surface-sunken)', color: hot ? 'var(--warning-strong)' : 'var(--text-muted)', flexShrink: 0 }}>
        {Ic(DOMAIN_ICON[domain], { width: 15, height: 15 })}
      </span>
      <span style={{ minWidth: 76 }}>
        <span style={{ display: 'block', font: '600 13px var(--font-text)', color: 'var(--text-strong)' }}>{DOMAIN_LABEL[domain]}</span>
        <DeltaChip delta={fourWeekDelta(trend)} />
      </span>
      <span style={{ flexShrink: 0 }}><Sparkline points={trend} color={hot ? 'var(--warning)' : 'var(--calm)'} width={96} height={26} /></span>
      <span style={{ flex: 1, font: '12px/1.5 var(--font-text)', color: 'var(--text-muted)', minWidth: 140 }}>{signal.driver}</span>
      <span style={{ font: '700 15px var(--font-mono)', color: hot ? 'var(--warning-strong)' : 'var(--text-strong)', width: 56, textAlign: 'right' }}>{signal.score}<span style={{ font: '10px var(--font-mono)', color: 'var(--text-subtle)' }}>/100</span></span>
      <span style={{ display: 'flex', alignItems: 'center', gap: 4, font: '600 11px var(--font-text)', color: 'var(--brand)', whiteSpace: 'nowrap' }}>
        See the data {Ic('arrow-right', { width: 12, height: 12 })}
      </span>
    </button>
  );
}

/* One domain's full data section in the Signals & Data tab. */
function DomainDetail({ domain, signal, trend, indicators, labels }) {
  const color = DOMAIN_COLOR[domain];
  return (
    <Card padding="lg" elevation="sm" className="ap-rise" style={{ marginBottom: 'var(--space-5)' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap', marginBottom: 'var(--space-2)' }}>
        <span style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', width: 36, height: 36, borderRadius: 'var(--radius-card)', background: 'var(--surface-sunken)', color: color }}>
          {Ic(DOMAIN_ICON[domain], { width: 18, height: 18 })}
        </span>
        <div style={{ flex: 1 }}>
          <div style={{ display: 'flex', alignItems: 'baseline', gap: 10, flexWrap: 'wrap' }}>
            <span style={{ font: '600 16px var(--font-display)', color: 'var(--text-strong)' }}>{DOMAIN_LABEL[domain]}</span>
            <span style={{ font: '700 18px var(--font-mono)', color: 'var(--text-strong)' }}>{signal.score}<span style={{ font: '11px var(--font-mono)', color: 'var(--text-subtle)' }}>/100</span></span>
            <TrendArrow points={trend} />
            <DeltaChip delta={fourWeekDelta(trend)} />
          </div>
        </div>
      </div>
      <div style={{ font: '13px/1.6 var(--font-text)', color: 'var(--text-body)', marginBottom: 'var(--space-5)', padding: '10px 12px', borderRadius: 'var(--radius-card)', background: 'var(--surface-sunken)' }}>
        {domainWhy(domain, signal, trend)}
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(230px, 1fr))', gap: 12 }}>
        {indicators.map(function (ind) {
          return <IndicatorChart key={ind.id} indicator={ind} labels={labels} color={color} />;
        })}
      </div>
    </Card>
  );
}

function VillageApp() {
  const store = useAsterStore();
  const [villageId, setVillageId] = React.useState('v25'); // demo default: a Warning-level village so there's something to act on
  const [pageTab, setPageTab] = React.useState('overview');
  const [signalsFocus, setSignalsFocus] = React.useState('all');
  const [callModal, setCallModal] = React.useState(null); // null | { protocolId } | { general: true } | {}
  const [usageModal, setUsageModal] = React.useState(false);
  const [doneActions, setDoneActions] = React.useState({}); // meeting checklist, local to this session
  const [toast, setToast, toastNode] = useToast();

  const village = window.AsterStore.findVillage(villageId);
  const synthesis = store.synthesis[villageId];
  const signals = store.signals[villageId];
  const trends = store.trends[villageId];
  const indicators = store.indicators[villageId];
  const fund = store.funds[villageId];
  const myCalls = window.AsterStore.callsForVillage(villageId);
  const matchingProtocols = window.AsterStore.protocolsMatchingVillage(villageId);
  const openCalls = myCalls.filter(function (c) { return c.status !== 'triggered' && c.status !== 'declined'; });

  // Fund reporting deadline from cadence: lastReportedDate + cadenceDays.
  const daysSinceReport = Math.floor((Date.now() - new Date(fund.lastReportedDate).getTime()) / DAY_MS);
  const daysUntilDue = fund.cadenceDays - daysSinceReport;
  const reportOverdue = daysUntilDue < 0;
  const reportDueSoon = daysUntilDue >= 0 && daysUntilDue <= 7;

  const villageDone = doneActions[villageId] || {};
  function toggleAction(a) {
    setDoneActions(function (prev) {
      const mine = Object.assign({}, prev[villageId] || {});
      mine[a] = !mine[a];
      return Object.assign({}, prev, { [villageId]: mine });
    });
  }

  function openSignals(domain) { setSignalsFocus(domain || 'all'); setPageTab('signals'); }

  function handleInstall() {
    if (window.__asterDeferredInstallPrompt) {
      window.__asterDeferredInstallPrompt.prompt();
      window.__asterDeferredInstallPrompt.userChoice.then(function (choice) {
        setToast(choice.outcome === 'accepted' ? 'App install started.' : { message: 'Install dismissed — you can try again anytime.', tone: 'info' });
      });
    } else {
      setToast({ message: 'Install prompt not available in this browser session — on a supporting mobile browser this button installs Aster as an app.', tone: 'info' });
    }
  }

  const visibleDomains = ['climate', 'economic', 'conflict'].filter(function (d) { return signalsFocus === 'all' || signalsFocus === d; });

  return (
    <div style={{ maxWidth: 920, margin: '0 auto', padding: 'var(--space-4) var(--space-5) var(--space-11)' }}>

      {/* ---------- DEMO-ONLY chrome: not part of the persona's product surface ---------- */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap', padding: '8px 12px', marginBottom: 'var(--space-6)', border: '1px dashed var(--border-default)', borderRadius: 'var(--radius-card)', background: 'var(--surface-sunken)' }}>
        <span style={{ font: '600 10px var(--font-mono)', letterSpacing: '0.08em', color: 'var(--text-subtle)' }}>PROTOTYPE DEMO</span>
        <span style={{ font: '12px var(--font-text)', color: 'var(--text-subtle)' }}>View as village:</span>
        <select value={villageId} onChange={function (e) { setVillageId(e.target.value); setSignalsFocus('all'); }}
          aria-label="Demo: choose which village to view as"
          style={{ font: '12px var(--font-text)', color: 'var(--text-body)', border: '1px solid var(--border-default)', borderRadius: 'var(--radius-input)', padding: '4px 8px', background: 'var(--surface-card)', maxWidth: 320 }}>
          {store.villages.map(function (v) {
            return <option key={v.id} value={v.id}>{v.name} — {v.township} ({LEVEL_LABEL[store.synthesis[v.id].level]})</option>;
          })}
        </select>
        <span style={{ font: '11px var(--font-text)', color: 'var(--text-subtle)' }}>In production each governance body only ever sees its own village.</span>
      </div>

      {/* ---------- Identity header ---------- */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12, flexWrap: 'wrap', marginBottom: 'var(--space-5)' }}>
        <div>
          <div style={{ font: '600 11px var(--font-text)', letterSpacing: '0.08em', textTransform: 'uppercase', color: 'var(--text-subtle)', marginBottom: 4 }}>
            ကျေးရွာ စီမံခန့်ခွဲမှု အဖွဲ့ · Village Governance Body
          </div>
          <h1 style={{ margin: 0, font: '700 26px var(--font-display)', color: 'var(--text-strong)' }}>{village.name}</h1>
          <div style={{ font: '13px var(--font-text)', color: 'var(--text-muted)', marginTop: 3 }}>
            {village.township}, {village.region} · {village.population.toLocaleString()} people · {village.households.toLocaleString()} households
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 6, font: '12px var(--font-text)', color: 'var(--text-subtle)', marginTop: 6, flexWrap: 'wrap' }}>
            {Ic('users', { width: 13, height: 13 })}{village.governanceBody}
            <span style={{ opacity: 0.5 }}>·</span>
            {Ic('user-check', { width: 13, height: 13 })}Fund manager: {village.fundManager}
          </div>
        </div>
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 8 }}>
          <AlertLevel level={synthesis.level} live={synthesis.level === 'severe' || synthesis.level === 'warning'} />
          <Button variant="ghost" size="sm" iconLeft={Ic('download', { width: 14, height: 14 })} onClick={handleInstall}>
            Install as app
          </Button>
        </div>
      </div>

      {/* ---------- Page tabs ---------- */}
      <Tabs active={pageTab} onChange={setPageTab} items={[
        { id: 'overview', label: 'ခြုံငုံကြည့် · Overview', icon: 'layout-dashboard' },
        { id: 'signals', label: 'အချက်အလက် · Signals & Data', icon: 'line-chart' },
        { id: 'support', label: 'အကူအညီ · Get support', icon: 'megaphone', count: openCalls.length || undefined },
        { id: 'fund', label: 'ရံပုံငွေ · Community Fund', icon: 'wallet', alert: reportOverdue || reportDueSoon },
      ]} />

      {/* ================= OVERVIEW ================= */}
      {pageTab === 'overview' && (
        <div className="ap-rise">
          <Card padding="lg" elevation="sm" accent={synthesis.level} style={{ marginBottom: 'var(--space-5)' }}>
            <div style={{ display: 'flex', gap: 'var(--space-7)', flexWrap: 'wrap', alignItems: 'center' }}>
              <SignalGauge value={synthesis.composite} level={synthesis.level} label="Composite risk" sublabel={LEVEL_LABEL[synthesis.level].toUpperCase()} />
              <div>
                <div style={{ font: '600 11px var(--font-text)', textTransform: 'uppercase', letterSpacing: '0.06em', color: 'var(--text-subtle)', marginBottom: 4 }}>12-week trend</div>
                <Sparkline points={trends.composite} color={LEVEL_COLOR[synthesis.level]} width={170} height={44} />
                <div style={{ display: 'flex', gap: 12, marginTop: 4, alignItems: 'center' }}>
                  <TrendArrow points={trends.composite} />
                  <DeltaChip delta={fourWeekDelta(trends.composite)} />
                </div>
              </div>
              <div style={{ display: 'flex', gap: 'var(--space-6)', flexWrap: 'wrap' }}>
                <Stat label="Lead time" value={synthesis.leadTime} tone="brand" />
                <Stat label="Confidence" value={synthesis.confidence} />
                <Stat label="Last updated" value={fmtRelative(synthesis.lastGenerated)} />
              </div>
            </div>

            <div style={{ marginTop: 'var(--space-5)', padding: '12px 14px', borderRadius: 'var(--radius-card)', background: 'var(--surface-sunken)', display: 'flex', gap: 10 }}>
              {Ic('info', { width: 15, height: 15, style: { flexShrink: 0, marginTop: 2, color: LEVEL_COLOR[synthesis.level] } })}
              <div style={{ font: '13px/1.6 var(--font-text)', color: 'var(--text-body)' }}>
                <strong style={{ color: 'var(--text-strong)' }}>ဆိုလိုသည်မှာ · What this means:</strong> {statusSummary(synthesis)}
              </div>
            </div>

            <div style={{ marginTop: 'var(--space-5)' }}>
              <div style={{ font: '600 12px var(--font-text)', color: 'var(--text-muted)', marginBottom: 4 }}>Signals by domain — tap a row to see the data behind it</div>
              {['climate', 'economic', 'conflict'].map(function (d) {
                return <DomainSignalRow key={d} domain={d} signal={signals[d]} trend={trends[d]} onOpen={function () { openSignals(d); }} />;
              })}
            </div>

            {(synthesis.level === 'warning' || synthesis.level === 'severe') ? (
              <AlertBanner level={synthesis.level} title="You may qualify for anticipatory support"
                icon={Ic('shield-alert', { width: 18, height: 18 })}
                action={<Button variant={synthesis.level === 'severe' ? 'danger' : 'primary'} size="sm" onClick={function () { setPageTab('support'); }}>
                  အကူအညီ ကြည့်မည် · View support options
                </Button>}>
                {matchingProtocols.length > 0
                  ? matchingProtocols.length + ' published protocol' + (matchingProtocols.length > 1 ? 's' : '') + ' currently match your risk level — applying takes under a minute.'
                  : 'No protocol matches yet, but you can send a general distress signal and the Risk Desk will try to match one.'}
              </AlertBanner>
            ) : (
              <div style={{ marginTop: 'var(--space-5)', display: 'flex', alignItems: 'center', gap: 12, flexWrap: 'wrap' }}>
                <Button variant="secondary" size="sm" onClick={function () { setPageTab('support'); }}>
                  အကူအညီ ကြည့်မည် · View support options
                </Button>
                <span style={{ font: '12px var(--font-text)', color: 'var(--text-subtle)' }}>Conditions look {LEVEL_LABEL[synthesis.level].toLowerCase()} — you can still reach out at any time.</span>
              </div>
            )}
          </Card>

          {/* At-a-glance duties strip */}
          <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(240px, 1fr))', gap: 12, marginBottom: 'var(--space-5)' }}>
            <Card padding="md" elevation="sm" interactive className="ap-hover-lift" style={{ cursor: 'pointer' }} onClick={function () { setPageTab('support'); }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
                {Ic('megaphone', { width: 15, height: 15, style: { color: 'var(--brand)' } })}
                <span style={{ font: '600 13px var(--font-text)', color: 'var(--text-strong)' }}>Requests in progress</span>
              </div>
              <div style={{ font: '12px/1.5 var(--font-text)', color: 'var(--text-muted)' }}>
                {openCalls.length === 0 ? 'No open requests. ' + (matchingProtocols.length > 0 ? matchingProtocols.length + ' protocols currently match your level.' : '') : openCalls.length + ' request' + (openCalls.length > 1 ? 's' : '') + ' moving through review — tap to track.'}
              </div>
            </Card>
            <Card padding="md" elevation="sm" interactive className="ap-hover-lift" style={{ cursor: 'pointer' }} onClick={function () { setPageTab('fund'); }}>
              <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
                {Ic('wallet', { width: 15, height: 15, style: { color: reportOverdue ? 'var(--warning-strong)' : 'var(--brand)' } })}
                <span style={{ font: '600 13px var(--font-text)', color: 'var(--text-strong)' }}>Community Fund</span>
                {(reportOverdue || reportDueSoon) && <Badge tone={reportOverdue ? 'warning' : 'watch'}>{reportOverdue ? 'Report overdue' : 'Due in ' + daysUntilDue + 'd'}</Badge>}
              </div>
              <div style={{ font: '12px/1.5 var(--font-text)', color: 'var(--text-muted)' }}>
                Balance {fmtMMK(fund.balanceMMK)} · last reported {fmtDate(fund.lastReportedDate)} — tap to manage.
              </div>
            </Card>
          </div>

          {/* Recommended actions checklist */}
          <Card padding="lg" elevation="sm">
            <SectionHeading eyebrow="ဆောင်ရွက်ရန်" title="Recommended actions"
              hint="From the latest synthesis — tick items off as your committee handles them." />
            {synthesis.recommendedActions.map(function (a) {
              const done = !!villageDone[a];
              return (
                <label key={a} className="ap-row" style={{ display: 'flex', alignItems: 'flex-start', gap: 10, padding: '10px 6px', borderTop: '1px solid var(--border-subtle)', cursor: 'pointer' }}>
                  <input type="checkbox" checked={done} onChange={function () { toggleAction(a); }} style={{ marginTop: 3, accentColor: 'var(--brand)' }} />
                  <span style={{ font: '13px/1.5 var(--font-text)', color: done ? 'var(--text-subtle)' : 'var(--text-body)', textDecoration: done ? 'line-through' : 'none' }}>{a}</span>
                </label>
              );
            })}
            <div style={{ font: '11px var(--font-text)', color: 'var(--text-subtle)', marginTop: 8 }}>
              Checklist is local to this device — it resets when the synthesis is refreshed.
            </div>
          </Card>
        </div>
      )}

      {/* ================= SIGNALS & DATA ================= */}
      {pageTab === 'signals' && (
        <div className="ap-rise">
          <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, flexWrap: 'wrap', marginBottom: 'var(--space-5)' }}>
            <div style={{ font: '13px/1.6 var(--font-text)', color: 'var(--text-muted)', maxWidth: 520 }}>
              The data behind each signal for <strong style={{ color: 'var(--text-strong)' }}>{village.name}</strong> — hover any chart for week-by-week values. All sample data is illustrative.
            </div>
            <FilterChips size="sm" active={signalsFocus} onChange={setSignalsFocus} items={[
              { id: 'all', label: 'All domains' },
              { id: 'climate', label: 'Climate', count: signals.climate.score, color: DOMAIN_COLOR.climate },
              { id: 'economic', label: 'Economic', count: signals.economic.score, color: DOMAIN_COLOR.economic },
              { id: 'conflict', label: 'Conflict', count: signals.conflict.score, color: DOMAIN_COLOR.conflict },
            ]} />
          </div>

          {/* Composite context strip */}
          <Card padding="md" elevation="sm" style={{ marginBottom: 'var(--space-5)' }}>
            <div style={{ display: 'flex', gap: 'var(--space-7)', flexWrap: 'wrap', alignItems: 'center' }}>
              <Stat label="Composite risk" value={synthesis.composite} unit="/100" tone={synthesis.level === 'calm' ? 'neutral' : synthesis.level} />
              <Sparkline points={trends.composite} color={LEVEL_COLOR[synthesis.level]} width={140} height={36} />
              <Stat label="Leading domain" value={DOMAIN_LABEL[synthesis.topDomain]} />
              <Stat label="Lead time" value={synthesis.leadTime} tone="brand" />
              <Stat label="Confidence" value={synthesis.confidence} />
            </div>
          </Card>

          {visibleDomains.map(function (d) {
            return <DomainDetail key={villageId + d} domain={d} signal={signals[d]} trend={trends[d]}
              indicators={indicators[d]} labels={indicators.labels} />;
          })}

          <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
            <Button variant="secondary" size="sm" iconRight={Ic('arrow-right', { width: 13, height: 13 })} onClick={function () { setPageTab('support'); }}>
              Concerned by what you see? View support options
            </Button>
          </div>
        </div>
      )}

      {/* ================= GET SUPPORT ================= */}
      {pageTab === 'support' && (
        <div className="ap-rise">
          <Card padding="lg" elevation="sm" style={{ marginBottom: 'var(--space-5)' }}>
            <SectionHeading eyebrow="ရရှိနိုင်သော အကူအညီ" title="Available support"
              hint={'Protocols published by humanitarian partners that match ' + village.name + '’s current ' + LEVEL_LABEL[synthesis.level] + ' level.'} />
            {matchingProtocols.length === 0 && (
              <EmptyState icon="file-x" text="No published protocol currently matches your risk level. You can still send a general distress signal — the Risk Desk will try to match one."
                action={<Button variant="primary" size="sm" onClick={function () { setCallModal({ general: true }); }}>Send a general distress signal</Button>} />
            )}
            {matchingProtocols.map(function (p) {
              return (
                <div key={p.id} style={{ display: 'flex', gap: 12, alignItems: 'flex-start', padding: '14px 0', borderTop: '1px solid var(--border-subtle)', flexWrap: 'wrap' }}>
                  <div style={{ flex: 1, minWidth: 220 }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
                      <span style={{ font: '600 14px var(--font-text)', color: 'var(--text-strong)' }}>{p.name}</span>
                      <span style={{ font: '600 13px var(--font-mono)', color: 'var(--brand)' }}>{fmtUSD(p.amount)}</span>
                      {p.unrestricted && <Badge tone="brand" variant="soft">Fast-track: auto-triggers after review window</Badge>}
                    </div>
                    <div style={{ font: '12px/1.5 var(--font-text)', color: 'var(--text-muted)', marginTop: 3 }}>{p.purpose}</div>
                    <div style={{ font: '11px var(--font-mono)', color: 'var(--text-subtle)', marginTop: 4 }}>Domain {DOMAIN_LABEL[p.domain]} · min level {LEVEL_LABEL[p.minLevel]}</div>
                  </div>
                  <Button variant="primary" size="sm" onClick={function () { setCallModal({ protocolId: p.id }); }}>Apply</Button>
                </div>
              );
            })}
            {matchingProtocols.length > 0 && (
              <div style={{ marginTop: 'var(--space-4)', display: 'flex', alignItems: 'center', gap: 10, flexWrap: 'wrap' }}>
                <Button variant="secondary" size="sm" onClick={function () { setCallModal({ general: true }); }}>Send a general distress signal instead</Button>
                <span style={{ font: '12px var(--font-text)', color: 'var(--text-subtle)' }}>For needs that don't fit a protocol above.</span>
              </div>
            )}
          </Card>

          <Card padding="lg" elevation="sm">
            <SectionHeading eyebrow="သင့်တောင်းဆိုမှုများ" title="Your calls for help"
              hint={openCalls.length > 0 ? 'Requests update below as they move through review.' : null} />
            {myCalls.length === 0 && <EmptyState icon="megaphone" text="No calls for help submitted yet for this village." />}
            {myCalls.map(function (c) {
              const p = c.protocolId ? window.AsterStore.findProtocol(c.protocolId) : null;
              return (
                <div key={c.id} style={{ padding: '14px 0', borderTop: '1px solid var(--border-subtle)' }}>
                  <div style={{ display: 'flex', justifyContent: 'space-between', gap: 10, flexWrap: 'wrap', alignItems: 'center' }}>
                    <div style={{ font: '600 14px var(--font-text)', color: 'var(--text-strong)' }}>
                      {p ? p.name : 'General distress signal'}
                      {p && <span style={{ font: '12px var(--font-mono)', color: 'var(--text-subtle)', marginLeft: 8 }}>{fmtUSD(p.amount)}</span>}
                    </div>
                    <Badge tone={CALL_STATUS_TONE[c.status]}>{CALL_STATUS_LABEL[c.status]}</Badge>
                  </div>
                  {c.message && <div style={{ font: '13px var(--font-text)', color: 'var(--text-body)', marginTop: 6 }}>{c.message}</div>}
                  <CallStepper call={c} />
                  {c.orgNote && (
                    <div style={{ marginTop: 10, padding: '8px 12px', borderRadius: 'var(--radius-card)', background: 'var(--surface-sunken)', font: '13px/1.5 var(--font-text)', color: 'var(--text-muted)', display: 'flex', gap: 8 }}>
                      {Ic('message-square', { width: 14, height: 14, style: { flexShrink: 0, marginTop: 2 } })}
                      <span><strong style={{ color: 'var(--text-body)' }}>Note from Aster Risk Desk / org:</strong> {c.orgNote}</span>
                    </div>
                  )}
                </div>
              );
            })}
          </Card>
        </div>
      )}

      {/* ================= COMMUNITY FUND ================= */}
      {pageTab === 'fund' && (
        <div className="ap-rise">
          <Card padding="lg" elevation="sm">
            <SectionHeading eyebrow="ရွေ့ကြေးရံပုံငွေ" title="Community Fund"
              right={<Button variant={reportOverdue ? 'primary' : 'secondary'} size="sm" iconLeft={Ic('receipt', { width: 14, height: 14 })} onClick={function () { setUsageModal(true); }}>Report fund usage</Button>} />

            {(reportOverdue || reportDueSoon) && (
              <div style={{ marginBottom: 'var(--space-4)' }}>
                <AlertBanner level={reportOverdue ? 'warning' : 'watch'}
                  title={reportOverdue ? 'Fund report overdue' : 'Fund report due soon'}
                  icon={Ic('calendar-clock', { width: 16, height: 16 })}>
                  {reportOverdue
                    ? 'The last report was ' + daysSinceReport + ' days ago — your ' + fund.cadenceDays + '-day cadence has passed. Report current usage so partners see an up-to-date balance.'
                    : 'Next report is due in ' + daysUntilDue + ' day' + (daysUntilDue === 1 ? '' : 's') + ' (every ' + fund.cadenceDays + ' days).'}
                </AlertBanner>
              </div>
            )}

            <div style={{ display: 'flex', gap: 'var(--space-7)', flexWrap: 'wrap', marginBottom: 'var(--space-4)' }}>
              <Stat label="Current balance" value={fmtMMK(fund.balanceMMK).replace(' MMK', '')} unit="MMK" tone="brand" />
              <Stat label="Last reported" value={fmtDate(fund.lastReportedDate)} />
              <Stat label="Next report" value={reportOverdue ? 'overdue' : 'in ' + daysUntilDue + 'd'} tone={reportOverdue ? 'warning' : 'neutral'} />
              <Stat label="Managed by" value={village.fundManager} />
            </div>
            <div style={{ font: '12px var(--font-text)', color: 'var(--text-subtle)' }}>
              Balance reflects the last governance-meeting report, not a live bank feed — cadence is configurable per village.
            </div>

            <div style={{ marginTop: 'var(--space-6)' }}>
              <div style={{ font: '600 12px var(--font-text)', color: 'var(--text-muted)', marginBottom: 6 }}>Usage history</div>
              {fund.usageHistory.length === 0 && <EmptyState icon="receipt" text="No usage reported yet. When a protocol triggers and funds are spent, report it here." />}
              {fund.usageHistory.map(function (u, i) {
                const p = u.protocolId ? window.AsterStore.findProtocol(u.protocolId) : null;
                return (
                  <div key={i} style={{ padding: '10px 0', borderTop: '1px solid var(--border-subtle)', display: 'flex', justifyContent: 'space-between', gap: 12, fontSize: 13 }}>
                    <div>
                      <div style={{ color: 'var(--text-body)' }}>{u.note}</div>
                      <div style={{ color: 'var(--text-subtle)', fontSize: 12 }}>{fmtDate(u.date)}{p ? ' · against ' + p.name : ''}</div>
                    </div>
                    <div style={{ whiteSpace: 'nowrap', color: 'var(--text-strong)', fontWeight: 600 }}>{fmtMMK(u.amountMMK)}</div>
                  </div>
                );
              })}
            </div>
          </Card>
        </div>
      )}

      <CallForHelpWizard open={!!callModal} seed={callModal} onClose={function () { setCallModal(null); }} villageId={villageId} matchingProtocols={matchingProtocols}
        onSubmitted={function () { setToast('Call for help submitted.'); }} />
      <UsageReportModal open={usageModal} onClose={function () { setUsageModal(false); }} villageId={villageId} fund={fund}
        onSubmit={function (opts) { window.AsterStore.reportFundUsage(villageId, opts); setUsageModal(false); setToast('Fund usage reported.'); }} />
      {toastNode}
    </div>
  );
}

/* ---------- Call-for-help wizard: choose → review → submitted ----------
   seed: { protocolId } preselects a protocol; { general: true } opens the distress-signal form. */
function CallForHelpWizard({ open, seed, onClose, villageId, matchingProtocols, onSubmitted }) {
  const [step, setStep] = React.useState('choose'); // choose | review | done
  const [tab, setTab] = React.useState('protocol');
  const [protocolId, setProtocolId] = React.useState('');
  const [message, setMessage] = React.useState('');

  React.useEffect(function () {
    if (open) {
      setStep('choose');
      const wantGeneral = seed && seed.general;
      setTab(wantGeneral || !matchingProtocols.length ? 'general' : 'protocol');
      setProtocolId(seed && seed.protocolId ? seed.protocolId : (matchingProtocols[0] ? matchingProtocols[0].id : ''));
      setMessage('');
    }
  }, [open, villageId]);

  const village = window.AsterStore.findVillage(villageId);
  const protocol = protocolId ? window.AsterStore.findProtocol(protocolId) : null;
  const canContinue = tab === 'protocol' ? !!protocolId : !!message.trim();

  function submit() {
    window.AsterStore.submitCallForHelp(villageId, tab === 'protocol' ? { protocolId: protocolId } : { message: message.trim() });
    setStep('done');
    onSubmitted && onSubmitted();
  }

  const stepDots = (
    <div style={{ display: 'flex', gap: 6, alignItems: 'center' }} aria-hidden="true">
      {['choose', 'review', 'done'].map(function (s, i) {
        const idx = ['choose', 'review', 'done'].indexOf(step);
        return <span key={s} style={{ width: i <= idx ? 18 : 7, height: 7, borderRadius: 4, background: i <= idx ? 'var(--brand)' : 'var(--border-default)', transition: 'width 200ms ease, background 200ms ease' }} />;
      })}
    </div>
  );

  return (
    <Modal open={open} onClose={onClose} width={540}
      title={step === 'done' ? 'Request submitted' : 'Submit a call for help'}
      subtitle={step === 'done' ? null : village.name + ' · ' + village.township + ', ' + village.region}
      footer={
        step === 'choose' ? (
          <React.Fragment>
            {stepDots}<span style={{ flex: 1 }} />
            <Button variant="secondary" onClick={onClose}>Cancel</Button>
            <Button variant="primary" disabled={!canContinue} iconRight={Ic('arrow-right', { width: 14, height: 14 })} onClick={function () { setStep('review'); }}>Review request</Button>
          </React.Fragment>
        ) : step === 'review' ? (
          <React.Fragment>
            {stepDots}<span style={{ flex: 1 }} />
            <Button variant="secondary" onClick={function () { setStep('choose'); }}>Back</Button>
            <Button variant="primary" iconLeft={Ic('send', { width: 14, height: 14 })} onClick={submit}>Confirm &amp; submit</Button>
          </React.Fragment>
        ) : (
          <Button variant="primary" onClick={onClose}>Done</Button>
        )
      }>

      {step === 'choose' && (
        <div>
          <div style={{ display: 'flex', gap: 8, marginBottom: 'var(--space-5)' }}>
            <Button variant={tab === 'protocol' ? 'primary' : 'secondary'} size="sm" onClick={function () { setTab('protocol'); }}>Apply to a published protocol</Button>
            <Button variant={tab === 'general' ? 'primary' : 'secondary'} size="sm" onClick={function () { setTab('general'); }}>Send a general distress signal</Button>
          </div>

          {tab === 'protocol' && (
            matchingProtocols.length === 0 ? (
              <EmptyState icon="file-x" text="No published protocol currently matches this village's risk level. Try a general distress signal instead."
                action={<Button variant="secondary" size="sm" onClick={function () { setTab('general'); }}>Switch to general signal</Button>} />
            ) : (
              <div role="radiogroup" aria-label="Matching protocols">
                <div style={{ font: '12px var(--font-text)', color: 'var(--text-subtle)', marginBottom: 10 }}>
                  {matchingProtocols.length} protocol{matchingProtocols.length > 1 ? 's' : ''} match{matchingProtocols.length === 1 ? 'es' : ''} your current risk level. Choose the one that fits your need.
                </div>
                {matchingProtocols.map(function (p) {
                  const selected = protocolId === p.id;
                  return (
                    <label key={p.id} className="ap-chip" style={{ display: 'flex', gap: 10, alignItems: 'flex-start', padding: '12px 14px', border: '1px solid ' + (selected ? 'var(--border-brand)' : 'var(--border-subtle)'), borderRadius: 'var(--radius-card)', marginBottom: 8, cursor: 'pointer', background: selected ? 'var(--surface-brand-soft)' : 'transparent' }}>
                      <input type="radio" name="protocol" checked={selected} onChange={function () { setProtocolId(p.id); }} style={{ marginTop: 4 }} />
                      <div style={{ flex: 1 }}>
                        <div style={{ display: 'flex', justifyContent: 'space-between', gap: 8, flexWrap: 'wrap' }}>
                          <span style={{ font: '600 13px var(--font-text)', color: 'var(--text-strong)' }}>{p.name}</span>
                          <span style={{ font: '600 13px var(--font-mono)', color: 'var(--brand)' }}>{fmtUSD(p.amount)}</span>
                        </div>
                        <div style={{ font: '12px/1.5 var(--font-text)', color: 'var(--text-muted)', marginTop: 3 }}>{p.purpose}</div>
                        {p.unrestricted && <Badge tone="brand" variant="soft" style={{ marginTop: 6 }}>Unrestricted — can auto-trigger after a short review window</Badge>}
                      </div>
                    </label>
                  );
                })}
              </div>
            )
          )}

          {tab === 'general' && (
            <Textarea label="Describe your situation" rows={4} value={message} maxLength={500}
              onChange={function (e) { setMessage(e.target.value); }}
              placeholder="e.g. Water access has become unreliable for part of the village…"
              hint="The Aster Risk Desk reads every general signal and tries to match it to a protocol." />
          )}
        </div>
      )}

      {step === 'review' && (
        <div className="ap-rise">
          <div style={{ font: '12px var(--font-text)', color: 'var(--text-subtle)', marginBottom: 12 }}>Please confirm before submitting on behalf of {village.governanceBody}.</div>
          <div style={{ border: '1px solid var(--border-subtle)', borderRadius: 'var(--radius-card)', padding: '14px 16px', marginBottom: 14 }}>
            {tab === 'protocol' && protocol ? (
              <React.Fragment>
                <div style={{ display: 'flex', justifyContent: 'space-between', gap: 8, flexWrap: 'wrap' }}>
                  <span style={{ font: '600 14px var(--font-text)', color: 'var(--text-strong)' }}>{protocol.name}</span>
                  <span style={{ font: '600 14px var(--font-mono)', color: 'var(--brand)' }}>{fmtUSD(protocol.amount)}</span>
                </div>
                <div style={{ font: '12px/1.5 var(--font-text)', color: 'var(--text-muted)', marginTop: 4 }}>{protocol.purpose}</div>
              </React.Fragment>
            ) : (
              <React.Fragment>
                <div style={{ font: '600 13px var(--font-text)', color: 'var(--text-strong)', marginBottom: 4 }}>General distress signal</div>
                <div style={{ font: '13px/1.5 var(--font-text)', color: 'var(--text-body)' }}>{message}</div>
              </React.Fragment>
            )}
          </div>
          <div style={{ font: '600 12px var(--font-text)', color: 'var(--text-muted)', marginBottom: 6 }}>What happens after you submit</div>
          <ol style={{ margin: 0, paddingLeft: 18, font: '13px/1.7 var(--font-text)', color: 'var(--text-body)' }}>
            <li>The Aster Risk Desk reviews your request against current signals.</li>
            {tab === 'protocol' && protocol && protocol.unrestricted
              ? <li>Because this protocol is unrestricted, it can auto-trigger after a short org review window.</li>
              : <li>The humanitarian organization decides whether to trigger the protocol.</li>}
            <li>If triggered, funds move to your Community Fund and appear under the Community Fund tab.</li>
          </ol>
        </div>
      )}

      {step === 'done' && (
        <div style={{ textAlign: 'center', padding: 'var(--space-4) 0' }}>
          <div className="ap-pop" style={{ display: 'inline-flex', width: 56, height: 56, borderRadius: '50%', background: 'var(--calm-soft)', alignItems: 'center', justifyContent: 'center', marginBottom: 12 }}>
            {Ic('check', { width: 26, height: 26, style: { color: 'var(--calm-strong)', strokeWidth: 3 } })}
          </div>
          <div style={{ font: '600 16px var(--font-display)', color: 'var(--text-strong)', marginBottom: 6 }}>တောင်းဆိုမှု ပေးပို့ပြီးပါပြီ · Your request is on its way</div>
          <div style={{ font: '13px/1.6 var(--font-text)', color: 'var(--text-muted)', maxWidth: 380, margin: '0 auto' }}>
            Track its progress under “Your calls for help” in the Get support tab. You'll see each step — risk desk review, org decision, and funds moving — as it happens.
          </div>
        </div>
      )}
    </Modal>
  );
}

/* ---------- Fund usage report with validation ---------- */
function UsageReportModal({ open, onClose, villageId, fund, onSubmit }) {
  const [protocolId, setProtocolId] = React.useState('');
  const [amount, setAmount] = React.useState('');
  const [note, setNote] = React.useState('');
  const triggeredCalls = window.AsterStore.callsForVillage(villageId).filter(function (c) { return c.status === 'triggered' && c.protocolId; });

  React.useEffect(function () {
    if (open) { setProtocolId(triggeredCalls[0] ? triggeredCalls[0].protocolId : ''); setAmount(''); setNote(''); }
  }, [open, villageId]);

  const protocolOptions = triggeredCalls.map(function (c) {
    const p = window.AsterStore.findProtocol(c.protocolId);
    return { value: p.id, label: p.name };
  });

  const amountNum = Number(amount);
  const amountInvalid = amount !== '' && (!isFinite(amountNum) || amountNum <= 0);
  const overBalance = isFinite(amountNum) && amountNum > fund.balanceMMK;
  const valid = protocolId && amountNum > 0 && note.trim();

  return (
    <Modal open={open} onClose={onClose} title="Report fund usage" subtitle={'Current balance ' + fmtMMK(fund.balanceMMK)} width={480}
      footer={protocolOptions.length > 0 && (
        <React.Fragment>
          <Button variant="secondary" onClick={onClose}>Cancel</Button>
          <Button variant="primary" disabled={!valid} onClick={function () { onSubmit({ protocolId: protocolId, amountMMK: amountNum, note: note.trim() }); }}>Submit report</Button>
        </React.Fragment>
      )}>
      {protocolOptions.length === 0 ? (
        <EmptyState icon="wallet" text="No triggered protocol to report usage against yet for this village." />
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-4)' }}>
          <Select label="Against which protocol" options={protocolOptions} value={protocolId} onChange={function (e) { setProtocolId(e.target.value); }} />
          <div>
            <Input label="Amount spent (MMK)" type="number" value={amount} onChange={function (e) { setAmount(e.target.value); }} placeholder="e.g. 4500000" />
            {amountInvalid && <div style={{ font: '12px var(--font-text)', color: 'var(--severe-strong)', marginTop: 4 }}>Enter an amount greater than zero.</div>}
            {!amountInvalid && amountNum > 0 && (
              <div style={{ font: '12px var(--font-text)', color: overBalance ? 'var(--warning-strong)' : 'var(--text-subtle)', marginTop: 4 }}>
                {fmtMMK(amountNum)}{overBalance ? ' — this is more than the reported balance; double-check before submitting.' : ''}
              </div>
            )}
          </div>
          <Textarea label="How it was used (against the protocol's stated purpose)" rows={3} value={note} maxLength={300}
            onChange={function (e) { setNote(e.target.value); }} />
        </div>
      )}
    </Modal>
  );
}
