// tasks.jsx — module Công việc (Tasks): overview · bảng Kanban · danh sách · cài đặt
// + widget không gắn dashboard (theo yêu cầu dashboard gọn). Mock state qua PortalContext.
const TASK_APP = APPS.find(a => a.id === 'tasks');

function tCustName(code){ const c = (window.CustomerStore && CustomerStore.byCode(code)) || null; return c ? (c.shortName || c.name) : ''; }
function tCountBy(arr, key){ const m = {}; arr.forEach(x => { const k = key(x); m[k] = (m[k] || 0) + 1; }); return m; }

function TaskModule(){
  const p = usePortal();
  const { t } = useLang();
  const sub = p.route.sub || 'overview';
  const items = [
    { id:'overview', icon:'bi-pie-chart', label:t('c.overview') },
    { id:'board', icon:'bi-kanban', label:t('tk.board') },
    { id:'list', icon:'bi-list-ul', label:t('c.list'), count:p.tasks.length },
    { id:'settings', icon:'bi-gear', label:t('c.settings') },
  ];
  const go = (id) => p.navigate({ name:'module', module:'tasks', sub:id });
  return (<>
    <ModuleSidebar app={TASK_APP} items={items} active={sub} onNavigate={go} />
    <main className="main">
      {sub === 'overview' && <TaskOverview go={go} />}
      {sub === 'board' && <TaskBoard />}
      {sub === 'list' && <TaskList go={go} />}
      {sub === 'help' && <ModuleHelp moduleId="tasks" app={TASK_APP} />}
      {sub === 'settings' && <TaskSettings />}
    </main>
  </>);
}

function TaskPriBadge({ pr }){ const { lang } = useLang(); const x = TASK_PRIORITY[pr] || TASK_PRIORITY.low; return <span className={'badge ' + x.cls}>{x[lang] || x.vi}</span>; }
function TaskStatusBadge({ st }){ const { lang } = useLang(); const x = TASK_STATUS[st] || TASK_STATUS.todo; return <span className={'badge ' + x.cls}><i className={'bi ' + x.icon}></i>{x[lang] || x.vi}</span>; }
function TaskDue({ task }){ const { lang } = useLang(); const od = taskOverdue(task); return <span className="mono" style={{ fontSize:'var(--fs-base)', color:od ? 'var(--error)' : 'var(--text-muted)', fontWeight:od ? 600 : 400 }}>{od && <i className="bi bi-exclamation-circle" style={{ marginRight:3 }}></i>}{task.dueDate ? fmtDate(task.dueDate) : '—'}</span>; }

/* ---------- Overview ---------- */
function TaskOverview({ go }){
  const p = usePortal();
  const { t, lang } = useLang();
  const ts = p.tasks;
  const open = ts.filter(taskOpen);
  const overdue = ts.filter(taskOverdue);
  const byPrio = tCountBy(ts, x => x.priority);
  const byAssignee = tCountBy(ts, x => x.assignee);
  const colors = ['var(--error)','var(--warning)','var(--gray-400)'];
  const upcoming = open.slice().sort((a, b) => (a.dueDate || '') < (b.dueDate || '') ? -1 : 1).slice(0, 8);
  return (
    <div className="page pagefade">
      <div className="page-head"><div><h1>{t('nav.tasks')}</h1><div className="sub">{lang === 'vi' ? 'Tổng quan công việc cần làm.' : 'Work & task overview.'}</div></div>
        <button className="btn btn-primary" onClick={() => p.quick('tasks')}><i className="bi bi-plus-lg"></i>{t('tk.new')}</button></div>
      <div className="kpi-strip">
        <Kpi label={lang === 'vi' ? 'Tổng công việc' : 'Total'} value={ts.length} icon="bi-check2-square" />
        <Kpi label={TASK_STATUS.todo[lang]} value={ts.filter(x => x.status === 'todo').length} icon="bi-circle" />
        <Kpi label={TASK_STATUS.doing[lang]} value={ts.filter(x => x.status === 'doing').length} icon="bi-arrow-repeat" />
        <Kpi label={lang === 'vi' ? 'Quá hạn' : 'Overdue'} value={overdue.length} icon="bi-exclamation-circle" />
      </div>
      <div className="dash-grid">
        <div className="card"><div className="card-head"><h3>{t('tk.priority')}</h3></div><div className="card-body">
          <DistribBars rows={['high','med','low'].map((k, i) => ({ label:TASK_PRIORITY[k][lang], value:byPrio[k] || 0, color:colors[i] }))} />
        </div></div>
        <div className="card span2"><div className="card-head"><h3>{lang === 'vi' ? 'Theo người phụ trách' : 'By assignee'}</h3></div><div className="card-body">
          <DistribBars rows={Object.entries(byAssignee).sort((a, b) => b[1] - a[1]).map(([k, v]) => ({ label:k, value:v, color:'var(--primary)' }))} />
        </div></div>
      </div>
      <div className="card" style={{ marginTop:14 }}>
        <div className="card-head"><h3>{t('tk.upcoming')}</h3><button className="btn btn-ghost btn-sm" onClick={() => go('list')}>{t('c.viewAll')}</button></div>
        <div className="card-body" style={{ paddingTop:6 }}>
          {upcoming.length === 0 && <EmptyState icon="bi-check2-all" text={lang === 'vi' ? 'Không có việc đang mở' : 'No open tasks'} />}
          {upcoming.map(tsk => (
            <div key={tsk.id} className="recent-row is-link" onClick={() => go('list')}>
              <span className="recent-ic" style={{ color:(TASK_PRIORITY[tsk.priority] || {}).color }}><i className={'bi ' + (TASK_STATUS[tsk.status] || {}).icon}></i></span>
              <div className="grow" style={{ minWidth:0 }}>
                <div className="truncate" style={{ fontWeight:500 }}>{tsk.title}</div>
                <div className="subtle truncate" style={{ fontSize:'var(--fs-sm)' }}>{tsk.assignee}{tsk.customer ? ' · ' + tCustName(tsk.customer) : ''}</div>
              </div>
              <TaskDue task={tsk} />
            </div>
          ))}
        </div>
      </div>
    </div>
  );
}

