// ============================================================
//   LayoutMatch — "Person + Job + Owner + Memory" shell
//   The atom: a match between a person and a job, with a current
//   owner and the memory the system carries forward.
//   The lanes are owner states, not pipeline stages.
//   The verb is the next action, surfaced on every row.
// ============================================================
const { color: MC } = window.FF;

/* ---------- Owner states (the 5 lanes) ----------
   AI lanes vs human lanes are separated by a small "→" — the
   handoff is visible at the nav level. Color is used here for
   identity only; nowhere else in the UI.                       */
const OWNERS = {
  ai: {
    key: 'ai', label: 'AI working',
    tint: MC.copilot[50], fg: MC.copilot[800], dot: MC.copilot[500],
    desc: 'The AI is sourcing, contacting, or screening.',
  },
  ready: {
    key: 'ready', label: 'Ready for you',
    tint: MC.primary[50], fg: MC.primary[800], dot: MC.primary[500],
    desc: "The AI has handed these to you. They're waiting on your judgment.",
  },
  active: {
    key: 'active', label: 'In progress',
    tint: MC.inform[50], fg: MC.inform[700], dot: MC.inform[500],
    desc: "You're working these — interviews, calls, offers.",
  },
  waiting: {
    key: 'waiting', label: 'Waiting',
    tint: MC.caution[50], fg: MC.caution[700], dot: MC.caution[500],
    desc: 'Waiting on the candidate or hiring manager.',
  },
  done: {
    key: 'done', label: 'Done',
    tint: MC.tint[40], fg: MC.shade[700], dot: MC.shade[600],
    desc: 'Closed — hired, rejected, or withdrawn.',
  },
};
const LANE_ORDER = ['ai', 'ready', 'active', 'waiting', 'done'];

/* ---------- Derive owner + next action from candidate data ----------
   This is the rule that converts pipeline-stage data into the
   match-with-owner model. Each match gets exactly one owner
   and exactly one suggested next verb.                          */
function deriveMatch(c) {
  if (c.stage === 'sourcing') {
    return { owner: 'ai', next: 'AI is reaching out', primary: false };
  }
  if (c.stage === 'new') {
    if (c.unread || c.justLanded) return { owner: 'ready', next: 'Read response', primary: true };
    return { owner: 'ai', next: 'AI is screening', primary: false };
  }
  if (c.stage === 'engaged') {
    if (c.unread || c.justLanded) return { owner: 'ready', next: 'Review response', primary: true };
    const m = (c.lastMsg || '').toLowerCase();
    if (/awaiting|reminder|sent reminder/.test(m)) return { owner: 'waiting', next: 'Nudge or move on', primary: false };
    if (/scheduled|booked|confirm/.test(m)) return { owner: 'active', next: 'Confirm interview', primary: true };
    if (/screening questions|sent screening/.test(m)) return { owner: 'waiting', next: 'Awaiting answers', primary: false };
    return { owner: 'active', next: 'Continue conversation', primary: false };
  }
  return { owner: 'active', next: 'Continue', primary: false };
}

/* ---------- Memory map ----------
   Memory is a layer, not a tab. Only surface what's notable.
   Empty memory = a clean candidate; that's information too.
   DNH is the only thing colored red — it's the one stop sign. */
const MEMORY = {
  c1:  [{ kind: 'note',     text: 'Sourced 3× before, never engaged' }],
  c3:  [{ kind: 'fresh',    text: 'New to FactoryFix' }],
  c10: [{ kind: 'repeat',   text: 'Applied 4× in 90 days' }],
  c11: [{ kind: 'former',   text: 'Former employee · 2019–2022' }],
  c13: [{ kind: 'rejected', text: 'Rejected — Press Op, March' }],
  c16: [{ kind: 'dnh',      text: 'Do not hire' }],
  c18: [{ kind: 'fresh',    text: 'First conversation' }],
  c19: [{ kind: 'repeat',   text: 'Also applied to CNC Setup' }],
  c20: [{ kind: 'former',   text: 'Former employee · 2021' }],
  c22: [{ kind: 'saidno',   text: 'Said no in March — shift conflict' }],
  c23: [{ kind: 'repeat',   text: '2nd application, this job' }],
  c25: [{ kind: 'fresh',    text: 'New' }],
  c27: [{ kind: 'former',   text: 'Interviewed Feb · QA role' }],
};

const MEM_STYLE = {
  note:     { bg: MC.tint[40],     fg: MC.shade[820] },
  fresh:    { bg: MC.tint[40],     fg: MC.shade[700] },
  repeat:   { bg: MC.inform[50],   fg: MC.inform[700] },
  former:   { bg: MC.highlight[50],fg: MC.highlight[700] },
  rejected: { bg: MC.caution[50],  fg: MC.caution[700] },
  saidno:   { bg: MC.caution[50],  fg: MC.caution[700] },
  dnh:      { bg: MC.critical[50], fg: MC.critical[700] },
};

