// Analyses list — filterable + sortable.
//
// Pulls a wide list (limit 200) from the API once, then does ALL filtering and
// sorting CLIENT-SIDE for instant feedback. The TopBar exposes a free-text
// search (matches ticker OR company name), decision chips (BUY / PASS), and
// status chips (Completed / Failed / Running / Queued). Below the TopBar a
// thin sort bar exposes Date asc/desc + Upside asc/desc.
//
// "Run Analysis" CTA is gated by EQ_IS_AUTHORIZED — non-authorized users get
// a greyed-out button with a tooltip and the trigger modal flow is blocked.

window.Analyses = function Analyses({ goto, session, isElevated }) {
  const { useState, useMemo } = React;

  // ── Filter / sort state ─────────────────────────────────────────────
  const [search,    setSearch]    = useState('');
  // Multi-select chip state: each map of value -> bool
  const [decisions, setDecisions] = useState({ BUY: true, PASS: true });
  const [statuses,  setStatuses]  = useState({ completed: true, failed: false, running: false, queued: false });
  // Sort: 'date_desc' | 'date_asc' | 'upside_desc' | 'upside_asc'
  const [sortKey,   setSortKey]   = useState('date_desc');

  // ── Authorization (DB-sourced via /api/auth/me, fallback to client check) ──
  const canTrigger = isElevated === true
    ? true
    : (window.EQ_IS_AUTHORIZED ? window.EQ_IS_AUTHORIZED(session) : false);
  const triggerTooltip = 'Restricted — contact your administrator to run analyses.';

  // ── Trigger modal state ────────────────────────────────────────────
  const [triggerOpen, setTriggerOpen] = useState(false);
  const [triggerBusy, setTriggerBusy] = useState(false);
  const [triggerMsg,  setTriggerMsg]  = useState(null);

  // ── Fetch (no params; client-side filter) ──────────────────────────
  const list = window.useApi(() => window.EQ_API.getAnalyses({ limit: 200 }), []);
  const allRows = list.data?.data || [];

  // ── Apply filters + sort ───────────────────────────────────────────
  const rows = useMemo(() => {
    let out = allRows;
    // Search: matches ticker OR company name (case-insensitive)
    const q = search.trim().toLowerCase();
    if (q) {
      out = out.filter(r =>
        (r.ticker || '').toLowerCase().includes(q) ||
        (r.company_name || '').toLowerCase().includes(q)
      );
    }
    // Decision chips: when none selected, show nothing (empty state)
    const dActive = Object.entries(decisions).filter(([, v]) => v).map(([k]) => k);
    if (dActive.length === 0) {
      out = [];
    } else {
      // Rows with decision = null/undefined (still queued/running) pass through
      // when ANY decision is selected — they don't have a decision yet, so we
      // show them gated by the status filter below.
      out = out.filter(r => !r.decision || dActive.includes(r.decision));
    }
    // Status chips: filter by status (must match at least one selected)
    const sActive = Object.entries(statuses).filter(([, v]) => v).map(([k]) => k);
    if (sActive.length === 0) {
      out = [];
    } else {
      out = out.filter(r => sActive.includes(r.status));
    }
    // Sort
    const sorted = [...out];
    sorted.sort((a, b) => {
      switch (sortKey) {
        case 'date_asc':   return new Date(a.created_at) - new Date(b.created_at);
        case 'upside_desc':return (b.upside_pct ?? -Infinity) - (a.upside_pct ?? -Infinity);
        case 'upside_asc': return (a.upside_pct ??  Infinity) - (b.upside_pct ??  Infinity);
        case 'date_desc':
        default:           return new Date(b.created_at) - new Date(a.created_at);
      }
    });
    return sorted;
  }, [allRows, search, decisions, statuses, sortKey]);

  // ── Trigger handler ────────────────────────────────────────────────
  const triggerAnalysis = async (ticker) => {
    const t = (ticker || '').trim().toUpperCase();
    if (!t) return;
    setTriggerBusy(true); setTriggerMsg(null);
    try {
      const res = await window.EQ_API.triggerAnalysis(t);
      setTriggerMsg({ ok: true, text: `Analysis queued for ${t} — ID ${res.id}` });
      setTriggerOpen(false);
      list.reload();
    } catch (e) {
      setTriggerMsg({ ok: false, text: e.message || 'Trigger failed' });
      throw e;
    } finally {
      setTriggerBusy(false);
    }
  };

  // ── Chip toggler ───────────────────────────────────────────────────
  const Chip = ({ active, label, color, onClick }) => (
    <button
      onClick={onClick}
      style={{
        padding: '5px 11px', fontSize: 12, fontWeight: active ? 600 : 500,
        background: active ? (color || 'var(--ink-900)') : 'var(--ink-100)',
        color: active ? 'white' : 'var(--ink-700)',
        border: '1px solid ' + (active ? (color || 'var(--ink-900)') : 'var(--ink-200)'),
        borderRadius: 6, cursor: 'pointer', fontFamily: 'inherit',
        letterSpacing: '0.02em',
      }}
    >{label}</button>
  );

  return (
    <div>
      <window.TopBar
        title="Analyses"
        subtitle={list.loading ? 'Loading…' : `${rows.length} of ${allRows.length} shown`}
        right={
          <button
            onClick={() => { if (canTrigger) setTriggerOpen(true); }}
            disabled={!canTrigger}
            title={!canTrigger ? triggerTooltip : 'Run a new equity analysis'}
            style={{
              padding: '8px 18px', fontSize: 12.5, fontWeight: 500,
              background: !canTrigger ? 'var(--ink-300)' : 'var(--ink-900)',
              color: 'white', borderRadius: 7, border: 'none',
              cursor: !canTrigger ? 'not-allowed' : 'pointer',
              opacity: !canTrigger ? 0.55 : 1,
              fontFamily: 'inherit',
              display: 'inline-flex', alignItems: 'center', gap: 7,
            }}
          >
            {!canTrigger ? (
              <svg width="13" height="13" viewBox="0 0 24 24" fill="none" style={{ color: '#ffb4b4' }}>
                <path d="M5 11h14a1 1 0 011 1v8a1 1 0 01-1 1H5a1 1 0 01-1-1v-8a1 1 0 011-1zm2 0V7a5 5 0 0110 0v4"
                      stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
              </svg>
            ) : (
              <svg width="13" height="13" viewBox="0 0 24 24" fill="none">
                <path d="M12 5v14M5 12h14" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
              </svg>
            )}
            Run Analysis
          </button>
        }
      />

      {/* ── Filter / sort bar ── */}
      <div style={{
        padding: '14px 32px',
        background: 'var(--paper)',
        borderBottom: '1px solid var(--ink-150)',
        display: 'flex', flexWrap: 'wrap', gap: 14, alignItems: 'center',
      }}>
        {/* Search */}
        <div style={{ position: 'relative', flex: '0 0 280px' }}>
          <svg width="13" height="13" viewBox="0 0 24 24" fill="none" style={{
            position: 'absolute', left: 11, top: '50%', transform: 'translateY(-50%)',
            color: 'var(--ink-400)', pointerEvents: 'none',
          }}>
            <path d="M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM21 21l-4.35-4.35" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
          </svg>
          <input
            value={search}
            onChange={e => setSearch(e.target.value)}
            placeholder="Search ticker or company…"
            style={{
              width: '100%', padding: '7px 10px 7px 32px', fontSize: 12.5,
              background: 'var(--ink-50)', border: '1px solid var(--ink-200)',
              borderRadius: 7, outline: 'none', color: 'var(--ink-900)',
              fontFamily: 'inherit', boxSizing: 'border-box',
            }}
          />
        </div>

        {/* Decision chips */}
        <div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
          <span style={{ fontSize: 10.5, fontWeight: 600, color: 'var(--ink-500)', textTransform: 'uppercase', letterSpacing: '0.06em', marginRight: 4 }}>Decision</span>
          <Chip active={decisions.BUY}  label="BUY"  color="var(--buy)"  onClick={() => setDecisions(d => ({ ...d, BUY:  !d.BUY }))}/>
          <Chip active={decisions.PASS} label="PASS" color="var(--pass)" onClick={() => setDecisions(d => ({ ...d, PASS: !d.PASS }))}/>
        </div>

        {/* Status chips */}
        <div style={{ display: 'flex', gap: 6, alignItems: 'center' }}>
          <span style={{ fontSize: 10.5, fontWeight: 600, color: 'var(--ink-500)', textTransform: 'uppercase', letterSpacing: '0.06em', marginRight: 4 }}>Status</span>
          <Chip active={statuses.completed} label="Completed" onClick={() => setStatuses(s => ({ ...s, completed: !s.completed }))}/>
          <Chip active={statuses.failed}    label="Failed"    onClick={() => setStatuses(s => ({ ...s, failed:    !s.failed    }))}/>
          <Chip active={statuses.running}   label="Running"   onClick={() => setStatuses(s => ({ ...s, running:   !s.running   }))}/>
          <Chip active={statuses.queued}    label="Queued"    onClick={() => setStatuses(s => ({ ...s, queued:    !s.queued    }))}/>
        </div>

        {/* Sort */}
        <div style={{ display: 'flex', gap: 6, alignItems: 'center', marginLeft: 'auto' }}>
          <span style={{ fontSize: 10.5, fontWeight: 600, color: 'var(--ink-500)', textTransform: 'uppercase', letterSpacing: '0.06em', marginRight: 4 }}>Sort</span>
          <select
            value={sortKey}
            onChange={e => setSortKey(e.target.value)}
            style={{
              padding: '6px 10px', fontSize: 12,
              background: 'var(--ink-50)', border: '1px solid var(--ink-200)',
              borderRadius: 6, outline: 'none', color: 'var(--ink-900)', fontFamily: 'inherit',
              cursor: 'pointer',
            }}
          >
            <option value="date_desc">Date (newest first)</option>
            <option value="date_asc">Date (oldest first)</option>
            <option value="upside_desc">Upside (high to low)</option>
            <option value="upside_asc">Upside (low to high)</option>
          </select>
        </div>
      </div>

      <div style={{ padding: '20px 32px', display: 'flex', flexDirection: 'column', gap: 12 }}>
        {triggerMsg && (
          <div style={{
            padding: '10px 16px', borderRadius: 8, fontSize: 12.5, fontWeight: 500,
            background: triggerMsg.ok ? 'var(--buy-soft)' : 'var(--pass-soft)',
            color: triggerMsg.ok ? 'var(--buy)' : 'var(--pass)',
            border: '1px solid ' + (triggerMsg.ok ? 'var(--buy-soft)' : 'var(--pass-soft)'),
          }}>
            {triggerMsg.ok ? '✓ ' : '✗ '}{triggerMsg.text}
          </div>
        )}
        <window.AnalysesTable
          rows={rows}
          loading={list.loading}
          error={list.error}
          onRetry={list.reload}
          onRowClick={(row) => goto('analysis', { analysisId: row.id })}
          onRerun={canTrigger ? (row) => triggerAnalysis(row.ticker) : undefined}
        />
      </div>

      {triggerOpen && (
        <window.RunAnalysisModal
          recentTickers={Array.from(new Set(allRows.map(r => r.ticker))).slice(0, 6)}
          onClose={() => { setTriggerOpen(false); setTriggerMsg(null); }}
          onSubmit={triggerAnalysis}
          busy={triggerBusy}
          error={triggerMsg && !triggerMsg.ok ? triggerMsg.text : null}
        />
      )}
    </div>
  );
};
