/** @jsx React.createElement */
/* ActiveProjectsBoardWidget — interactive pipeline matrix. Each Therapy Area
   row is split by a dotted line: Ph 3 / Approved-Marketed opportunities sit
   below it. Cards drag between cells; TA counts and the # row derive from
   live state. Columns are fixed-width so the header, every TA row and the
   footer share one alignment grid. */

const APO_COLS = 'minmax(84px,0.85fr) minmax(118px,1fr) minmax(150px,1.7fr) minmax(120px,1.15fr) minmax(104px,1fr) minmax(104px,1fr)';
const APO_DASH = '1px dashed #AEB8C6';

function UpcomingBand({ ta, band, onOpenPhase }) {
  const data = APO_UPCOMING[ta];
  const sum = APO_PHASE_ORDER.reduce((s, k) => s + data[k], 0);
  if (sum === 0) return <div style={{ padding: '8px 10px', width: '100%' }} />;
  const keys = band === 'above' ? ['platform', 'pc', 'ph1', 'ph2'] : ['ph3', 'approved'];
  return (
    <div style={{ padding: '8px 10px', width: '100%' }}>
      <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 5 }}>
        {keys.map((pk) => {
          const ph = APO_PHASES[pk];
          const n = data[pk];
          const zero = n === 0;
          const clickable = !zero && onOpenPhase;
          return (
            <div key={pk} title={clickable ? `${ph.label} \u2014 view opportunities` : ph.label}
              className={clickable ? 'apo-upcell' : undefined}
              onClick={clickable ? () => onOpenPhase(ta, pk) : undefined}
              style={{
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                height: 26, borderRadius: 6,
                background: ph.fill,
                border: `1px solid ${ph.border}`,
                color: ph.text,
                fontSize: 13, fontWeight: 700, fontVariantNumeric: 'tabular-nums',
                cursor: clickable ? 'pointer' : 'default',
              }}>{n}</div>
          );
        })}
      </div>
    </div>
  );
}

function TALabelCell({ ta, count, onFilter }) {
  return (
    <div style={{
      position: 'relative', height: '100%', boxSizing: 'border-box',
      display: 'flex', flexDirection: 'column', justifyContent: 'center',
      gap: 4, padding: '12px 12px 12px 18px', background: '#fff',
    }}>
      <span style={{ position: 'absolute', left: 0, top: 8, bottom: 8, width: 5, borderRadius: 3, background: ta.accent }} />
      <div style={{ fontSize: 14, fontWeight: 600, color: 'var(--ab-navy-700)', lineHeight: 1.2 }}>{ta.name}</div>
      <button className="apo-linkcount" onClick={() => onFilter && onFilter(ta.key)} title={`View ${ta.name} opportunities`}>
        <b>{count}</b> active
      </button>
    </div>
  );
}

// ── One Therapy-Area row: an aligned 6-col × 2-row sub-grid. Row 1 (above the
//    dotted line) holds Platform→Ph 2; row 2 holds Ph 3 / Approved. ──────────
function APOMatrixRow({ ta, projects, onMove, onOpen, onOpenPhase, onFilterTa, hover, highlight }) {
  const [over, setOver] = React.useState(null);
  const byStage = APO_STAGES.map((st) => {
    const cards = projects.filter(p => p.ta === ta.key && p.stage === st.key);
    return { st, above: cards.filter(c => !apoIsBelow(c)), below: cards.filter(apoIsBelow) };
  });
  const cells = (band) => byStage.map((c, i) => {
    const kk = c.st.key + ':' + band;
    const list = band === 'above' ? c.above : c.below;
    return (
      <div key={kk}
        onDragOver={(e) => { if (!window.__apoDragId) return; e.preventDefault(); e.dataTransfer.dropEffect = 'move'; if (over !== kk) setOver(kk); }}
        onDragLeave={(e) => { if (!e.currentTarget.contains(e.relatedTarget)) setOver(o => (o === kk ? null : o)); }}
        onDrop={(e) => { e.preventDefault(); setOver(null); const id = e.dataTransfer.getData('text/plain') || window.__apoDragId; if (id) onMove(id, { ta: ta.key, stage: c.st.key }); }}
        style={{
          gridColumn: 3 + i, gridRow: band === 'above' ? 1 : 2,
          background: c.st.tint,
          borderRight: i < APO_STAGES.length - 1 ? '1px solid var(--ab-border)' : 'none',
          borderBottom: band === 'above' ? APO_DASH : 'none',
          padding: 8, minHeight: band === 'above' ? 42 : 24, boxSizing: 'border-box',
          boxShadow: over === kk ? 'inset 0 0 0 2px var(--ab-blue-400)' : 'none',
          transition: 'box-shadow 120ms var(--ab-ease)',
        }}>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: 5, alignContent: 'flex-start' }}>
          {list.map(card => (
            <div key={card.id} style={{ flex: '1 1 96px', minWidth: 92, maxWidth: 176 }}>
              <ProjectChip project={card} onOpen={onOpen} onHover={hover} highlight={highlight} />
            </div>
          ))}
        </div>
      </div>
    );
  });
  return (
    <div style={{ display: 'grid', gridTemplateColumns: APO_COLS, borderTop: '1px solid var(--ab-border)' }}>
      <div style={{ gridColumn: 1, gridRow: '1 / span 2', borderRight: '1px solid var(--ab-border)' }}>
        <TALabelCell ta={ta} count={apoTaCount(projects, ta.key)} onFilter={onFilterTa} />
      </div>
      <div style={{ gridColumn: 2, gridRow: 1, borderRight: '1px solid var(--ab-border)', borderBottom: APO_DASH, display: 'flex', alignItems: 'flex-start' }}>
        <UpcomingBand ta={ta.key} band="above" onOpenPhase={onOpenPhase} />
      </div>
      {cells('above')}
      <div style={{ gridColumn: 2, gridRow: 2, borderRight: '1px solid var(--ab-border)', display: 'flex', alignItems: 'flex-start' }}>
        <UpcomingBand ta={ta.key} band="below" onOpenPhase={onOpenPhase} />
      </div>
      {cells('below')}
    </div>
  );
}