/* ============================================================
   ROOT
   ============================================================ */
function LayoutMatch({ candidates, selectedId, onSelect, vocab }) {
  const [owner, setOwner] = React.useState('ready');
  const decorated = candidates.map(c => ({ ...c, _m: deriveMatch(c) }));
  const counts = LANE_ORDER.reduce((acc, k) => {
    acc[k] = decorated.filter(c => c._m.owner === k).length; return acc;
  }, {});
  // Done lane currently empty in seed data — fake a couple so the lane reads as real.
  counts.done = 8;

  const list = decorated.filter(c => c._m.owner === owner);
  const O = OWNERS[owner];

  return (
    <React.Fragment>
      <LaneRow counts={counts} active={owner} onChange={setOwner}/>
      <LaneHeader owner={O} count={list.length || counts[owner]}/>
      <MatchList items={list} selectedId={selectedId} onSelect={onSelect}/>
    </React.Fragment>
  );
}

/* ---------- Lane navigation ---------- */
function LaneRow({ counts, active, onChange }) {
  return (
    <div style={{
      padding: '14px 18px 12px', borderBottom: `1px solid ${MC.tint[80]}`,
      display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'nowrap', overflowX: 'auto',
    }}>
      {LANE_ORDER.map((k, i) => (
        <React.Fragment key={k}>
          {i === 2 && <LaneDivider/>}
          <LanePill owner={OWNERS[k]} count={counts[k]} active={k === active} onClick={() => onChange(k)}/>
        </React.Fragment>
      ))}
    </div>
  );
}

function LanePill({ owner, count, active, onClick }) {
  return (
    <button onClick={onClick} style={{
      display: 'inline-flex', alignItems: 'center', gap: 7, padding: '7px 12px 7px 10px',
      background: active ? owner.tint : 'transparent',
      border: `1px solid ${active ? owner.dot : MC.tint[80]}`,
      borderRadius: 9999, cursor: 'pointer',
      fontSize: 13, fontWeight: active ? 700 : 500,
      color: active ? owner.fg : MC.shade[820],
      whiteSpace: 'nowrap',
    }}>
      <span style={{
        width: 7, height: 7, borderRadius: '50%', background: owner.dot,
        opacity: active ? 1 : .55,
      }}/>
      {owner.label}
      <span style={{
        fontWeight: 700, color: active ? owner.fg : MC.shade[700],
        fontVariantNumeric: 'tabular-nums',
      }}>{count}</span>
    </button>
  );
}

/* The "handoff" divider — the entire AI→human mental model in 2cm of UI. */
function LaneDivider() {
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 6, padding: '0 4px',
      color: MC.shade[600], fontSize: 11, fontWeight: 600,
      letterSpacing: '.04em', textTransform: 'uppercase', flex: 'none',
    }} title="The AI hands matches over to you here.">
      <span aria-hidden style={{
        width: 14, height: 1, background: MC.tint[100],
      }}/>
      <span style={{ fontSize: 13, color: MC.shade[700] }}>→</span>
    </span>
  );
}

/* ---------- Lane header (sentence-level explanation) ---------- */
function LaneHeader({ owner, count }) {
  return (
    <div style={{ padding: '14px 20px 8px', display: 'flex', alignItems: 'baseline', gap: 10 }}>
      <div style={{ flex: 1 }}>
        <div style={{
          fontSize: 11, fontWeight: 700, color: MC.shade[700],
          letterSpacing: '.08em', textTransform: 'uppercase', marginBottom: 2,
        }}>{owner.label}</div>
        <div style={{ fontSize: 13, color: MC.shade[820], lineHeight: 1.45 }}>
          {owner.desc}
        </div>
      </div>
      <div style={{
        fontSize: 12, color: MC.shade[700], fontVariantNumeric: 'tabular-nums', flex: 'none',
      }}>
        {count} {count === 1 ? 'match' : 'matches'}
      </div>
    </div>
  );
}

/* ---------- Match list ---------- */
function MatchList({ items, selectedId, onSelect }) {
  if (!items.length) {
    return (
      <div style={{ padding: '40px 20px', textAlign: 'center', color: MC.shade[700], fontSize: 13 }}>
        Nothing in this lane right now.
      </div>
    );
  }
  return (
    <div style={{ flex: 1, overflow: 'auto', borderTop: `1px solid ${MC.tint[80]}` }}>
      {items.map(c => (
        <MatchRow key={c.id} c={c} selected={c.id === selectedId} onSelect={onSelect}/>
      ))}
    </div>
  );
}

