// Tasks — AI-detected commitments + manual to-dos.
// Richer than a flat list: each task carries an action-items checklist with live
// progress, a due date, AI provenance, and a one-tap suggested action. The editor
// is a slide-in drawer (not a generic centered modal).

const TASK_TYPES = [['Follow Up','purple'],['Commitment','blue'],['Reminder','gold'],['To-do','teal']];
const PRIO_TINT = { High:'red', Medium:'gold', Low:'green' };
const TODAY_ISO = new Date().toISOString().slice(0, 10);
const MONTHS = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
function fmtDue(d) { return `${MONTHS[d.getMonth()]} ${d.getDate()}`; }
function isoFrom(d) { return d.toISOString().slice(0, 10); }
function relDue(days) { const d = new Date(); d.setDate(d.getDate() + days); return { dueISO: isoFrom(d), due: fmtDue(d) }; }
const subPct = t => { const s = t.subtasks || []; return s.length ? Math.round(s.filter(x => x.done).length / s.length * 100) : 0; };

// ---- reply helpers ----
const isEmailTask = t => !!(t && t.source && /email/i.test(t.source));
const cap = s => s ? s.charAt(0).toUpperCase() + s.slice(1) : s;
const lcFirst = s => s ? s.charAt(0).toLowerCase() + s.slice(1) : s;
// The person/thread the task came from -> a plausible address to reply to.
function senderFrom(source) {
  const name = (String(source || '').split('·')[0] || 'Sender').trim() || 'Sender';
  const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, '.').replace(/^\.|\.$/g, '') || 'sender';
  return { name, addr: `${slug}@email.com` };
}
// Subject derived from the task title.
function subjectFrom(t) {
  const title = String(t.title || '');
  const m = /about (.+)/i.exec(title) || /(?:reply to|re:)\s*(.+)/i.exec(title);
  return cap(m ? m[1] : title);
}
// Zeranda's drafted reply body — contextual, editable once generated.
function aiDraft(t) {
  const first = senderFrom(t.source).name.split(' ')[0];
  const subj = lcFirst(subjectFrom(t));
  const when = t.due ? `I'll have everything wrapped up ahead of ${t.due}` : 'I\u2019m getting on it right away';
  return (
`Hi ${first},

Thanks for your email about ${subj}. I wanted to confirm I\u2019ve received it and I\u2019m taking care of it \u2014 ${when}.

Please let me know if there\u2019s anything else you need from me in the meantime.

Best regards,
Alex`);
}

