/* ============================================================
   VLF 2026 · OPS — LỚP GIỮ CONNECT + WORKLIST (học từ Field App)
   Bổ sung vào app thật: trạng thái online/offline · hàng đợi outbox
   · đồng bộ · toast audit; và worklist gộp việc mọi nhiệm vụ.
   Phụ trợ — KHÔNG đụng 13 màn cũ. CSS: vlf-ops-connect.css
   ============================================================ */

/* ---- strip trạng thái mạng (chỉ hiện khi offline hoặc còn hàng đợi) ---- */
function ConnectStrip({ store }) {
  const lang = useLang();
  if (!store) return null;
  const { online, queue, syncNow } = store;
  const n = queue ? queue.length : 0;
  if (online && n === 0) return null;
  return (
    <div className={'ops-conn ' + (online ? 'ops-conn--sync' : 'ops-conn--off')}>
      <span className="ops-conn-dot" />
      <div className="ops-conn-tx">
        <b>{online ? trL(lang, { vi: 'Đang đồng bộ…', en: 'Syncing…' }) : trL(lang, { vi: 'Mất sóng · ngoại tuyến', en: 'Offline' })}</b>
        <span>{n
          ? trL(lang, { vi: n + ' thao tác chờ đẩy về control tower', en: n + ' actions queued for control tower' })
          : trL(lang, { vi: 'Thao tác đang đồng bộ realtime', en: 'Syncing in real time' })}</span>
      </div>
      {n > 0 && <button className="ops-conn-btn" onClick={syncNow}>{trL(lang, { vi: 'Đồng bộ ngay', en: 'Sync now' })}</button>}
    </div>);
}

/* ---- toast audit (đặt cố định trong .za-screen) ---- */
function OpsToasts({ toasts }) {
  if (!toasts || !toasts.length) return null;
  const ic = (tone) => tone === 'warn' ? 'clock' : tone === 'crit' ? 'bell' : 'check';
  return (
    <div className="ops-toasts">
      {toasts.map((t) => (
        <div key={t.id} className={'ops-toast ops-toast--' + (t.tone || 'ok')}>
          <span className="ops-toast-ic"><Icon name={ic(t.tone)} size={16} sw={2.2} /></span>
          <div className="ops-toast-tx"><b>{t.title}</b>{t.sub && <span>{t.sub}</span>}</div>
        </div>
      ))}
    </div>);
}

/* ---- Worklist hợp nhất: gộp việc còn mở của MỌI nhiệm vụ đang giữ ----
   Nguồn từ chính O: sự cố gần khu + việc con chưa xong (đội + phối hợp).
   Sắp theo ưu tiên (sự cố → P1 → P2 → P3), khép vòng bằng nav thẳng. */
function OpsWorklist({ O, lang, team, tasks, collab, nav }) {
  const items = [];
  // 1) sự cố đang mở gần khu của bạn
  O.incidentsForPhase()
    .filter((i) => i.status !== 'resolved' && (i.team === team.id || (team.zone && i.zone && i.zone.vi === team.zone.vi)))
    .forEach((i) => items.push({
      prio: -1, tone: i.sev === 'high' ? 'crit' : 'warn', icon: 'bell',
      label: i.title, sub: { vi: trL(lang, i.zone) + ' · ' + trL(lang, O.incStatus[i.status]), en: trL(lang, i.zone) + ' · ' + trL(lang, O.incStatus[i.status]) },
      tag: { vi: 'Sự cố', en: 'Incident' }, onClick: () => nav('incident', { id: i.id }),
    }));
  // 2) việc con chưa xong của nhiệm vụ đội + phối hợp
  const seen = new Set();
  [...(tasks || []), ...(collab || [])].forEach((t) => {
    if (seen.has(t.id)) return; seen.add(t.id);
    const info = O.deadlineInfo(t);
    const pr = t.prio === 'P1' ? 1 : t.prio === 'P2' ? 2 : 3;
    (t.steps || []).forEach((s) => {
      if (s.done) return;
      items.push({
        prio: info.state === 'overdue' ? 0 : pr,
        tone: info.state === 'overdue' ? 'crit' : t.prio === 'P1' ? 'warn' : 'norm',
        icon: 'check', label: s.t, sub: t.title, who: s.by,
        tag: O.teamById(t.team).name, onClick: () => nav('task', { id: t.id }),
      });
    });
  });
  if (!items.length) return null;
  items.sort((a, b) => a.prio - b.prio);
  const shown = items.slice(0, 7);
  return (
    <>
      <SectionHead
        title={trL(lang, { vi: 'Việc cần xử lý · gộp mọi nhiệm vụ', en: 'To-do · across all your duties' })}
        sub={trL(lang, { vi: 'một danh sách — sự cố, việc đội & phối hợp', en: 'one list — incidents, team & collab work' })}
        right={<span className="v-pill" style={{ background: 'var(--vlf-purple-50)', color: 'var(--vlf-purple-700)' }}>{items.length}</span>} />
      <div className="v-card ops-wl">
        {shown.map((w, i) => (
          <div className={'ops-wl-row' + (i ? ' bt' : '')} key={i} onClick={w.onClick}>
            <span className={'ops-wl-ic ops-wl-ic--' + w.tone}><Icon name={w.icon} size={16} sw={2.1} /></span>
            <div className="ops-wl-tx">
              <div className="t">{trL(lang, w.label)}</div>
              <div className="s">{trL(lang, w.sub)}{w.who ? ' · ' + w.who : ''}</div>
            </div>
            <span className="ops-wl-tag">{trL(lang, w.tag)}</span>
            <Icon name="chev" size={16} className="chev" />
          </div>
        ))}
      </div>
    </>);
}