/* ---------- Board (Kanban) ---------- */
function TaskBoard(){
  const p = usePortal();
  const { t, lang } = useLang();
  const ts = p.tasks;
  const advance = (tsk, e) => { e.stopPropagation(); const i = TASK_STATUS_FLOW.indexOf(tsk.status); const next = TASK_STATUS_FLOW[Math.min(i + 1, TASK_STATUS_FLOW.length - 1)]; p.updateTask(tsk.id, { status:next }); };
  return (
    <div className="page pagefade">
      <div className="page-head"><div><h1>{t('tk.board')}</h1><div className="sub">{lang === 'vi' ? 'Kéo công việc qua các giai đoạn (bấm › để chuyển).' : 'Move tasks across stages.'}</div></div>
        <button className="btn btn-primary" onClick={() => p.quick('tasks')}><i className="bi bi-plus-lg"></i>{t('tk.new')}</button></div>
      <div className="task-board">
        {TASK_STATUS_FLOW.map(col => {
          const list = ts.filter(x => x.status === col);
          return (
            <div key={col} className="task-col">
              <div className="task-col-head"><span className="flex g8 items-center"><i className={'bi ' + TASK_STATUS[col].icon}></i>{TASK_STATUS[col][lang]}</span><span className="ncount">{list.length}</span></div>
              <div className="task-col-body">
                {list.length === 0 && <div className="subtle" style={{ fontSize:'var(--fs-base)', textAlign:'center', padding:'10px 0' }}>—</div>}
                {list.map(tsk => (
                  <div key={tsk.id} className="task-card" onClick={() => p.quick('tasks', tsk)}>
                    <div className="flex justify-between items-center g8">
                      <TaskPriBadge pr={tsk.priority} />
                      {col !== 'done' && <button className="iconbtn" style={{ width:22, height:22 }} title={lang === 'vi' ? 'Chuyển giai đoạn' : 'Advance'} onClick={(e) => advance(tsk, e)}><i className="bi bi-chevron-right" style={{ fontSize:12 }}></i></button>}
                    </div>
                    <div style={{ fontWeight:500, fontSize:'var(--fs-md)', margin:'6px 0' }}>{tsk.title}</div>
                    <div className="flex justify-between items-center" style={{ fontSize:'var(--fs-base)' }}>
                      <span className="flex g4 items-center subtle"><Avatar name={tsk.assignee} size={18} /><span className="truncate" style={{ maxWidth:90 }}>{tsk.assignee}</span></span>
                      <TaskDue task={tsk} />
                    </div>
                  </div>
                ))}
              </div>
            </div>
          );
        })}
      </div>
    </div>
  );
}

