/* ELEV8 ATS - Tasks (#/tasks): the one task queue (R98). The `tasks` collection in
   data.js is the single source of truth - Today's "Get on with it" renders an
   owner-filtered view of the same rows, and every write goes through E8Store so
   completes/snoozes/reassigns survive reload and show up on both surfaces.
   Namespace: .e8-tk-* (grepped unique before adding). */
const DStk = window.Stand8DesignSystem_b5c975;

const TK_URGENCY = {
  now: { label: 'Right now', tone: 'danger' },
  today: { label: 'Today', tone: 'warning' },
  week: { label: 'This week', tone: 'neutral' },
};
const TK_KIND_ICON = { match: 'join_inner', bench: 'engineering', send: 'send', alert: 'priority_high', note: 'sticky_note_2', general: 'task_alt' };

/* Resolve a task's typed ref to { name, icon, path } for the related-record chip. */
function tkRefInfo(t) {
  if (!t || !t.ref) return null;
  const D = window.E8DATA || {};
  const r = t.ref;
  if (r.type === 'job') {
    const j = (D.jobs || []).find((x) => x.id === r.id);
    return j ? { name: j.id + ' · ' + j.client, icon: 'work', path: 'job/' + j.id + '/overview' } : null;
  }
  if (r.type === 'candidate') {
    const c = (D.matches || []).find((x) => x.id === r.id);
    return c ? { name: c.name, icon: 'person', path: 'candidate/' + c.id } : null;
  }
  if (r.type === 'client') {
    const c = (D.clients || []).find((x) => x.id === r.id);
    return c ? { name: c.name, icon: 'apartment', path: 'client/' + c.id } : null;
  }
  if (r.type === 'engagement') {
    const e = (D.managedEngagements || []).find((x) => x.id === r.id);
    return e ? { name: e.name, icon: 'badge', path: 'engagement/' + e.id } : null;
  }
  return null;
}

/* The row's action destination: explicit route ('#/...') wins, then the ref's record. */
function tkTaskPath(t) {
  if (t && t.route) return String(t.route).replace(/^#\//, '');
  const ref = tkRefInfo(t);
  return ref ? ref.path : null;
}

/* ---- Shared write helpers (Today + Tasks use the same verbs) ---- */
function tkComplete(t, showToast) {
  const snap = window.E8Store.snapshot('tasks', t.id, ['state', 'doneAt']);
  window.E8Store.set('tasks', t.id, { state: 'done', doneAt: 'Just now' });
  if (showToast) showToast('Done · ' + t.title.slice(0, 44) + (t.title.length > 44 ? '…' : ''), 'Undo', () => window.E8Store.set('tasks', t.id, snap || { state: 'open', doneAt: null }));
}
function tkReopen(t, showToast) {
  window.E8Store.set('tasks', t.id, { state: 'open', doneAt: null });
  if (showToast) showToast('Reopened - back on the queue');
}

/* ---- Needs review: read-through of E8Queue review items + Watchtower findings.
   Display only - their state lives in the approvals queue, every row opens #/approvals. ---- */
function TkNeedsReview() {
  const queueItems = window.E8Queue ? window.E8Queue.list().filter((i) => i.state === 'review') : [];
  const flags = (window.E8Watch ? window.E8Watch.findings() : [])
    .filter((f) => !queueItems.some((i) => i.title === f.title)); // Watchtower drafts already queued show once
  const rows = queueItems
    .map((i) => ({ icon: i.icon || 'fact_check', title: i.title, sub: (i.agent ? i.agent : 'Agent') + (i.when ? ' · ' + i.when : ''), tone: 'warning' }))
    .concat(flags.map((f) => ({ icon: f.icon || 'radar', title: f.title, sub: 'Watchtower · last sweep', tone: f.severity === 'danger' ? 'danger' : 'warning' })));
  if (!rows.length) return null;
  const shown = rows.slice(0, 4);
  const go = () => navigate('approvals');
  return (
    <div className="e8-card e8-tk-review">
      <div className="e8-tk-review-head">
        <span className="e8-tk-review-title"><span className="material-symbols-outlined" aria-hidden="true">fact_check</span>Needs review</span>
        <span className="e8-tk-review-n">{rows.length} waiting on you</span>
        <button type="button" className="e8-tk-review-all" onClick={go}>Open approvals →</button>
      </div>
      {shown.map((r, i) => (
        <div key={i} className="e8-tk-review-row" role="button" tabIndex={0} onClick={go}
          onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); go(); } }}>
          <span className={'e8-tk-review-ic ' + r.tone}><span className="material-symbols-outlined" aria-hidden="true">{r.icon}</span></span>
          <span className="e8-tk-review-t">{r.title}</span>
          <span className="e8-tk-review-s">{r.sub}</span>
          <span className="material-symbols-outlined e8-tk-review-chev" aria-hidden="true">chevron_right</span>
        </div>
      ))}
      {rows.length > shown.length ? (
        <button type="button" className="e8-tk-review-more" onClick={go}>+{rows.length - shown.length} more in approvals</button>
      ) : null}
    </div>
  );
}