// ── The matrix ──────────────────────────────────────────────────────────
function APOMatrix({ projects, onMove, onOpen, onFilterStage, onOpenPhase, onFilterAll, onFilterTa, highlight }) {
  const [tip, setTip] = React.useState(null);
  const timer = React.useRef(null);
  React.useEffect(() => () => clearTimeout(timer.current), []);
  const hover = React.useCallback((p, rect) => {
    clearTimeout(timer.current);
    if (!p) { setTip(null); return; }
    timer.current = setTimeout(() => setTip({ p, rect }), 140);
  }, []);
  const upcomingTotal = APO_TAS.reduce((s, ta) => s + APO_PHASE_ORDER.reduce((x, k) => x + APO_UPCOMING[ta.key][k], 0), 0);
  return (
    <div style={{ border: '1px solid var(--ab-border)', borderRadius: 12, overflow: 'hidden', background: '#fff', width: '100%', boxSizing: 'border-box' }}>
      {/* ── Header row ── */}
      <div style={{ display: 'grid', gridTemplateColumns: APO_COLS }}>
        <div style={{ ...apoHeadBase, background: '#fff', borderRight: '1px solid var(--ab-border)' }}>
          <span style={{ fontSize: 11, fontWeight: 700, color: 'var(--ab-slate-400)', letterSpacing: '.08em' }}>TA</span>
        </div>
        <div className="apo-stagehead" title="View all active opportunities" onClick={() => onFilterAll && onFilterAll()}
          style={{ ...apoHeadBase, background: '#fff', borderRight: '1px solid var(--ab-border)', flexDirection: 'column', gap: 2, cursor: 'pointer' }}>
          <span style={{ fontSize: 12.5, fontWeight: 600, color: 'var(--ab-navy-700)', textAlign: 'center', lineHeight: 1.2 }}>Upcoming<br/>opportunities</span>
        </div>
        {APO_STAGES.map((st, i) => (
          <div key={st.key} className="apo-stagehead"
            title={`${st.label} \u2014 view opportunities in this stage`}
            onClick={() => onFilterStage && onFilterStage(st.key)}
            style={{
              ...apoHeadBase, background: st.head, color: st.headText,
              flexDirection: 'column', gap: 1, cursor: 'pointer',
              borderRight: i < APO_STAGES.length - 1 ? '1px solid rgba(255,255,255,.5)' : 'none',
            }}>
            <span style={{ fontSize: 13, fontWeight: 700, lineHeight: 1.1 }}>{st.label}</span>
            <span style={{ fontSize: 10.5, fontWeight: 500, opacity: .8 }}>{st.sub}</span>
          </div>
        ))}
      </div>

      {/* ── TA rows ── */}
      {APO_TAS.map((ta) => (
        <APOMatrixRow key={ta.key} ta={ta} projects={projects}
          onMove={onMove} onOpen={onOpen} onOpenPhase={onOpenPhase} onFilterTa={onFilterTa} hover={hover} highlight={highlight} />
      ))}

      {/* ── Totals footer (#) — live counts ── */}
      <div style={{ display: 'grid', gridTemplateColumns: APO_COLS }}>
        <div style={{ ...apoFootBase, background: 'var(--ab-slate-50)', borderRight: '1px solid var(--ab-border)', justifyContent: 'flex-start', paddingLeft: 18 }}>
          <span style={{ fontSize: 13, fontWeight: 700, color: 'var(--ab-slate-500)' }}>#</span>
        </div>
        <div className="apo-footcell" title="View all active opportunities" onClick={() => onFilterAll && onFilterAll()}
          style={{ ...apoFootBase, background: 'var(--ab-slate-50)', borderRight: '1px solid var(--ab-border)' }}>
          <span style={apoFootNum}>{upcomingTotal}</span>
        </div>
        {APO_STAGES.map((st, i) => {
          const n = apoStageCount(projects, st.key);
          return (
            <div key={st.key} className="apo-footcell" title={`View ${st.label} opportunities`} onClick={() => onFilterStage && onFilterStage(st.key)}
              style={{
                ...apoFootBase, background: st.tint,
                borderRight: i < APO_STAGES.length - 1 ? '1px solid var(--ab-border)' : 'none',
              }}>
              <span style={{ ...apoFootNum, color: st.headText }}>{n || '\u2013'}</span>
            </div>
          );
        })}
      </div>
      <APOTooltip tip={tip} />
    </div>
  );
}