/* ---------- List ---------- */
function TaskList({ go }){
  const p = usePortal();
  const { t, lang } = useLang();
  const toast = useToast();
  const confirm = useConfirm();
  const [q, setQ] = React.useState('');
  const [status, setStatus] = React.useState('all');
  const [prio, setPrio] = React.useState('all');
  const srt = useTableSort();
  const list = srt.sortRows(p.tasks.filter(tsk =>
    (status === 'all' || tsk.status === status) &&
    (prio === 'all' || tsk.priority === prio) &&
    (!q || (tsk.title + tsk.assignee + (tCustName(tsk.customer) || '')).toLowerCase().includes(q.toLowerCase()))),
    { title:x => x.title, owner:x => x.assignee, cust:x => tCustName(x.customer), prio:x => ({ high:0, med:1, low:2 })[x.priority] ?? 9,
      status:x => TASK_STATUS_FLOW.indexOf(x.status), due:x => x.dueDate });
  const cycle = (tsk) => { const i = TASK_STATUS_FLOW.indexOf(tsk.status); p.updateTask(tsk.id, { status:TASK_STATUS_FLOW[(i + 1) % TASK_STATUS_FLOW.length] }); };
  const remove = async (tsk, e) => { e.stopPropagation(); if (!(await confirm({ message:(lang === 'vi' ? 'Xóa công việc: ' : 'Delete: ') + tsk.title + '?', confirmLabel:lang === 'vi' ? 'Xóa' : 'Delete' }))) return; p.deleteTask(tsk.id); toast(lang === 'vi' ? 'Đã xóa' : 'Deleted', 'success'); };
  return (
    <div className="page pagefade">
      <div className="page-head"><div><h1>{t('c.list')}</h1><div className="sub">{list.length} {lang === 'vi' ? 'công việc' : 'tasks'}</div></div>
        <button className="btn btn-primary" onClick={() => p.quick('tasks')}><i className="bi bi-plus-lg"></i>{t('tk.new')}</button></div>
      <div className="toolbar">
        <div className="topsearch" style={{ width:240, background:'var(--bg)', border:'1px solid var(--border-strong)' }}><i className="bi bi-search"></i>
          <input value={q} onChange={e => setQ(e.target.value)} placeholder={t('c.search')} style={{ border:'none', outline:'none', background:'transparent', flex:1 }} /></div>
        <div className="seg">
          <button className={status === 'all' ? 'is-active' : ''} onClick={() => setStatus('all')}>{t('c.all')}</button>
          {TASK_STATUS_FLOW.map(s => <button key={s} className={status === s ? 'is-active' : ''} onClick={() => setStatus(s)}>{TASK_STATUS[s][lang]}</button>)}
        </div>
        <select className="select" style={{ width:'auto' }} value={prio} onChange={e => setPrio(e.target.value)}>
          <option value="all">{t('tk.priority')}: {t('c.all')}</option>
          {['high','med','low'].map(k => <option key={k} value={k}>{TASK_PRIORITY[k][lang]}</option>)}
        </select>
      </div>
      <div className="card"><div style={{ overflow:'auto' }}>
        <table className="tbl">
          <thead><tr><ThSort k="title" sort={srt}>{t('tk.title')}</ThSort><ThSort k="owner" sort={srt}>{t('c.owner')}</ThSort><ThSort k="cust" sort={srt}>{t('ct.customer')}</ThSort><ThSort k="prio" sort={srt}>{t('tk.priority')}</ThSort><ThSort k="status" sort={srt}>{t('c.status')}</ThSort><ThSort k="due" sort={srt}>{t('tk.due')}</ThSort><th style={{ width:40 }}></th></tr></thead>
          <tbody>
            {list.map(tsk => (
              <tr key={tsk.id} onClick={() => p.quick('tasks', tsk)}>
                <td><span style={{ fontWeight:500 }}>{tsk.title}</span></td>
                <td><span className="flex g8 items-center"><Avatar name={tsk.assignee} size={22} />{tsk.assignee}</span></td>
                <td className="muted">{tsk.customer ? tCustName(tsk.customer) : '—'}</td>
                <td><TaskPriBadge pr={tsk.priority} /></td>
                <td onClick={(e) => { e.stopPropagation(); cycle(tsk); }} style={{ cursor:'pointer' }} title={lang === 'vi' ? 'Bấm để đổi trạng thái' : 'Click to change'}><TaskStatusBadge st={tsk.status} /></td>
                <td><TaskDue task={tsk} /></td>
                <td style={{ textAlign:'center' }}><button className="iconbtn" style={{ width:24, height:24 }} title={t('c.delete')} onClick={(e) => remove(tsk, e)}><i className="bi bi-trash" style={{ fontSize:12 }}></i></button></td>
              </tr>
            ))}
          </tbody>
        </table>
        {list.length === 0 && <EmptyState text={t('c.empty')} />}
      </div></div>
    </div>
  );
}