/* ---- One task row ---- */
function TkRow({ t, me, owners, showToast }) {
  const ref = tkRefInfo(t);
  const path = tkTaskPath(t);
  const urg = TK_URGENCY[t.urgency] || TK_URGENCY.week;
  const done = t.state === 'done';
  const open = () => { if (path) navigate(path); };
  const snooze = (until) => {
    const snap = window.E8Store.snapshot('tasks', t.id, ['state', 'snoozedUntil']);
    window.E8Store.set('tasks', t.id, { state: 'snoozed', snoozedUntil: until });
    if (showToast) showToast('Snoozed until ' + until.toLowerCase(), 'Undo', () => window.E8Store.set('tasks', t.id, snap || { state: 'open', snoozedUntil: null }));
  };
  const unsnooze = () => {
    window.E8Store.set('tasks', t.id, { state: 'open', snoozedUntil: null });
    if (showToast) showToast('Back on the queue');
  };
  const reassign = (name) => {
    const snap = window.E8Store.snapshot('tasks', t.id, ['owner']);
    window.E8Store.set('tasks', t.id, { owner: name });
    if (window.E8Audit) window.E8Audit.log({ agent: 'You', prov: 'human', action: 'Reassigned task to ' + name, target: t.title, route: 'tasks' });
    if (showToast) showToast('Reassigned to ' + name, 'Undo', () => window.E8Store.set('tasks', t.id, snap || { owner: t.owner }));
  };
  const menuItems = [];
  if (t.state === 'open') {
    menuItems.push({ header: 'Snooze' });
    menuItems.push({ id: 'sn-tom', icon: 'schedule', label: 'Tomorrow', onClick: () => snooze('Tomorrow') });
    menuItems.push({ id: 'sn-week', icon: 'update', label: 'Next week', onClick: () => snooze('Next week') });
    menuItems.push({ separator: true });
  }
  if (t.state === 'snoozed') {
    menuItems.push({ id: 'unsnooze', icon: 'notifications_active', label: 'Unsnooze now', onClick: unsnooze });
    menuItems.push({ separator: true });
  }
  menuItems.push({ header: 'Reassign to' });
  owners.filter((o) => o !== t.owner).forEach((o) => menuItems.push({ id: 'as-' + o, icon: 'person', label: o, onClick: () => reassign(o) }));
  return (
    <div className={'e8-tk-row' + (done ? ' is-done' : '')}>
      <button type="button" className="e8-tk-check" onClick={() => (done ? tkReopen(t, showToast) : tkComplete(t, showToast))}
        aria-label={done ? 'Reopen task' : 'Mark done'} title={done ? 'Reopen' : 'Mark done'}>
        <span className="material-symbols-outlined">{done ? 'check_circle' : 'radio_button_unchecked'}</span>
      </button>
      <span className={'e8-tk-ic ' + urg.tone}><span className="material-symbols-outlined" aria-hidden="true">{t.icon || TK_KIND_ICON[t.kind] || 'task_alt'}</span></span>
      <div className={'e8-tk-main' + (path ? '' : ' no-link')} onClick={open}
        role={path ? 'button' : undefined} tabIndex={path ? 0 : undefined}
        onKeyDown={(e) => { if (path && (e.key === 'Enter' || e.key === ' ')) { e.preventDefault(); open(); } }}>
        <div className="e8-tk-title">
          {t.title}
          {t.aiAssisted ? <span className="e8-tk-ai" title={t.prov === 'observed' ? 'AI observed this signal' : 'AI teed this up for you'}><span className="material-symbols-outlined" aria-hidden="true">auto_awesome</span></span> : null}
        </div>
        {t.sub ? <div className="e8-tk-sub">{t.sub}</div> : null}
        {(ref || t.owner !== me || t.state === 'snoozed' || (done && t.doneAt)) ? (
          <div className="e8-tk-meta">
            {ref ? (
              <button type="button" className="e8-tk-chip" title={'Open ' + ref.name}
                onClick={(e) => { e.stopPropagation(); navigate(ref.path); }}>
                <span className="material-symbols-outlined" aria-hidden="true">{ref.icon}</span>
                <span className="e8-tk-chip-t">{ref.name}</span>
              </button>
            ) : null}
            {t.owner !== me ? (
              <span className="e8-tk-owner" title={'Owner: ' + t.owner}><DStk.Avatar name={t.owner} size="sm" />{t.owner}</span>
            ) : null}
            {t.state === 'snoozed' ? <span className="e8-tk-note"><span className="material-symbols-outlined" aria-hidden="true">snooze</span>Until {(t.snoozedUntil || 'later').toLowerCase()}</span> : null}
            {done && t.doneAt ? <span className="e8-tk-note"><span className="material-symbols-outlined" aria-hidden="true">check</span>Done {String(t.doneAt).toLowerCase()}</span> : null}
          </div>
        ) : null}
      </div>
      <span style={{ display: 'inline-flex', alignItems: 'center' }}>
        <WorkspacePinButton type="task" id={t.id} compact />
        <DStk.MenuButton items={menuItems} title="Task actions" size="sm" />
      </span>
    </div>
  );
}

