// Metric Entry — daily/weekly entry surface backed by live Firestore.
// Renders the shared EntryFormBody inline plus a "Recent saved entries"
// panel below so the user can verify what actually persisted.
//
// Replaced the prior conversational chat + mobile-preview demo, which
// rendered values to local React state only and never hit the database.

function Huddle({ persona }) {
  const isMobile = useMedia('(max-width: 760px)');
  return (
    <div style={{
      padding: isMobile ? '16px 16px 32px' : 28,
      display: 'grid',
      gridTemplateColumns: isMobile ? '1fr' : 'minmax(0, 560px) minmax(0, 1fr)',
      gap: isMobile ? 16 : 24,
      alignItems: 'start',
      width: '100%', maxWidth: '100%', minWidth: 0,
    }}>
      <div className="card" style={{ overflow: 'hidden', minWidth: 0 }}>
        <window.EntryFormBody mode="inline"/>
      </div>

      <RecentEntriesPanel persona={persona} isMobile={isMobile}/>
    </div>
  );
}

// ─── Recent entries — verification panel ────────────────────────────────
// Pulls the last 14 days of metricEntries for the current persona from
// Firestore and lists them. Refreshes whenever an entry is saved (the
// EntryFormBody dispatches a `norwill:entry-saved` event).
function RecentEntriesPanel({ persona, isMobile }) {
  const [auth, setAuth] = React.useState(null);
  const [rows, setRows] = React.useState(null);
  const [error, setError] = React.useState(null);
  // On mobile the recent-entries list collapses by default so the entry form
  // is the dominant surface and the keyboard can use the full screen.
  const [collapsed, setCollapsed] = React.useState(!!isMobile);
  React.useEffect(() => { setCollapsed(!!isMobile); }, [isMobile]);

  React.useEffect(() => {
    window.getCurrentAuthContext().then(setAuth);
  }, []);

  const personaId = persona?.id || auth?.personaId || null;

  const refresh = React.useCallback(() => {
    if (!auth) return;
    setError(null);
    window.loadRecentEntries({ personaId, days: 14, auth })
      .then(setRows)
      .catch(err => {
        console.error('[norwill] loadRecentEntries failed', err);
        setError(err.message || 'Failed to load recent entries.');
      });
  }, [auth, personaId]);

  React.useEffect(refresh, [refresh]);

  React.useEffect(() => {
    function onSaved() { refresh(); }
    window.addEventListener('norwill:entry-saved', onSaved);
    return () => window.removeEventListener('norwill:entry-saved', onSaved);
  }, [refresh]);

  const METRICS_BY_ID = React.useMemo(() => {
    const map = {};
    (window.NORWILL_DATA?.METRICS || []).forEach(m => { map[m.id] = m; });
    return map;
  }, []);

  const PEOPLE_BY_UID = React.useMemo(() => {
    const map = {};
    (window.NORWILL_DATA?.PEOPLE || []).forEach(p => { map[p.id] = p; });
    return map;
  }, []);

  return (
    <div className="card" style={{
      display: 'flex', flexDirection: 'column', overflow: 'hidden',
      maxHeight: isMobile ? undefined : 'calc(100vh - 110px)',
      minWidth: 0,
    }}>
      <button
        type="button"
        onClick={() => isMobile && setCollapsed(c => !c)}
        style={{
          padding: '14px 18px',
          borderBottom: collapsed && isMobile ? 'none' : '1px solid var(--hairline)',
          display: 'flex', alignItems: 'center', gap: 10,
          background: 'transparent', border: 'none', textAlign: 'left',
          cursor: isMobile ? 'pointer' : 'default',
          width: '100%',
        }}
        aria-expanded={!collapsed}
      >
        <div style={{ flex: 1, minWidth: 0 }}>
          <div className="eyebrow">Verify</div>
          <div style={{ fontSize: 14, fontWeight: 700, marginTop: 2, color: 'var(--ink-900)' }}>
            Recent saved entries
            <span style={{ fontSize: 11, fontWeight: 500, color: 'var(--ink-500)', marginLeft: 8 }}>
              · last 14 days{persona ? ` · ${persona.name.split(' ')[0]}` : ''}
            </span>
          </div>
        </div>
        {!isMobile && (
          <span
            onClick={(e) => { e.stopPropagation(); refresh(); }}
            role="button" tabIndex={0}
            title="Refresh"
            style={{
              background: 'var(--surface-card)', border: '1px solid var(--hairline)',
              color: 'var(--ink-700)', padding: '5px 11px', borderRadius: 7,
              fontSize: 12, fontWeight: 600, cursor: 'pointer', display: 'inline-flex', alignItems: 'center',
            }}>
            ↻ Refresh
          </span>
        )}
        {isMobile && (
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.4" strokeLinecap="round" strokeLinejoin="round" style={{ color: 'var(--ink-500)', transform: collapsed ? 'none' : 'rotate(180deg)', transition: 'transform 160ms var(--ease-out)' }}>
            <polyline points="6 9 12 15 18 9"/>
          </svg>
        )}
      </button>

      {(!collapsed || !isMobile) && (
      <div style={{ flex: 1, overflow: 'auto' }}>
        {!auth ? (
          <PanelEmpty text="Loading…"/>
        ) : error ? (
          <PanelEmpty text={'Couldn’t load entries: ' + error}/>
        ) : rows === null ? (
          <PanelEmpty text="Loading recent entries…"/>
        ) : rows.length === 0 ? (
          <PanelEmpty text={
            persona
              ? `No entries logged for ${persona.name} in the last 14 days.`
              : 'No entries logged in the last 14 days.'
          }/>
        ) : (
          <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12.5 }}>
            <thead>
              <tr style={{ background: 'var(--card-alt)', borderBottom: '1px solid var(--line)' }}>
                <Th>Date</Th>
                <Th>Metric</Th>
                <Th align="right">Value</Th>
                <Th>Entered by</Th>
              </tr>
            </thead>
            <tbody>
              {rows.map((r, i) => {
                const metric = METRICS_BY_ID[r.metricId];
                const owner  = PEOPLE_BY_UID[r.ownerId];
                const submittedDifferent = r.submittedBy && owner && !r.submittedBy.endsWith(':' + owner.id) && r.submittedBy !== owner.id;
                return (
                  <tr key={i} style={{ borderBottom: '1px solid var(--line)' }}>
                    <Td mono>{r.date}</Td>
                    <Td>
                      <div style={{ fontWeight: 600 }}>{metric ? metric.label : r.metricId}</div>
                      <div style={{ fontSize: 11, color: 'var(--ink-500)' }}>
                        {owner ? owner.name : (r.ownerId || '—')}
                        {r.period === 'week' ? ' · weekly' : r.period === 'month' ? ' · monthly' : ' · daily'}
                      </div>
                    </Td>
                    <Td align="right" mono>
                      <strong>{r.value != null ? Number(r.value).toLocaleString() : '—'}</strong>
                    </Td>
                    <Td>
                      <div style={{ fontSize: 12 }}>
                        {labelForSubmitter(r.submittedBy, PEOPLE_BY_UID)}
                      </div>
                      {submittedDifferent && (
                        <div style={{ fontSize: 10.5, color: '#92400e', fontWeight: 600 }}>
                          covering for {owner?.name?.split(' ')[0]}
                        </div>
                      )}
                    </Td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        )}
      </div>
      )}
    </div>
  );
}

function PanelEmpty({ text }) {
  return (
    <div style={{ padding: 28, color: 'var(--ink-500)', fontSize: 13, lineHeight: 1.5 }}>
      {text}
    </div>
  );
}

function Th({ children, align = 'left' }) {
  return <th style={{
    textAlign: align, fontSize: 10.5, letterSpacing: 0.06,
    textTransform: 'uppercase', color: 'var(--ink-500)', fontWeight: 600,
    padding: '10px 14px',
  }}>{children}</th>;
}

function Td({ children, align = 'left', mono }) {
  return <td className={mono ? 'mono tnum' : undefined} style={{
    textAlign: align, padding: '10px 14px',
    color: 'var(--ink-800)', verticalAlign: 'top',
  }}>{children}</td>;
}

// Best-effort: submittedBy is a uid (`local:dave` in dev, a Firebase uid
// in prod). We can't always map it back to a person name without a
// users-collection roster, so fall back to a short hash.
function labelForSubmitter(submittedBy, peopleById) {
  if (!submittedBy) return '—';
  if (submittedBy.startsWith('local:')) {
    const uname = submittedBy.slice(6);
    return uname.charAt(0).toUpperCase() + uname.slice(1);
  }
  // Heuristic: try to match by personaId in case the saver is a known persona.
  const direct = peopleById[submittedBy];
  if (direct) return direct.name;
  return submittedBy.slice(0, 6) + '…';
}
