/* "Calm" Airtm-native dashboard.
 * Hero · pipeline funnel · filterable KPI grid (by req + time period) · open reqs · AI shortlist · updates feed. */

function DashV1({ onNav }) {
  const { role } = React.useContext(RoleContext);
  const [searchOpen, setSearchOpen] = React.useState(false);
  const [settingsOpen, setSettingsOpen] = React.useState(false);
  const [candidate, setCandidate] = React.useState(null);

  /* filters */
  const [reqFilter, setReqFilter]   = React.useState('all');
  const [period, setPeriod]         = React.useState('month');
  const [updateFilter, setUpdateFilter] = React.useState('all');
  const [showAllReqs, setShowAllReqs]   = React.useState(false);
  const periodObj = TIME_PERIODS.find(p => p.id === period);

  React.useEffect(() => {
    const fn = (e) => {
      if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') { e.preventDefault(); setSearchOpen(true); }
      if (e.key === 'Escape') { setSearchOpen(false); setSettingsOpen(false); setCandidate(null); }
    };
    window.addEventListener('keydown', fn);
    return () => window.removeEventListener('keydown', fn);
  }, []);

  /* hero copy is role-driven */
  const hero = {
    exec: {
      eyebrow: `Hiring at a glance · ${periodObj.short}`,
      headline: 'On track on 4 of 6 reqs.',
      sub: 'Two reqs at risk of missing the 30-day target. AI flagged 3 strong candidates that need a decision today.',
    },
    manager: {
      eyebrow: `Your team · ${periodObj.short}`,
      headline: '3 candidates need your review.',
      sub: 'Senior Backend & Product Designer are still open. AI ranked 12 new applicants since yesterday.',
    },
    recruiter: {
      eyebrow: `Pipeline · ${periodObj.short}`,
      headline: '84 candidates in screening.',
      sub: '12 new applicants overnight. 4 interviews scheduled today, 2 offers waiting on signature.',
    },
  }[role];

  /* requisitions scoped to filter + role */
  const baseReqs = role === 'manager' ? REQS.filter(r => r.owner === 'Carla R.') : REQS;
  const filteredReqs = baseReqs.filter(r => reqFilter === 'all' || r.id === reqFilter);
  const visibleReqs = showAllReqs ? baseReqs : filteredReqs;

  const topCandidates = (() => {
    let pool = CANDIDATES;
    if (reqFilter !== 'all') {
      const role = reqById(reqFilter)?.role;
      pool = pool.filter(c => c.role === role);
    }
    return [...pool].sort((a,b) => b.score - a.score).slice(0, 4);
  })();

  /* KPIs — prefer live values from /api/dashboard (window.KPIS); fall back to
     metricSeries() pseudo-data only when no live data is available. */
  const live = window.KPIS || null;
  const kpiDefs = [
    { id: 'ttf',     label: 'Time to fill',       unit: 'd', fmt: (v) => `${Math.round(v)}d`, lowerBetter: true  },
    { id: 'offer',   label: 'Offer acceptance',   unit: '%', fmt: (v) => `${Math.round(v)}%`, lowerBetter: false },
    { id: 'screen',  label: 'Screening approval', unit: '%', fmt: (v) => `${Math.round(v)}%`, lowerBetter: false },
    { id: 'reqs',    label: 'Open jobs',          unit: '',  fmt: (v) => `${Math.round(v)}`,  lowerBetter: false },
    { id: 'applied', label: 'In applied stage',   unit: '',  fmt: (v) => `${Math.round(v)}`,  lowerBetter: false },
  ];
  const kpis = kpiDefs.map(k => {
    if (live && live[k.id]) {
      const lk = live[k.id];
      const current = Number(lk.current) || 0;
      const target  = Number(lk.target)  || 0;
      const onTrack = k.lowerBetter ? current <= target : current >= target;
      const tone    = k.id === 'reqs' || k.id === 'applied' ? 'neutral' : onTrack ? 'prog' : 'warn';
      return { ...k, current, target, lowerBetter: k.lowerBetter, tone,
               displayValue: k.fmt(current), targetDisplay: k.fmt(target),
               // Real-data KPIs don't have trend history yet — flat placeholder.
               values:   Array(8).fill(current),
               trendPct: 0,
               binLabel: 'wk',
               bins:     8 };
    }
    const s = metricSeries(k.id, period, reqFilter);
    const onTrack = s.lowerBetter ? s.current <= s.target : s.current >= s.target;
    const tone = k.id === 'reqs' ? 'neutral' : onTrack ? 'prog' : 'warn';
    return { ...k, ...s, tone, displayValue: k.fmt(s.current), targetDisplay: k.fmt(s.target) };
  });

  /* pipeline counts, scoped */
  const pipelineCounts = PIPELINE.map(s => {
    if (reqFilter === 'all') return s;
    const role = reqById(reqFilter)?.role;
    return { ...s, count: Math.max(2, Math.round(s.count * (CANDIDATES.filter(c => c.role === role).length / CANDIDATES.length) * 1.4)) };
  });

  const periodLabel = periodObj.label.toLowerCase();
  const reqLabel = reqFilter === 'all' ? 'all jobs' : `the ${reqById(reqFilter)?.title}`;

  /* updates filter */
  const UPDATE_FILTERS = [
    { id: 'all',        label: 'All',           match: () => true },
    { id: 'offers',     label: 'Offers',        match: (u) => u.t.startsWith('offer') },
    { id: 'interviews', label: 'Interviews',    match: (u) => u.t === 'interview' },
    { id: 'stage',      label: 'Stage changes', match: (u) => u.t === 'stage' },
  ];
  const visibleUpdates = UPDATES.filter(
    UPDATE_FILTERS.find(f => f.id === updateFilter)?.match || (() => true)
  );

  return (
    <div style={{ display: 'flex', height: '100%', background: 'var(--bg-secondary)', position: 'relative', overflow: 'hidden' }}>
      <Sidebar active="dashboard" onNav={onNav} />
      <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0 }}>
        <Topbar onSearch={() => setSearchOpen(true)} onSettings={() => setSettingsOpen(true)} />
        <div style={{ flex: 1, overflow: 'auto' }}>
          <div style={{ maxWidth: 1280, margin: '0 auto', padding: '24px 32px 40px' }}>

            {/* page header: title + filters */}
            <div style={{
              display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between',
              gap: 20, marginBottom: 20, flexWrap: 'wrap'
            }}>
              <div>
                <h2 style={{ margin: 0, fontSize: 26, fontWeight: 600, letterSpacing: '-0.01em' }}>Dashboard</h2>
                <div style={{ fontSize: 13, color: 'var(--content-tertiary)', marginTop: 4 }}>
                  Showing {reqLabel} · {periodLabel}
                </div>
              </div>
              <FilterBar
                req={reqFilter} setReq={setReqFilter}
                period={period} setPeriod={setPeriod}
              />
            </div>

            {/* hero */}
            <div style={{
              background: 'linear-gradient(160deg, var(--indigo-70), var(--indigo-50))',
              color: 'var(--content-inverse-1)',
              borderRadius: 20, padding: '28px 32px',
              display: 'grid', gridTemplateColumns: '1.6fr 1fr', gap: 32,
              marginBottom: 24, position: 'relative', overflow: 'hidden'
            }}>
              <svg style={{ position: 'absolute', right: -40, top: -40, opacity: 0.18 }} width="280" height="280" viewBox="0 0 280 280">
                <circle cx="200" cy="80" r="80" fill="var(--yellow-50)" />
                <circle cx="120" cy="180" r="60" fill="var(--mint-50)" />
                <rect x="160" y="170" width="80" height="80" rx="20" fill="var(--color-white)" />
              </svg>
              <div style={{ position: 'relative', display: 'flex', flexDirection: 'column', gap: 12 }}>
                <div style={{ fontSize: 12, fontWeight: 600, letterSpacing: '.08em',
                  textTransform: 'uppercase', opacity: .85 }}>{hero.eyebrow}</div>
                <h2 style={{ margin: 0, fontSize: 32, lineHeight: 1.15, fontWeight: 600, letterSpacing: '-0.01em' }}>
                  {hero.headline}
                </h2>
                <p style={{ margin: 0, fontSize: 15, lineHeight: 1.5, opacity: .9, maxWidth: 540 }}>
                  {hero.sub}
                </p>
                <div style={{ display: 'flex', gap: 8, marginTop: 8 }}>
                  <button onClick={() => setSearchOpen(true)} style={{
                    display: 'inline-flex', alignItems: 'center', gap: 8,
                    padding: '11px 18px', borderRadius: 100, border: 0,
                    background: 'var(--color-white)', color: 'var(--content-primary)',
                    fontWeight: 600, fontSize: 14, cursor: 'pointer', fontFamily: 'var(--font-sans)'
                  }}>
                    <I.Sparkle width="16" height="16" style={{ color: 'var(--indigo-50)' }} />
                    Ask AI
                  </button>
                  <button onClick={() => onNav && onNav('pipeline')} style={{
                    display: 'inline-flex', alignItems: 'center', gap: 8,
                    padding: '11px 18px', borderRadius: 100, border: 0,
                    background: 'rgba(249,249,249,0.16)', color: 'var(--color-white)',
                    backdropFilter: 'blur(6px)', fontWeight: 600, fontSize: 14, cursor: 'pointer',
                    fontFamily: 'var(--font-sans)'
                  }}>
                    View pipeline →
                  </button>
                </div>
              </div>

              {/* pipeline funnel mini */}
              <div style={{ position: 'relative', display: 'flex', flexDirection: 'column', gap: 8 }}>
                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                  <div style={{ fontSize: 12, fontWeight: 600, letterSpacing: '.08em',
                    textTransform: 'uppercase', opacity: .85 }}>Pipeline</div>
                  <button onClick={() => onNav && onNav('pipeline')} style={{
                    background: 'transparent', border: 0, padding: 0,
                    fontSize: 12, fontWeight: 600, color: 'var(--color-white)',
                    cursor: 'pointer', opacity: .9, fontFamily: 'var(--font-sans)'
                  }}>Open →</button>
                </div>
                {pipelineCounts.map((s,i) => {
                  const max = pipelineCounts[0].count;
                  return (
                    <div key={s.stage} style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                      <div style={{ fontSize: 12, fontWeight: 500, opacity: .8, width: 76 }}>{s.stage}</div>
                      <div style={{ flex: 1, height: 8, background: 'rgba(249,249,249,0.16)', borderRadius: 100, overflow: 'hidden' }}>
                        <div style={{ width: `${(s.count/max)*100}%`, height: '100%',
                          background: i < 4 ? 'var(--color-white)' : 'var(--yellow-50)',
                          borderRadius: 100, transition: 'width 600ms ease-out' }} />
                      </div>
                      <div style={{ fontSize: 13, fontWeight: 600, fontVariantNumeric: 'tabular-nums', width: 38, textAlign: 'right' }}>{s.count}</div>
                    </div>
                  );
                })}
              </div>
            </div>

            {/* KPIs */}
            <div style={{ display: 'flex', alignItems: 'baseline', justifyContent: 'space-between', marginBottom: 12 }}>
              <h3 style={{ margin: 0, fontSize: 18, fontWeight: 600 }}>Key metrics</h3>
              <span style={{ fontSize: 12, color: 'var(--content-tertiary)' }}>
                {periodObj.label} · {reqFilter === 'all' ? 'all reqs' : reqById(reqFilter)?.title}
              </span>
            </div>
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 12, marginBottom: 28 }}>
              {kpis.map(k => (
                <div key={k.id} style={{
                  background: 'var(--bg-primary)', border: '1px solid var(--stroke-secondary)',
                  borderRadius: 16, padding: 18, display: 'flex', flexDirection: 'column', gap: 10
                }}>
                  <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
                    <div style={{ fontSize: 12, fontWeight: 600, color: 'var(--content-tertiary)' }}>{k.label}</div>
                    <Pill tone={k.tone}>
                      {k.trendPct > 0 ? <I.ArrowUp width="10" height="10" />
                        : k.trendPct < 0 ? <I.ArrowDn width="10" height="10" /> : null}
                      {Math.abs(k.trendPct)}%
                    </Pill>
                  </div>
                  <div style={{ display: 'flex', alignItems: 'flex-end', justifyContent: 'space-between', gap: 8 }}>
                    <div>
                      <div style={{ fontWeight: 600, fontSize: 28, lineHeight: 1.1, letterSpacing: '-0.01em' }}>
                        {k.displayValue}
                      </div>
                      <div style={{ fontSize: 12, color: 'var(--content-tertiary)', marginTop: 2 }}>
                        Target {k.targetDisplay}
                      </div>
                    </div>
                    <div style={{ width: 96 }}>
                      <Sparkbar values={k.values} height={32}
                        color={k.tone === 'prog' ? 'var(--green-50)'
                             : k.tone === 'warn' ? 'var(--yellow-50)'
                             : 'var(--indigo-30)'} />
                    </div>
                  </div>
                </div>
              ))}
            </div>

            {/* requisitions + AI shortlist */}
            <div style={{ display: 'grid', gridTemplateColumns: '1.5fr 1fr', gap: 20, marginBottom: 28 }}>
              <div style={{ background: 'var(--bg-primary)', border: '1px solid var(--stroke-secondary)',
                borderRadius: 16, padding: 20 }}>
                <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14 }}>
                  <h3 style={{ margin: 0, fontSize: 16, fontWeight: 600 }}>
                    {role === 'manager' ? 'Your jobs' : reqFilter === 'all' ? 'Open jobs' : 'Job'}
                  </h3>
                  {(reqFilter !== 'all' || (role === 'manager' && baseReqs.length < REQS.length)) && (
                    <button className="btn btn-link" style={{ fontSize: 13, padding: '4px 8px' }}
                      onClick={() => setShowAllReqs(v => !v)}>
                      {showAllReqs ? 'Show filtered' : `View all (${baseReqs.length})`}
                    </button>
                  )}
                </div>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
                  {visibleReqs.map(r => (
                    <div key={r.id} style={{
                      display: 'grid', gridTemplateColumns: '1.6fr 1fr 1fr auto', gap: 12,
                      alignItems: 'center', padding: '12px 10px', borderRadius: 10,
                      cursor: 'pointer', transition: 'background 120ms ease-out'
                    }} onMouseEnter={(e) => e.currentTarget.style.background = 'var(--bg-secondary)'}
                       onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
                      <div>
                        <div style={{ fontWeight: 600, fontSize: 14 }}>{r.title}</div>
                        <div style={{ fontSize: 12, color: 'var(--content-tertiary)', marginTop: 2 }}>
                          {r.applicants} applicants · {r.days}d open
                        </div>
                      </div>
                      <div>
                        <div style={{ fontSize: 11, fontWeight: 600, color: 'var(--content-tertiary)',
                          textTransform: 'uppercase', letterSpacing: '.06em' }}>AI fill</div>
                        <div style={{ fontSize: 14, fontWeight: 600, fontVariantNumeric: 'tabular-nums',
                          color: r.predicted > r.target ? 'var(--yellow-70)' : 'var(--green-70)' }}>
                          ~{r.predicted}d
                        </div>
                      </div>
                      <Pill tone={r.status === 'On track' ? 'prog' : 'warn'} dot>{r.status}</Pill>
                      <Avatar name={r.owner} size={28} tone="auto" />
                    </div>
                  ))}
                  {visibleReqs.length === 0 && (
                    <div style={{ padding: 20, textAlign: 'center', color: 'var(--content-tertiary)', fontSize: 13 }}>
                      No jobs match this filter.
                    </div>
                  )}
                </div>
              </div>

              <div style={{ background: 'var(--bg-primary)', border: '1px solid var(--stroke-secondary)',
                borderRadius: 16, padding: 20, display: 'flex', flexDirection: 'column' }}>
                <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 4 }}>
                  <I.Sparkle width="16" height="16" style={{ color: 'var(--indigo-50)' }} />
                  <h3 style={{ margin: 0, fontSize: 16, fontWeight: 600 }}>AI shortlist</h3>
                </div>
                <p style={{ margin: '0 0 14px', fontSize: 12, color: 'var(--content-tertiary)' }}>
                  {reqFilter === 'all'
                    ? 'Top-ranked across all open reqs.'
                    : `Top-ranked for ${reqById(reqFilter)?.title}.`}
                </p>
                <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                  {topCandidates.map(c => (
                    <button key={c.id} onClick={() => setCandidate(c)} style={{
                      display: 'flex', alignItems: 'center', gap: 12,
                      padding: '10px 10px', borderRadius: 10, border: 0, background: 'transparent',
                      cursor: 'pointer', textAlign: 'left', font: 'inherit', transition: 'background 120ms ease-out'
                    }} onMouseEnter={(e) => e.currentTarget.style.background = 'var(--bg-secondary)'}
                       onMouseLeave={(e) => e.currentTarget.style.background = 'transparent'}>
                      <ScoreRing score={c.score} size={42} stroke={4} />
                      <div style={{ flex: 1, minWidth: 0 }}>
                        <div style={{ fontWeight: 600, fontSize: 13 }}>{c.name}</div>
                        <div style={{ fontSize: 11, color: 'var(--content-tertiary)' }}>
                          {roleLabel(c.role)} · {c.loc.split(',')[1]?.trim() || c.loc}
                        </div>
                      </div>
                    </button>
                  ))}
                  {topCandidates.length === 0 && (
                    <div style={{ padding: 16, textAlign: 'center', color: 'var(--content-tertiary)', fontSize: 13 }}>
                      No candidates yet.
                    </div>
                  )}
                </div>
                <button onClick={() => setSearchOpen(true)} style={{
                  marginTop: 14, padding: '10px 14px', border: '1px dashed var(--stroke-primary)',
                  borderRadius: 12, background: 'transparent', cursor: 'pointer',
                  fontSize: 13, color: 'var(--content-highlight)', fontWeight: 600,
                  fontFamily: 'var(--font-sans)', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 6
                }}>
                  <I.Sparkle width="14" height="14" />
                  Ask for a custom shortlist
                </button>
              </div>
            </div>

            {/* updates feed */}
            <div style={{ background: 'var(--bg-primary)', border: '1px solid var(--stroke-secondary)',
              borderRadius: 16, padding: 20 }}>
              <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 14, flexWrap: 'wrap', gap: 10 }}>
                <h3 style={{ margin: 0, fontSize: 16, fontWeight: 600 }}>Latest updates</h3>
                <div style={{ display: 'flex', gap: 6 }}>
                  {UPDATE_FILTERS.map(f => (
                    <Pill key={f.id}
                      tone={updateFilter === f.id ? 'brand' : 'neutral'}
                      active={updateFilter === f.id}
                      onClick={() => setUpdateFilter(f.id)}>
                      {f.label}
                    </Pill>
                  ))}
                </div>
              </div>
              <div style={{ display: 'flex', flexDirection: 'column' }}>
                {visibleUpdates.length === 0 && (
                  <div style={{ padding: 20, textAlign: 'center', color: 'var(--content-tertiary)', fontSize: 13 }}>
                    No updates in this category.
                  </div>
                )}
                {visibleUpdates.map((u,i) => (
                  <div key={i} style={{
                    display: 'grid', gridTemplateColumns: 'auto 1fr auto', gap: 14,
                    padding: '12px 4px', alignItems: 'center',
                    borderTop: i > 0 ? '1px solid var(--stroke-secondary)' : 0
                  }}>
                    <UpdateIcon type={u.t} tone={u.tone} />
                    <div>
                      <span style={{ fontWeight: 600, fontSize: 14 }}>{u.who}</span>
                      <span style={{ fontSize: 14, color: 'var(--content-secondary)', marginLeft: 6 }}>{u.what}</span>
                    </div>
                    <div style={{ fontSize: 12, color: 'var(--content-tertiary)' }}>{u.when} ago</div>
                  </div>
                ))}
              </div>
            </div>

          </div>
        </div>
      </div>

      <AISearchModal open={searchOpen} onClose={() => setSearchOpen(false)} onOpenCandidate={setCandidate} />
      <SettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} />
      <CandidateDrawer candidate={candidate} onClose={() => setCandidate(null)} />
    </div>
  );
}

function UpdateIcon({ type, tone }) {
  const tones = {
    brand:   { bg: 'var(--indigo-20)', fg: 'var(--indigo-90)' },
    prog:    { bg: 'var(--green-20)',  fg: 'var(--green-90)' },
    dest:    { bg: 'var(--red-20)',    fg: 'var(--red-90)' },
    neutral: { bg: 'var(--neutral-20)',fg: 'var(--neutral-80)' },
  };
  const t = tones[tone] || tones.neutral;
  const ic = type === 'offer-accept' ? <I.Check width="16" height="16" />
           : type === 'offer-sent'   ? <I.Send width="16" height="16" />
           : type === 'offer-decline'? <I.X width="16" height="16" />
           : type === 'interview'    ? <I.Calendar width="16" height="16" />
           : <I.ArrowUp width="16" height="16" />;
  return (
    <div style={{ width: 32, height: 32, borderRadius: 10, background: t.bg, color: t.fg,
      display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
      {ic}
    </div>
  );
}

window.DashV1 = DashV1;