/* ---- Grouped section list (urgency bands, matching Today's queue) ---- */
function TkGroups({ tasks, me, owners, showToast }) {
  const groups = ['now', 'today', 'week']
    .map((u) => ({ id: u, ...TK_URGENCY[u], tasks: tasks.filter((t) => t.urgency === u) }))
    .filter((g) => g.tasks.length);
  // Tasks without a recognized urgency still render (defensive - quick-add always sets one).
  const other = tasks.filter((t) => !TK_URGENCY[t.urgency]);
  return (
    <React.Fragment>
      {groups.map((g) => (
        <div key={g.id} className={'e8-tk-group' + (g.id === 'now' ? ' e8-tk-group-now' : '')}>
          <div className="e8-tk-group-h"><span className={'e8-tk-urg ' + g.tone}>{g.label}</span><span className="e8-tk-group-n">{g.tasks.length}</span></div>
          {g.tasks.map((t) => <TkRow key={t.id} t={t} me={me} owners={owners} showToast={showToast} />)}
        </div>
      ))}
      {other.map((t) => <TkRow key={t.id} t={t} me={me} owners={owners} showToast={showToast} />)}
    </React.Fragment>
  );
}

function TasksScreen() {
  const D = window.E8DATA;
  const { showToast } = React.useContext(window.E8Ctx);
  const [, setTick] = React.useState(0);
  React.useEffect(() => (window.E8Events ? window.E8Events.subscribe(['store:changed', 'queue:changed', 'watch:swept'], () => setTick((n) => n + 1)) : undefined), []);
  const [tab, setTab] = React.useState('mine');
  const [title, setTitle] = React.useState('');
  const [urgency, setUrgency] = React.useState('today');
  const addRef = React.useRef(null);

  /* CMDK "New task" lands here: focus the quick-add whether we were mounted or not. */
  React.useEffect(() => {
    const focusAdd = () => { window.__e8TaskAddPending = false; if (addRef.current) { try { addRef.current.focus(); } catch (e) {} } };
    if (window.__e8TaskAddPending) focusAdd();
    window.addEventListener('e8-task-add', focusAdd);
    return () => window.removeEventListener('e8-task-add', focusAdd);
  }, []);

  const me = D.user.name;
  const all = D.tasks || [];
  const mine = all.filter((t) => t.owner === me && t.state === 'open');
  const team = all.filter((t) => t.owner !== me && t.state === 'open');
  const snoozed = all.filter((t) => t.state === 'snoozed');
  const doneRows = all.filter((t) => t.state === 'done');
  const owners = [...new Set([me].concat(all.map((t) => t.owner), (D.jobs || []).map((j) => j.owner)))].filter(Boolean);

  const add = () => {
    const v = title.trim();
    if (!v) return;
    const rec = {
      id: 'tk-' + Date.now().toString(36) + Math.random().toString(36).slice(2, 5),
      title: v, sub: '', kind: 'general', urgency,
      owner: me, state: 'open', snoozedUntil: null, ref: null, route: null,
      aiAssisted: false, prov: null, createdAt: 'Just now', doneAt: null,
    };
    window.E8Store.add('tasks', rec);
    setTitle('');
    if (showToast) showToast('Task added to ' + (TK_URGENCY[urgency] || TK_URGENCY.today).label.toLowerCase(), 'Undo', () => window.E8Store.remove('tasks', rec.id));
  };

  const tabs = [
    { id: 'mine', label: 'My tasks', count: mine.length },
    { id: 'team', label: 'Team', count: team.length },
    { id: 'snoozed', label: 'Snoozed', count: snoozed.length },
    { id: 'done', label: 'Done', count: doneRows.length },
  ];

  const empty = {
    mine: { icon: 'task_alt', title: 'All clear', body: 'Nothing open on your queue. New tasks from Today, records and agents land here.' },
    team: { icon: 'group', title: 'No open team tasks', body: 'Reassign a task to a teammate and it will show up here.' },
    snoozed: { icon: 'snooze', title: 'Nothing snoozed', body: 'Snooze a task for tomorrow or next week from its row menu.' },
    done: { icon: 'check_circle', title: 'Nothing completed yet', body: 'Check a task off here or on Today and it lands in this list.' },
  }[tab];

  let body;
  if (tab === 'mine' && mine.length) body = <TkGroups tasks={mine} me={me} owners={owners} showToast={showToast} />;
  else if (tab === 'team' && team.length) body = <TkGroups tasks={team} me={me} owners={owners} showToast={showToast} />;
  else if (tab === 'snoozed' && snoozed.length) {
    const bands = ['Tomorrow', 'Next week'].map((u) => ({ u, tasks: snoozed.filter((t) => t.snoozedUntil === u) })).filter((b) => b.tasks.length);
    const rest = snoozed.filter((t) => t.snoozedUntil !== 'Tomorrow' && t.snoozedUntil !== 'Next week');
    body = (
      <React.Fragment>
        {bands.map((b) => (
          <div key={b.u} className="e8-tk-group">
            <div className="e8-tk-group-h"><span className="e8-tk-urg neutral">{b.u}</span><span className="e8-tk-group-n">{b.tasks.length}</span></div>
            {b.tasks.map((t) => <TkRow key={t.id} t={t} me={me} owners={owners} showToast={showToast} />)}
          </div>
        ))}
        {rest.map((t) => <TkRow key={t.id} t={t} me={me} owners={owners} showToast={showToast} />)}
      </React.Fragment>
    );
  } else if (tab === 'done' && doneRows.length) {
    body = doneRows.map((t) => <TkRow key={t.id} t={t} me={me} owners={owners} showToast={showToast} />);
  } else {
    body = <div style={{ maxWidth: 460, margin: '32px auto' }}><DStk.EmptyState icon={empty.icon} title={empty.title} body={empty.body} /></div>;
  }

  return (
    <React.Fragment>
      <Topbar crumbs={[{ label: 'Tasks' }]} />
      <div className="e8-content">
        <div className="e8-page e8-tk-page">
          <PageHead title="Tasks" sub="One queue across Today, records and agents - yours by default" />
          <TkNeedsReview />
          <div className="e8-tk-bar">
            <DStk.SubTabs items={tabs} active={tab} onChange={setTab} />
            <div className="e8-tk-add">
              <div className="e8-input-wrap e8-tk-add-input">
                <span className="material-symbols-outlined" aria-hidden="true">add_task</span>
                <input ref={addRef} placeholder="Add a task…" value={title} aria-label="New task title"
                  onChange={(e) => setTitle(e.target.value)}
                  onKeyDown={(e) => { if (e.key === 'Enter') add(); }} />
              </div>
              <DStk.Select aria-label="Urgency" value={urgency} onChange={(e) => setUrgency(e.target.value)}
                options={[{ value: 'now', label: 'Right now' }, { value: 'today', label: 'Today' }, { value: 'week', label: 'This week' }]} />
              <DStk.Button variant="primary" size="sm" icon="add" onClick={add} disabled={!title.trim()}>Add</DStk.Button>
            </div>
          </div>
          <div className="e8-tk-board">{body}</div>
        </div>
      </div>
    </React.Fragment>
  );
}