/* ---------- Settings ---------- */
function TaskSettings(){
  const { t, lang } = useLang();
  return (
    <div className="page pagefade">
      <div className="page-head"><div><h1>{t('c.settings')}</h1><div className="sub">{lang === 'vi' ? 'Quy ước trạng thái & mức ưu tiên.' : 'Status & priority conventions.'}</div></div></div>
      <div className="dash-grid">
        <div className="card"><div className="card-head"><h3>{t('c.status')}</h3></div><div className="card-body col g8">
          {TASK_STATUS_FLOW.map(s => <div key={s} className="flex justify-between items-center"><span className="flex g8 items-center"><i className={'bi ' + TASK_STATUS[s].icon}></i>{TASK_STATUS[s][lang]}</span><TaskStatusBadge st={s} /></div>)}
        </div></div>
        <div className="card"><div className="card-head"><h3>{t('tk.priority')}</h3></div><div className="card-body col g8">
          {['high','med','low'].map(k => <div key={k} className="flex justify-between items-center"><span>{TASK_PRIORITY[k][lang]}</span><TaskPriBadge pr={k} /></div>)}
        </div></div>
      </div>
    </div>
  );
}

/* ---------- New/Edit modal (quick-action target; truyền task để sửa) ---------- */
function NewTaskModal({ onClose, editing }){
  const p = usePortal();
  const { t, lang } = useLang();
  const toast = useToast();
  const L = (vi, en) => (lang === 'vi' ? vi : en);
  const [f, setF] = React.useState(editing
    ? { title:editing.title, desc:editing.desc || '', status:editing.status, priority:editing.priority, assignee:editing.assignee, dueDate:editing.dueDate || TODAY, customer:editing.customer || '' }
    : { title:'', desc:'', status:'todo', priority:'med', assignee:(p.me && p.me.name) || (p.users[0] && p.users[0].name) || '', dueDate:TODAY, customer:'' });
  const set = (k, v) => setF(s => ({ ...s, [k]:v }));
  const save = () => {
    if (!f.title.trim()){ toast(L('Nhập tiêu đề công việc', 'Enter a task title'), 'error'); return; }
    const rec = { title:f.title.trim(), desc:f.desc.trim(), status:f.status, priority:f.priority, assignee:f.assignee, dueDate:f.dueDate, customer:f.customer || null };
    if (editing){ p.updateTask(editing.id, rec); toast(L('Đã lưu công việc', 'Saved'), 'success'); onClose(); return; }
    p.addTask({ id:genTaskCode(p.tasks), ...rec });
    toast(L('Đã tạo công việc', 'Task created'), 'success');
    onClose();
  };
  return (
    <Modal title={editing ? L('Sửa công việc', 'Edit task') : t('tk.new')} width={560} onClose={onClose}
      footer={<><button className="btn" onClick={onClose}>{t('c.cancel')}</button><button className="btn btn-primary" onClick={save}>{editing ? t('c.save') : t('c.create')}</button></>}>
      <div className="col g16">
        <Field label={t('tk.title')}><input className="input" autoFocus value={f.title} onChange={e => set('title', e.target.value)} placeholder={L('VD: Gửi báo giá cho khách hàng', 'e.g. Send quote to customer')} /></Field>
        <Field label={t('tk.desc')}><textarea className="textarea" rows={2} value={f.desc} onChange={e => set('desc', e.target.value)} placeholder={L('Mô tả chi tiết (tùy chọn)', 'Details (optional)')} /></Field>
        <div className="flex g12 wrap">
          <div style={{ flex:'1 1 160px' }}><Field label={t('c.status')}><Segmented value={f.status} onChange={v => set('status', v)} options={TASK_STATUS_FLOW.map(s => ({ value:s, label:TASK_STATUS[s][lang] }))} /></Field></div>
          <div style={{ flex:'1 1 140px' }}><Field label={t('tk.priority')}><select className="select" value={f.priority} onChange={e => set('priority', e.target.value)}>{['high','med','low'].map(k => <option key={k} value={k}>{TASK_PRIORITY[k][lang]}</option>)}</select></Field></div>
        </div>
        <div className="flex g12 wrap">
          <div style={{ flex:'1 1 180px' }}><Field label={t('c.owner')}><select className="select" value={f.assignee} onChange={e => set('assignee', e.target.value)}>{p.users.map(u => <option key={u.id || u.name}>{u.name}</option>)}</select></Field></div>
          <div style={{ flex:'1 1 140px' }}><Field label={t('tk.due')}><DateInput value={f.dueDate} onChange={v => set('dueDate', v)} /></Field></div>
        </div>
        <Field label={t('ct.customer') + ' (' + L('tùy chọn', 'optional') + ')'}><select className="select" value={f.customer} onChange={e => set('customer', e.target.value)}>
          <option value="">— {L('không gắn', 'none')} —</option>
          {p.customers.map(c => <option key={c.code} value={c.code}>{c.code} · {c.name}</option>)}
        </select></Field>
      </div>
    </Modal>
  );
}

Object.assign(window, { TaskModule, NewTaskModal });