// ---- progress ring ----
function Ring({ pct, size = 18, stroke = 3, color = 'var(--green-500)' }) {
  const r = (size - stroke) / 2, c = 2 * Math.PI * r;
  return (
    <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`} style={{ transform:'rotate(-90deg)', flex:'none' }}>
      <circle cx={size/2} cy={size/2} r={r} fill="none" stroke="var(--surface-sunk)" strokeWidth={stroke} />
      <circle cx={size/2} cy={size/2} r={r} fill="none" stroke={color} strokeWidth={stroke} strokeLinecap="round"
        strokeDasharray={`${c * pct / 100} ${c}`} />
    </svg>
  );
}

// ---- list card ----
function TaskItem({ t, done, onToggle, onOpen, onReply }) {
  const subs = t.subtasks || [];
  const total = subs.length, dn = subs.filter(s => s.done).length;
  const pct = done ? 100 : subPct(t);
  const overdue = !done && t.dueISO && t.dueISO < TODAY_ISO;
  // Surface the single most important actionable thing on the row: the next
  // unchecked step, falling back to Zeranda's suggested action, then a note peek.
  const nextStep = subs.find(s => !s.done);
  const nextLabel = nextStep ? nextStep.label : (t.action || '');
  const allDone = total > 0 && dn === total;
  return (
    <div className={`taskrow ${done ? 'done' : ''}`} onClick={onOpen} style={{ cursor:'pointer' }}>
      <div className={`tcheck ${done ? 'on' : ''}`} onClick={e => { e.stopPropagation(); onToggle(); }} title="Mark complete"><Icon name="check" size={14} color="#fff" /></div>
      <div className="body">
        <div className="head">
          <span className="ttl">{t.title}</span>
          <span className={`pill b-${t.prioTint}`}>{t.prio}</span>
        </div>
        {!done && nextLabel && (
          <div className="task-next" title={nextLabel}>
            <span className="nx-lbl">{nextStep ? 'Next step' : 'Suggested'}</span>
            <span className="nx-txt">{nextLabel}</span>
          </div>
        )}
        {!done && !nextLabel && allDone && (
          <div className="task-next ready"><Icon name="check-circle-2" size={14} /><span className="nx-txt">All steps done — ready to complete</span></div>
        )}
        {!done && !nextLabel && total === 0 && t.ctx && (
          <div className="task-next note" title={t.ctx}><Icon name="sticky-note" size={13} /><span className="nx-txt">{t.ctx}</span></div>
        )}
        <div className="task-meta">
          <span className={`pill b-${t.typeTint}`}>{t.type}</span>
          {t.due && <span className={`task-due ${overdue ? 'over' : ''}`}><Icon name="calendar" size={13} /> {overdue ? 'Overdue · ' : ''}{t.due}</span>}
          {total > 0 && <span className="task-prog"><Ring pct={pct} size={16} /> {dn}/{total} steps</span>}
          {t.source && <span className="task-src"><Icon name="sparkles" size={12} /> {t.source}</span>}
          {t.source && /email/i.test(t.source) && <MailboxBadge addr={mailboxFor(t)} variant="mini" />}
        </div>
      </div>
      <div className="actions" onClick={e => e.stopPropagation()}>
        {!done && isEmailTask(t) && (
          <button className="reply-btn" onClick={onReply} title={`Reply to ${senderFrom(t.source).name}`}>
            <Icon name="corner-up-left" size={14} /> Reply
          </button>
        )}
        <button className="iconbtn" onClick={onOpen} title="Edit task"><Icon name="pencil" size={16} /></button>
        {!done && <button className="iconbtn" onClick={onToggle} title="Complete"><Icon name="check-circle-2" size={17} /></button>}
      </div>
    </div>
  );
}

// ---- editor drawer ----
function TaskDrawer({ task, creating, onClose, onSave, onDelete }) {
  const [form, setForm] = useState(task);
  const [newSub, setNewSub] = useState('');
  const [confirmDismiss, setConfirmDismiss] = useState(false);
  const [mailSent, setMailSent] = useState(false);
  useEffect(() => { setForm(task); setNewSub(''); setConfirmDismiss(false); setMailSent(false); }, [task]);
  const perm = usePermissions();
  const canSend = perm.has('send');                 // sending replies access granted?
  const [showReconnect, setShowReconnect] = useState(false);
  const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
  const subs = form.subtasks || [];
  const dn = subs.filter(s => s.done).length;
  const pct = subs.length ? Math.round(dn / subs.length * 100) : 0;

  const addSub = (label) => { const l = (label ?? newSub).trim(); if (!l) return; set('subtasks', [...subs, { id:'s' + Date.now() + Math.random().toString(36).slice(2,5), label:l, done:false }]); setNewSub(''); };
  const toggleSub = id => set('subtasks', subs.map(s => s.id === id ? { ...s, done: !s.done } : s));
  const delSub = id => set('subtasks', subs.filter(s => s.id !== id));
  const setDue = ({ dueISO, due }) => setForm(f => ({ ...f, dueISO, due }));
  const clearDue = () => setForm(f => ({ ...f, dueISO:'', due:'' }));

  const valid = String(form.title || '').trim();
  const save = () => { const tt = TASK_TYPES.find(([l]) => l === form.type) || TASK_TYPES[0];
    onSave({ ...form, typeTint: tt[1], prioTint: PRIO_TINT[form.prio] || 'gold' }); };
  // "Send email" only makes sense for items Zeranda pulled from an email thread
  const isEmail = /email/i.test(form.source || '');
  const sendMail = () => { setMailSent(true); setTimeout(() => setMailSent(false), 2400); };

  return (
    <React.Fragment>
      <div className="scrim" onClick={onClose} />
      <div className="drawer zd-scroll">
        <div className="dhead">
          <IconChip icon="check-square" tint={form.typeTint || 'purple'} size={40} radius={12} />
          <div style={{ flex:1, minWidth:0 }}>
            <div style={{ fontFamily:'var(--font-display)', fontWeight:700, fontSize:18 }}>{creating ? 'New task' : 'Task'}</div>
            <div style={{ fontSize:12.5, color:'var(--fg-3)' }}>{creating ? 'Capture a to-do or commitment' : (form.source || 'Personal task')}</div>
          </div>
          <button className="iconbtn" onClick={onClose}><Icon name="x" size={18} /></button>
        </div>
        <div className="dbody">
          <label className="fl">Task</label>
          <div className="finput"><Icon name="check-square" size={16} color="var(--fg-4)" /><input value={form.title || ''} onChange={e => set('title', e.target.value)} placeholder="What needs doing?" /></div>

          <div className="drow">
            <div style={{ flex:1 }}><label className="fl">Type</label>
              <Dropdown value={form.type} options={TASK_TYPES.map(([l]) => ({ value:l, label:l }))} onChange={v => set('type', v)} minWidth={'100%'} icon="tag" />
            </div>
            <div style={{ flex:1 }}><label className="fl">Priority</label>
              <Dropdown value={form.prio} options={['High','Medium','Low'].map(p => ({ value:p, label:p, tint:PRIO_TINT[p] }))} onChange={v => set('prio', v)} minWidth={'100%'} />
            </div>
          </div>

          <label className="fl">Due date</label>
          <div className="due-chips">
            <button className={form.dueISO === relDue(0).dueISO ? 'on' : ''} onClick={() => setDue(relDue(0))}>Today</button>
            <button className={form.dueISO === relDue(1).dueISO ? 'on' : ''} onClick={() => setDue(relDue(1))}>Tomorrow</button>
            <button className={form.dueISO === relDue(7).dueISO ? 'on' : ''} onClick={() => setDue(relDue(7))}>Next week</button>
            <div className="finput due-input"><Icon name="calendar" size={15} color="var(--fg-4)" /><input type="date" value={form.dueISO || ''} onChange={e => setDue({ dueISO:e.target.value, due: e.target.value ? fmtDue(new Date(e.target.value)) : '' })} /></div>
            {form.dueISO && <button className="iconbtn" onClick={clearDue} title="Clear"><Icon name="x" size={15} /></button>}
          </div>

          {/* action items / subtasks */}
          <div className="subt-head">
            <label className="fl" style={{ margin:0 }}>Action items</label>
            {subs.length > 0 && <span className="subt-prog"><Ring pct={pct} size={16} /> {dn}/{subs.length} done</span>}
          </div>
          {subs.length > 0 && <div className="subt-bar"><div className="fill" style={{ width:`${pct}%` }} /></div>}
          <div className="subt-list">
            {subs.map(s => (
              <div className={`subt-row ${s.done ? 'done' : ''}`} key={s.id}>
                <button className={`subt-check ${s.done ? 'on' : ''}`} onClick={() => toggleSub(s.id)}><Icon name="check" size={12} color="#fff" /></button>
                <span className="subt-lbl">{s.label}</span>
                <button className="iconbtn" onClick={() => delSub(s.id)} title="Remove"><Icon name="x" size={14} /></button>
              </div>
            ))}
            <div className="subt-add">
              <Icon name="plus" size={15} color="var(--fg-4)" />
              <input value={newSub} onChange={e => setNewSub(e.target.value)} onKeyDown={e => e.key === 'Enter' && addSub()} placeholder="Add a step…" />
              {newSub.trim() && <button className="link-btn" onClick={() => addSub()}>Add</button>}
            </div>
          </div>

          {/* AI suggestion */}
          {form.action && (
            <div className="ai-suggest">
              <div className="ai-s-top"><Icon name="sparkles" size={15} color="var(--gold-600)" /> Suggested by Zeranda</div>
              <div className="ai-s-body">{form.action}</div>
              <div className="ai-s-acts">
                <button className="link-btn" onClick={() => addSub(form.action)}><Icon name="plus" size={13} /> Add as step</button>
                {form.source && <button className="link-btn muted"><Icon name="external-link" size={13} /> View source</button>}
              </div>
            </div>
          )}

          <label className="fl">Notes</label>
          <textarea className="fld" value={form.ctx || ''} onChange={e => set('ctx', e.target.value)} placeholder="Context or background" />

          <div className="task-foot">
            {!creating && (confirmDismiss ? (
              <div className="foot-confirm">
                <span className="fc-q"><Icon name="alert-circle" size={15} color="var(--red-600)" /> Remove this — it isn’t a task?</span>
                <div className="fc-btns">
                  <button className="footact danger" onClick={() => onDelete(form.id)}><Icon name="trash-2" size={15} /> Remove</button>
                  <button className="footact" onClick={() => setConfirmDismiss(false)}>Keep it</button>
                </div>
              </div>
            ) : (
              <div className="task-foot-actions">
                {isEmail && (canSend ? (
                  <button className={`footact ${mailSent ? 'ok' : ''}`} disabled={mailSent} onClick={sendMail}
                    title={`Reply to the source email · ${form.source}`}>
                    <Icon name={mailSent ? 'check' : 'mail'} size={16} />{mailSent ? 'Email sent' : 'Send email'}
                  </button>
                ) : (
                  <button className="footact warn" onClick={() => setShowReconnect(true)} title="Reconnect to turn on sending">
                    <Icon name="refresh-cw" size={16} /> Reconnect to send
                  </button>
                ))}
                <button className="footact danger" onClick={() => setConfirmDismiss(true)} title="Dismiss — this isn’t a task">
                  <Icon name="ban" size={16} /> Not a task
                </button>
              </div>
            ))}
            <div className="task-foot-primary">
              <Btn variant="ghost" onClick={onClose}>Cancel</Btn>
              <button className="btn btn-primary" style={{ flex:1, justifyContent:'center', opacity: valid ? 1 : .5, pointerEvents: valid ? 'auto' : 'none' }} onClick={save}>
                <Icon name="check" size={16} />{creating ? 'Add task' : 'Save changes'}
              </button>
            </div>
          </div>
        </div>
      </div>
      {showReconnect && perm.primary() && <ReconnectModal account={perm.primary()} highlight={['send']} reason="so Zeranda can send replies"
        onClose={() => setShowReconnect(false)} onDone={() => setShowReconnect(false)} />}
    </React.Fragment>
  );
}

// ---- reply composer (centered popup) ----
// Reachable straight from the task row for email-sourced tasks — no need to open
// the editor first. Reply to the source thread, let Zeranda draft the body, edit, send.
function ReplyComposer({ task, onClose, onSent }) {
  const fromAddr = mailboxFor(task);
  const sender = senderFrom(task.source);
  const [subject, setSubject] = useState('Re: ' + subjectFrom(task));
  const [body, setBody] = useState('');
  const [phase, setPhase] = useState('idle'); // idle | drafting | drafted | sending | sent
  const typingRef = useRef(null);
  useEffect(() => () => clearTimeout(typingRef.current), []);
  const perm = usePermissions();
  const canSend = perm.has('send');
  const [showReconnect, setShowReconnect] = useState(false);

  const draft = () => {
    clearTimeout(typingRef.current);
    setPhase('drafting'); setBody('');
    const full = aiDraft(task);
    const step = Math.max(6, Math.round(full.length / 14));
    let i = 0;
    const type = () => {
      i = Math.min(full.length, i + step);
      setBody(full.slice(0, i));
      if (i < full.length) typingRef.current = setTimeout(type, 32);
      else setPhase('drafted');
    };
    typingRef.current = setTimeout(type, 260);
  };
  const send = () => {
    if (!canSend) { setShowReconnect(true); return; }
    setPhase('sending');
    setTimeout(() => { setPhase('sent'); onSent && onSent(task); }, 750);
    setTimeout(onClose, 2050);
  };
  const busy = phase === 'drafting' || phase === 'sending';

  return (
    <React.Fragment>
    <div className="modal-scrim" onClick={busy ? undefined : onClose}>
      <div className="modal reply-modal zd-scroll" onClick={e => e.stopPropagation()}>
        <button className="modal-x" onClick={onClose} aria-label="Close"><Icon name="x" size={18} /></button>
        {phase === 'sent' ? (
          <div style={{ padding:'54px 28px', textAlign:'center' }}>
            <span style={{ width:62, height:62, borderRadius:'50%', background:'var(--green-50)', display:'grid', placeItems:'center', margin:'0 auto 16px' }}>
              <Icon name="send" size={26} color="var(--green-600)" />
            </span>
            <div style={{ fontFamily:'var(--font-display)', fontWeight:700, fontSize:21 }}>Reply sent</div>
            <div style={{ fontSize:14, color:'var(--fg-2)', marginTop:6 }}>Your reply to {sender.name} is on its way from {mailboxMeta(fromAddr).label}.</div>
          </div>
        ) : (
          <React.Fragment>
            <div className="modal-body">
              <span className="modal-badge reply-badge"><Icon name="corner-up-left" size={13} color="var(--gold-700)" /> Reply · email</span>
              <h3>Reply to {sender.name}</h3>
              <div className="msub">Replying to the email Zeranda detected this task from.</div>

              {!canSend && (
                <AccessNotice variant="panel" icon="send"
                  title="Reconnect to send replies"
                  ctaLabel="Reconnect to send"
                  onCta={() => setShowReconnect(true)}>
                  Zeranda can still draft this for you below — reconnect your inbox to turn on sending so you can send it from here.
                </AccessNotice>
              )}

              <div className="reply-head">
                <div className="reply-fld">
                  <span className="rf-k">To</span>
                  <span className="rf-v"><span className="rf-name">{sender.name}</span><span className="rf-addr">{sender.addr}</span></span>
                </div>
                <div className="reply-fld">
                  <span className="rf-k">From</span>
                  <span className="rf-v"><MailboxBadge addr={fromAddr} variant="mini" /><span className="rf-addr">{fromAddr}</span></span>
                </div>
                <div className="reply-fld">
                  <span className="rf-k">Subject</span>
                  <input className="rf-input" value={subject} onChange={e => setSubject(e.target.value)} />
                </div>
              </div>

              <div className="reply-body-wrap">
                <textarea className="reply-body" value={body} onChange={e => { setBody(e.target.value); if (phase === 'idle') setPhase('drafted'); }}
                  placeholder="Write your reply, or let Zeranda draft it for you…" readOnly={phase === 'drafting'} />
                {phase === 'idle' && !body && (
                  <button className="ai-draft-cta" onClick={draft}>
                    <Icon name="sparkles" size={18} color="var(--gold-700)" />
                    <span className="adc-t">Draft this reply with AI</span>
                    <span className="adc-s">Zeranda writes a first draft from the email — you can edit before sending</span>
                  </button>
                )}
                {phase === 'drafting' && (
                  <div className="ai-drafting"><span className="ai-dot" /><span className="ai-dot" /><span className="ai-dot" /> Zeranda is writing…</div>
                )}
              </div>
            </div>
            <div className="modal-foot reply-foot">
              <button className="ai-btn" onClick={draft} disabled={busy}>
                <Icon name="sparkles" size={15} /> {body ? 'Rewrite with AI' : 'Draft with AI'}
              </button>
              <div className="reply-foot-r">
                <button className="btn btn-ghost" onClick={onClose} disabled={busy}>Cancel</button>
                <button className="btn btn-primary" disabled={!body.trim() || busy || !canSend} title={!canSend ? 'Reconnect to enable sending' : undefined} onClick={send}>
                  <Icon name="send" size={15} /> {phase === 'sending' ? 'Sending…' : 'Send reply'}
                </button>
              </div>
            </div>
          </React.Fragment>
        )}
      </div>
    </div>
    {showReconnect && perm.primary() && <ReconnectModal account={perm.primary()} highlight={['send']} reason="so Zeranda can send replies"
      onClose={() => setShowReconnect(false)} onDone={() => setShowReconnect(false)} />}
    </React.Fragment>
  );
}

function Tasks() {
  const D = window.ZD_DATA;
  const [tasks, setTasks] = useState(D.tasks);
  const [doneIds, setDone] = useState(new Set());
  const [tab, setTab] = useState('pending');
  const [q, setQ] = useState('');
  const [sel, setSel] = useState(null);       // task being edited
  const [creating, setCreating] = useState(false);
  const [replyTask, setReplyTask] = useState(null);  // task being replied to

  const blank = () => ({ id:'t' + Date.now(), title:'', type:'To-do', typeTint:'teal', prio:'Medium', prioTint:'gold',
    due:'', dueISO:'', source:'', ctx:'', action:'', subtasks:[] });
  const openNew = () => { setSel(blank()); setCreating(true); };
  useCreateShortcut(openNew);

  const toggle = id => setDone(prev => { const n = new Set(prev); n.has(id) ? n.delete(id) : n.add(id); return n; });
  const saveTask = upd => {
    setTasks(list => list.some(t => t.id === upd.id) ? list.map(t => t.id === upd.id ? upd : t) : [upd, ...list]);
    setSel(null); setCreating(false);
  };
  const delTask = id => { setTasks(list => list.filter(t => t.id !== id)); setSel(null); setCreating(false); };

  const pending = tasks.filter(t => !doneIds.has(t.id));
  const completed = tasks.filter(t => doneIds.has(t.id));
  const dueToday = pending.filter(t => t.dueISO === TODAY_ISO || (t.dueISO && t.dueISO < TODAY_ISO)).length;
  const list = (tab === 'pending' ? pending : tab === 'completed' ? completed : tasks)
    .filter(t => t.title.toLowerCase().includes(q.toLowerCase()));

  return (
    <div className="screen-inner">
      <div className="statrow">
        <StatCard label="Pending tasks" value={pending.length} sub="Active tasks" icon="check-square" tint="purple" />
        <StatCard label="Due / overdue" value={dueToday} sub={dueToday ? 'Needs attention' : 'Nothing due'} icon="calendar-clock" tint={dueToday ? 'gold' : 'green'} />
        <StatCard label="Completed" value={completed.length} sub="This session" icon="check-circle-2" tint="green" />
      </div>

      <div className="card card-pad rise">
        <SectionHeader title="Tasks" sub="AI-detected commitments and manual to-dos" actionEl={<Btn variant="primary" icon="plus" kbd="C" title="New task — press C" onClick={openNew}>New task</Btn>} />
        <div className="search" style={{ margin:'4px 0 14px' }}><Icon name="search" size={17} /><input placeholder="Search tasks…" value={q} onChange={e => setQ(e.target.value)} /></div>
        <div className="tabs" style={{ marginBottom:16 }}>
          {[['pending','Pending',pending.length],['completed','Completed',completed.length],['all','All',tasks.length]].map(([id,lbl,c]) => (
            <button key={id} className={tab === id ? 'on' : ''} onClick={() => setTab(id)}>{lbl} <span className="tab-n">{c}</span></button>
          ))}
        </div>
        {list.map(t => (
          <TaskItem key={t.id} t={t} done={doneIds.has(t.id)} onToggle={() => toggle(t.id)} onOpen={() => { setSel(t); setCreating(false); }} onReply={() => setReplyTask(t)} />
        ))}
        {list.length === 0 && <div style={{ textAlign:'center', color:'var(--fg-3)', padding:'40px 0' }}>
          <Icon name="check-circle-2" size={30} color="var(--green-500)" /><div style={{ marginTop:8 }}>You're all caught up.</div>
        </div>}
      </div>

      {sel && <TaskDrawer task={sel} creating={creating} onClose={() => { setSel(null); setCreating(false); }} onSave={saveTask} onDelete={delTask} />}
      {replyTask && <ReplyComposer task={replyTask} onClose={() => setReplyTask(null)} onSent={(t) => {
        // reflect the sent reply on the task: tick off any reply/send action items
        setTasks(list => list.map(x => x.id === t.id ? { ...x, subtasks: (x.subtasks || []).map(s => /repl|send|email/i.test(s.label) ? { ...s, done:true } : s) } : x));
      }} />}
    </div>
  );
}
window.Tasks = Tasks;