Object.assign(window, { ConnectStrip, OpsToasts, OpsWorklist, OpsDutyBoard });

/* ---- Ca của tôi · nhiều nhiệm vụ (một người giữ nhiều năng lực, xoay theo ca) ----
   Học từ Field App: bỏ "khoá 1 vai = 1 màn". Hiện mọi nhiệm vụ người này giữ
   theo từng ca; chạm một nhiệm vụ → mở đúng bối cảnh năng lực (bảng nhiệm vụ đội). */
const DUTY_ICON = { gate: 'qr', stand: 'flag', marshal: 'flag', village: 'village', shuttle: 'car', medical: 'medical', security: 'shield' };
function OpsDutyBoard({ O, lang, role, nav }) {
  const duties = O.personDuties[role.id];
  if (!duties) return null;
  const shiftKeys = O.dutyShifts.filter((s) => (duties[s.id] || []).length);
  const initial = (shiftKeys.find((s) => (duties[s.id] || []).length) || O.dutyShifts[0]).id;
  const [sh, setSh] = useState(initial);
  const list = duties[sh] || [];
  const total = O.dutyCount(role.id);
  if (total <= 1) return null; // chỉ hiện cho người thực sự giữ nhiều nhiệm vụ
  return (
    <>
      <SectionHead
        title={trL(lang, { vi: 'Ca của tôi · nhiều nhiệm vụ', en: 'My shift · multiple duties' })}
        sub={trL(lang, { vi: 'Hôm nay bạn giữ ' + total + ' nhiệm vụ — xoay theo ca, cùng một app', en: 'You hold ' + total + ' duties today — rotating by shift, one app' })} />
      <div className="v-card ops-duty">
        <div className="ops-duty-seg">
          {O.dutyShifts.map((s) => {
            const n = (duties[s.id] || []).length;
            return (
              <button key={s.id} className={s.id === sh ? 'on' : ''} onClick={() => setSh(s.id)} disabled={!n}>
                <b>{trL(lang, s.l)}{n ? ' · ' + n : ''}</b><i>{s.t}</i>
              </button>);
          })}
        </div>
        {list.length ? list.map((tid, i) => {
          const tm = O.teamById(tid);
          return (
            <div className={'ops-duty-row' + (i ? ' bt' : '')} key={i} onClick={() => nav('tasks', { team: tid })}>
              <span className="ops-duty-ic" style={{ background: tm.color + '22', color: tm.color }}><Icon name={DUTY_ICON[tid] || 'check'} size={17} sw={1.85} /></span>
              <div className="ops-duty-tx">
                <div className="t">{trL(lang, tm.name)}</div>
                <div className="s">{trL(lang, tm.zone || tm.name)} · {trL(lang, { vi: 'Bộ đàm', en: 'Radio' })} {tm.radio}</div>
              </div>
              <span className="ops-duty-open">{trL(lang, { vi: 'Mở', en: 'Open' })}<Icon name="chev" size={14} /></span>
            </div>);
        }) : <div className="ops-duty-empty">{trL(lang, { vi: 'Ca này bạn nghỉ — không có nhiệm vụ.', en: 'Off this shift — no duties.' })}</div>}
        <div className="ops-duty-foot"><Icon name="info" size={12} sw={2} />{trL(lang, { vi: 'Cùng một app, cùng thao tác — chỉ năng lực đổi theo nhiệm vụ.', en: 'Same app, same actions — only the capability changes per duty.' })}</div>
      </div>
    </>);
}