/* ---------- The atom — Person + Job + Owner + Memory + Verb ---------- */
function MatchRow({ c, selected, onSelect }) {
  const O = OWNERS[c._m.owner];
  const memory = MEMORY[c.id] || [];
  return (
    <div onClick={() => onSelect?.(c.id)} style={{
      position: 'relative', padding: '14px 20px 14px 18px',
      borderBottom: `1px solid ${MC.tint[80]}`, cursor: 'pointer',
      background: selected ? MC.highlight[50] + '66' : '#fff',
    }}>
      {selected && <div style={{
        position: 'absolute', left: 0, top: 0, bottom: 0, width: 3, background: MC.highlight[500],
      }}/>}

      {/* Row 1 — identity + time */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 3 }}>
        <input type="checkbox" style={{ width: 14, height: 14, accentColor: MC.highlight[500] }}
          onClick={e => e.stopPropagation()}/>
        <h3 style={{
          margin: 0, fontSize: 14, fontWeight: 700, color: MC.shade[880],
          whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
        }}>{c.name}</h3>
        <span style={{
          display: 'inline-flex', alignItems: 'center', gap: 3, padding: '1px 6px 1px 4px',
          background: MC.primary[500], color: '#fff',
          fontSize: 11, fontWeight: 700, borderRadius: 4, flex: 'none',
        }}>
          <span style={{ fontSize: 9 }}>★</span>{c.score}
        </span>
        <div style={{ flex: 1 }}/>
        <span style={{ fontSize: 11, color: MC.shade[700], flex: 'none' }}>{c.time}</span>
      </div>

      {/* Row 2 — the match: person FOR job */}
      <div style={{
        fontSize: 12.5, color: MC.shade[820], marginLeft: 22, marginBottom: 6,
        whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
      }}>
        <span style={{ color: MC.shade[700] }}>for</span>{' '}
        <span style={{ fontWeight: 600, color: MC.shade[880] }}>Machine Operator I</span>
        <span style={{ color: MC.shade[600] }}> · {c.loc}</span>
      </div>

      {/* Row 3 — the most recent signal (conversation OR sourcing context) */}
      {c.lastMsg && (
        <div style={{
          fontSize: 12.5, color: MC.shade[820], marginLeft: 22, marginBottom: 8,
          fontStyle: c.lastMsg.startsWith('"') || c.lastMsg.startsWith('\u201C') ? 'normal' : 'normal',
          whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis',
        }}>
          <span style={{ color: MC.shade[600] }}>
            {c._m.owner === 'ai' ? 'AI: ' : c.lastMsg.startsWith('"') || c.lastMsg.startsWith('\u201C') ? 'They said: ' : '· '}
          </span>
          {c.lastMsg}
        </div>
      )}
      {!c.lastMsg && c.stage === 'sourcing' && (
        <div style={{
          fontSize: 12.5, color: MC.shade[700], marginLeft: 22, marginBottom: 8,
        }}>
          <span style={{ color: MC.shade[600] }}>AI: </span>
          {c.role} at {c.company}
        </div>
      )}

      {/* Row 4 — owner pill + memory badges + next action verb */}
      <div style={{
        marginLeft: 22, display: 'flex', alignItems: 'center', gap: 6, flexWrap: 'wrap',
      }}>
        <OwnerPill owner={O}/>
        {memory.map((m, i) => <MemoryBadge key={i} m={m}/>)}
        <div style={{ flex: 1, minWidth: 8 }}/>
        <NextAction action={c._m} owner={O}/>
      </div>
    </div>
  );
}

function OwnerPill({ owner }) {
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 5, padding: '2px 8px 2px 7px',
      borderRadius: 9999, fontSize: 11, fontWeight: 700,
      background: owner.tint, color: owner.fg, flex: 'none',
    }}>
      <span style={{ width: 6, height: 6, borderRadius: '50%', background: owner.dot }}/>
      {owner.label}
    </span>
  );
}

function MemoryBadge({ m }) {
  const s = MEM_STYLE[m.kind] || MEM_STYLE.note;
  const dnh = m.kind === 'dnh';
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 4, padding: '2px 8px',
      borderRadius: 9999, fontSize: 11, fontWeight: dnh ? 700 : 600,
      background: s.bg, color: s.fg, flex: 'none',
      border: dnh ? `1px solid ${MC.critical[300]}` : 'none',
      letterSpacing: dnh ? '.02em' : 0, textTransform: dnh ? 'uppercase' : 'none',
    }}>
      <span style={{ opacity: .7, fontSize: 10 }}>◇</span>
      {m.text}
    </span>
  );
}

function NextAction({ action, owner }) {
  if (action.primary) {
    return (
      <button onClick={e => e.stopPropagation()} style={{
        display: 'inline-flex', alignItems: 'center', gap: 4, padding: '4px 10px',
        background: MC.shade[880], color: '#fff', border: 0, borderRadius: 6,
        fontSize: 12, fontWeight: 600, cursor: 'pointer', flex: 'none',
      }}>
        {action.next} <span style={{ fontSize: 11 }}>→</span>
      </button>
    );
  }
  return (
    <span style={{ fontSize: 11.5, color: MC.shade[700], flex: 'none' }}>
      {action.next}
    </span>
  );
}

Object.assign(window, { LayoutMatch });