const apoHeadBase = {
  display: 'flex', alignItems: 'center', justifyContent: 'center',
  padding: '11px 10px', minHeight: 52, boxSizing: 'border-box', textAlign: 'center',
};
const apoFootBase = {
  display: 'flex', alignItems: 'center', justifyContent: 'center',
  padding: '9px 10px', borderTop: '2px solid var(--ab-border-strong)',
};
const apoFootNum = {
  fontSize: 15, fontWeight: 700, color: 'var(--ab-slate-700)',
};

// ── Legend ───────────────────────────────────────────────────────────────
function APOLegend({ highlight, onHover, hidden, onToggle }) {
  return (
    <div data-tour="legend" style={{ display: 'flex', flexWrap: 'wrap', gap: '18px 36px', padding: '16px 4px 2px' }}>
      <div>
        <div style={apoLegendTitle}>Development phase</div>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px 14px' }}>
          {APO_PHASE_ORDER.map((pk) => {
            const ph = APO_PHASES[pk];
            const off = !!(hidden && hidden['phase:' + pk]);
            const active = highlight && highlight.type === 'phase' && highlight.key === pk;
            return (
              <div key={pk} className="apo-legitem" data-active={String(!!active)} data-off={String(off)}
                onMouseEnter={() => { if (!off && onHover) onHover({ type: 'phase', key: pk }); }}
                onMouseLeave={() => onHover && onHover(null)}
                onClick={() => onToggle && onToggle('phase', pk)}
                style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                <span style={{ width: 16, height: 16, borderRadius: 4, background: ph.fill, border: `1px solid ${ph.border}`, flexShrink: 0 }} />
                <span style={apoLegendLabel}>{ph.label}</span>
              </div>
            );
          })}
        </div>
      </div>
      <div>
        <div style={apoLegendTitle}>Status this week</div>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: '8px 14px', maxWidth: 820 }}>
          {APO_FLAG_ORDER.map((flag) => {
            const off = !!(hidden && hidden['flag:' + flag]);
            const active = highlight && highlight.type === 'flag' && highlight.key === flag;
            return (
              <div key={flag} className="apo-legitem" data-active={String(!!active)} data-off={String(off)}
                onMouseEnter={() => { if (!off && onHover) onHover({ type: 'flag', key: flag }); }}
                onMouseLeave={() => onHover && onHover(null)}
                onClick={() => onToggle && onToggle('flag', flag)}
                style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
                <FlagGlyph flag={flag} />
                <span style={apoLegendLabel}>{APO_STATUS[flag]}</span>
              </div>
            );
          })}
        </div>
      </div>
    </div>
  );
}

const apoLegendTitle = {
  fontSize: 10, fontWeight: 700, letterSpacing: '.07em', textTransform: 'uppercase',
  color: 'var(--ab-slate-400)', marginBottom: 8,
};
const apoLegendLabel = { fontSize: 11.5, color: 'var(--ab-slate-600)', lineHeight: 1.2 };

function apoLegendHidden(p, hidden) {
  if (!hidden) return false;
  return !!(hidden['phase:' + p.phase] || (p.flags || []).some(f => hidden['flag:' + f]));
}

Object.assign(window, { APOMatrix, APOLegend, APOMatrixRow, apoLegendHidden });