/* ---- Record task rail (R98 Task 5): a compact, additive block for any record detail rail.
   Lists the open `tasks` whose ref = { type, id } matches this record, with inline complete
   (undo toast via tkComplete) and a one-field quick-add that stamps ref + owner from context.
   Reuses the .e8-tk-check checkbox; own layout via .e8-rtk-* (grepped unique before adding). ---- */
function RecordTasksRail({ refType, refId, title }) {
  const { showToast } = React.useContext(window.E8Ctx);
  const [, setTick] = React.useState(0);
  React.useEffect(() => (window.E8Events ? window.E8Events.subscribe(['store:changed'], () => setTick((n) => n + 1)) : undefined), []);
  const D = window.E8DATA || {};
  const me = (D.user || {}).name;
  const open = (D.tasks || []).filter((t) => t.ref && t.ref.type === refType && t.ref.id === refId && t.state === 'open');
  const [text, setText] = React.useState('');
  const add = () => {
    const v = text.trim();
    if (!v) return;
    const rec = {
      id: 'tk-' + Date.now().toString(36) + Math.random().toString(36).slice(2, 5),
      title: v, sub: '', kind: 'general', urgency: 'today',
      owner: me, state: 'open', snoozedUntil: null, ref: { type: refType, id: refId }, route: null,
      aiAssisted: false, prov: null, createdAt: 'Just now', doneAt: null,
    };
    window.E8Store.add('tasks', rec);
    setText('');
    if (window.E8Audit) window.E8Audit.log({ agent: 'You', prov: 'human', action: 'Added task', target: v, route: 'tasks' });
    if (showToast) showToast('Task added', 'Undo', () => window.E8Store.remove('tasks', rec.id));
  };
  return (
    <div className="e8-rail-block e8-rtk">
      <div className="e8-rail-title" style={{ display: 'flex', alignItems: 'center', gap: 7 }}>
        {title || 'Tasks'} {open.length ? <span className="e8-rail-count">{open.length}</span> : null}
      </div>
      <div className="e8-rtk-list">
        {open.length ? open.map((t) => {
          const urg = TK_URGENCY[t.urgency] || TK_URGENCY.week;
          return (
            <div key={t.id} className="e8-rtk-row">
              <button type="button" className="e8-tk-check e8-rtk-check" onClick={() => tkComplete(t, showToast)} aria-label="Mark done" title="Mark done">
                <span className="material-symbols-outlined">radio_button_unchecked</span>
              </button>
              <div className="e8-rtk-main">
                <div className="e8-rtk-title">{t.title}{t.aiAssisted ? <span className="e8-tk-ai" title="AI teed this up"><span className="material-symbols-outlined" aria-hidden="true">auto_awesome</span></span> : null}</div>
                <div className="e8-rtk-meta">
                  <span className={'e8-rtk-urg ' + urg.tone}>{urg.label}</span>
                  {t.owner && t.owner !== me ? <span className="e8-rtk-owner"><DStk.Avatar name={t.owner} size="sm" />{t.owner}</span> : null}
                </div>
              </div>
            </div>
          );
        }) : <div className="e8-rtk-empty">No open tasks on this record.</div>}
      </div>
      <div className="e8-rtk-add">
        <input className="e8-rtk-input" placeholder="Add a task…" value={text} aria-label="Add a task to this record"
          onChange={(e) => setText(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') add(); }} />
        <button type="button" className="e8-rtk-addbtn" onClick={add} disabled={!text.trim()} aria-label="Add task" title="Add task">
          <span className="material-symbols-outlined">add</span>
        </button>
      </div>
    </div>
  );
}

Object.assign(window, { TasksScreen, tkTaskPath, tkRefInfo, tkComplete, tkReopen, TK_KIND_ICON, RecordTasksRail });
