// Dashboard.jsx — caregiver clinical view. Responsive: mobile (list⇄detail) + desktop (split).
const { useState: useStateDash, useMemo: useMemoDash } = React;

const STATUS_DOT = { submitted: '#1AA06D', progress: '#E0901B', waiting: '#C2CEDB' };
const statusLabel = (s, D) => s === 'submitted' ? D.status_ready : s === 'progress' ? D.status_progress : D.status_waiting;
const sexLabel = (s, D) => s === 'm' ? D.sex_m : s === 'f' ? D.sex_f : '';
const fileGlyph = t => t === 'image' ? '🖼' : t === 'video' ? '🎬' : '📄';
const snippet = (s, n = 70) => !s ? '' : (s.length > n ? s.slice(0, n).trim() + '…' : s);

function Row({ p, active, seen, onClick, D }) {
  const T = window.TOK, dot = STATUS_DOT[p.status];
  // a "seen" complaint reads as done: muted to light gray so unseen ones stand out
  const dim = seen && !active;
  return (
    <button onClick={onClick} style={{
      width: '100%', textAlign: 'left', cursor: 'pointer', border: 'none',
      background: active ? T.surface : (dim ? '#FAFCFE' : 'transparent'),
      borderLeft: `3px solid ${active ? T.accent : 'transparent'}`,
      padding: '15px 18px', display: 'flex', gap: 13, alignItems: 'flex-start', fontFamily: 'inherit',
      borderBottom: `1px solid ${T.lineSoft}`,
    }}>
      <span style={{ width: 42, height: 42, borderRadius: 11, flexShrink: 0, marginTop: 2, background: active ? T.accent : (dim ? '#EDF1F6' : T.boneDeep), color: active ? '#fff' : (dim ? '#B7C4D2' : T.muted), fontFamily: "'Instrument Serif', serif", fontSize: 20, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>{p.serial}</span>
      <span style={{ flex: 1, minWidth: 0 }}>
        <span style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
          <span style={{ fontSize: 15.5, fontWeight: 600, color: dim ? T.faint : T.ink, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{p.name}</span>
          <span style={{ fontSize: 13, color: dim ? '#B7C4D2' : T.faint, flexShrink: 0 }}>{p.age || '—'}</span>
        </span>
        <span style={{ display: '-webkit-box', WebkitLineClamp: 2, WebkitBoxOrient: 'vertical', overflow: 'hidden', fontSize: 13.5, color: dim ? '#B7C4D2' : T.muted, marginTop: 3, lineHeight: 1.45 }}>
          {p.complaint ? snippet(p.complaint) : <span style={{ color: T.faint }}>{statusLabel(p.status, D)}</span>}
        </span>
      </span>
      <span style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 7, flexShrink: 0, paddingTop: 4 }}>
        {seen
          ? <span title={D.seen} style={{ width: 17, height: 17, borderRadius: '50%', background: '#E6EBF1', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
              <svg width="11" height="11" viewBox="0 0 24 24" fill="none"><path d="M5 12.5l4.2 4.2L19 7" stroke="#9DB2C8" strokeWidth="3" strokeLinecap="round" strokeLinejoin="round"/></svg>
            </span>
          : <span style={{ width: 8, height: 8, borderRadius: '50%', background: dot }} />}
        {p.files.length > 0 && (
          <span style={{ display: 'inline-flex', alignItems: 'center', gap: 3, fontSize: 11.5, color: T.faint }}>
            <svg width="11" height="11" viewBox="0 0 24 24" fill="none"><path d="M16 8l-7 7a3 3 0 0 1-4-4l8-8a4.5 4.5 0 0 1 6 6l-8 8" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/></svg>
            {p.files.length}
          </span>
        )}
      </span>
    </button>
  );
}

function Detail({ p, compact, onBack, seen, onToggleSeen, onAskDelete, D }) {
  const T = window.TOK;
  const [menuOpen, setMenuOpen] = useStateDash(false);
  React.useEffect(() => { setMenuOpen(false); }, [p && p.id]);
  if (!p) return (
    <div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'center', flexDirection: 'column', gap: 16, color: T.faint }}>
      <svg width="46" height="46" viewBox="0 0 24 24" fill="none"><path d="M4 5h16M4 10h16M4 15h10" stroke={T.line} strokeWidth="2" strokeLinecap="round"/></svg>
      <div style={{ fontSize: 16 }}>{D.pick_patient}</div>
    </div>
  );

  const overflowMenu = (
    <div style={{ position: 'relative', flexShrink: 0, zIndex: 40 }}>
      <button onClick={() => setMenuOpen(o => !o)} title="আরও" style={{ width: 40, height: 40, borderRadius: 11, border: `1px solid ${menuOpen ? T.accent : T.line}`, background: menuOpen ? T.accentSoft : T.bone, cursor: 'pointer', color: T.inkSoft, display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <svg width="20" height="20" viewBox="0 0 24 24" fill="none"><circle cx="12" cy="5" r="1.7" fill="currentColor"/><circle cx="12" cy="12" r="1.7" fill="currentColor"/><circle cx="12" cy="19" r="1.7" fill="currentColor"/></svg>
      </button>
      {menuOpen && (
        <React.Fragment>
          <div onClick={() => setMenuOpen(false)} style={{ position: 'fixed', inset: 0, zIndex: 30 }} />
          <div className="om-pop" style={{ position: 'absolute', top: 'calc(100% + 8px)', right: 0, zIndex: 31, width: 256, background: T.surface, border: `1px solid ${T.line}`, borderRadius: 14, boxShadow: '0 14px 40px rgba(17,42,65,0.18)', overflow: 'hidden' }}>
            <button onClick={() => { setMenuOpen(false); onAskDelete(p); }} style={{ width: '100%', textAlign: 'left', display: 'flex', gap: 11, alignItems: 'flex-start', padding: '14px 15px', cursor: 'pointer', border: 'none', background: 'transparent', fontFamily: 'inherit' }}
              onMouseEnter={e => e.currentTarget.style.background = '#FCF2EF'} onMouseLeave={e => e.currentTarget.style.background = 'transparent'}>
              <svg width="18" height="18" viewBox="0 0 24 24" fill="none" style={{ marginTop: 1, flexShrink: 0 }}><path d="M5 7h14M10 11v6M14 11v6M6 7l1 13h10l1-13M9 7V4h6v3" stroke="#C0492B" strokeWidth="1.7" strokeLinecap="round" strokeLinejoin="round"/></svg>
              <span>
                <span style={{ display: 'block', fontSize: 14.5, fontWeight: 600, color: '#C0492B' }}>{D.del_entry}</span>
                <span style={{ display: 'block', fontSize: 12.5, color: T.muted, marginTop: 2, lineHeight: 1.4 }}>{D.del_entry_sub}</span>
              </span>
            </button>
          </div>
        </React.Fragment>
      )}
    </div>
  );

  const actions = (
    <div style={{ display: 'flex', alignItems: 'center', gap: 9, flexShrink: 0 }}>
      {p.status === 'submitted' && (
        <button onClick={() => onToggleSeen(p.id)} style={{
          display: 'inline-flex', alignItems: 'center', gap: 7, padding: '0 14px', height: 40, cursor: 'pointer',
          fontFamily: 'inherit', fontSize: 14, fontWeight: 600, borderRadius: 11,
          border: `1px solid ${seen ? T.line : T.accent}`,
          background: seen ? '#EDF1F6' : T.accent,
          color: seen ? '#9DB2C8' : '#fff',
        }}>
          <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M5 12.5l4.2 4.2L19 7" stroke="currentColor" strokeWidth="2.6" strokeLinecap="round" strokeLinejoin="round"/></svg>
          {seen ? D.seen : (compact ? D.seen : D.mark_seen)}
        </button>
      )}
      {overflowMenu}
    </div>
  );

  const head = (
    <div style={{ display: 'flex', alignItems: 'flex-start', gap: 16, paddingBottom: 22, borderBottom: `1px solid ${T.line}` }}>
      <div style={{ width: 56, height: 56, borderRadius: 14, background: T.accent, color: '#fff', fontFamily: "'Instrument Serif', serif", fontSize: 26, display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>{p.serial}</div>
      <div style={{ flex: 1, minWidth: 0 }}>
        <div style={{ fontSize: 23, fontWeight: 600, color: T.ink, lineHeight: 1.2 }}>{p.name}</div>
        <div style={{ fontSize: 14.5, color: T.muted, marginTop: 4 }}>{p.age ? p.age + ' ' + D.years : '—'}{p.sex ? ' · ' + sexLabel(p.sex, D) : ''}{p.phone ? ' · ' + p.phone : ''}{p.submittedAt ? ' · ' + p.submittedAt : ''}</div>
      </div>
      {!compact && actions}
    </div>
  );

  if (p.status !== 'submitted') {
    return (
      <div style={{ flex: 1, overflowY: 'auto' }}>
        {compact && <BackBar onBack={onBack} right={actions} D={D} />}
        <div style={{ maxWidth: 760, margin: '0 auto', padding: compact ? '18px 22px 40px' : '34px 40px' }}>
          {head}
          <div style={{ marginTop: 28, color: T.muted, fontSize: 15.5, lineHeight: 1.6 }}>
            {p.status === 'progress' ? D.msg_progress : D.msg_waiting}
          </div>
        </div>
      </div>
    );
  }

  return (
    <div style={{ flex: 1, overflowY: 'auto' }}>
      {compact && <BackBar onBack={onBack} right={actions} D={D} />}
      <div style={{ maxWidth: 760, margin: '0 auto', padding: compact ? '18px 22px 40px' : '34px 44px 56px' }}>
        {head}
        <div style={{ marginTop: 26 }}>
          <div style={{ fontSize: 12, fontWeight: 700, letterSpacing: 1, color: T.faint, marginBottom: 14 }}>{D.in_words}</div>
          <div style={{ fontSize: compact ? 18 : 21, lineHeight: 1.75, color: T.ink, whiteSpace: 'pre-wrap' }}>{p.complaint}</div>
        </div>
        <div style={{ marginTop: 36 }}>
          <div style={{ fontSize: 12, fontWeight: 700, letterSpacing: 1, color: T.faint, marginBottom: 14 }}>{D.attachments} {p.files.length ? `· ${p.files.length}` : ''}</div>
          {p.files.length === 0
            ? <div style={{ fontSize: 15, color: T.faint }}>{D.no_files}</div>
            : <div style={{ display: 'grid', gridTemplateColumns: compact ? 'repeat(2,1fr)' : 'repeat(auto-fill, minmax(150px, 1fr))', gap: 13 }}>
                {p.files.map((f, i) => (
                  <div key={i} style={{ border: `1px solid ${T.line}`, borderRadius: 13, overflow: 'hidden', cursor: 'pointer', background: T.surface }}>
                    <div style={{ height: 96, background: f.url ? `center/cover no-repeat url(${f.url})` : T.boneDeep, display: 'flex', alignItems: 'center', justifyContent: 'center', fontSize: 28 }}>{!f.url && fileGlyph(f.type)}</div>
                    <div style={{ padding: '9px 11px', fontSize: 13, color: T.inkSoft, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>{f.name}</div>
                  </div>
                ))}
              </div>}
        </div>
      </div>
    </div>
  );
}

function BackBar({ onBack, right, D }) {
  const T = window.TOK;
  return (
    <div style={{ position: 'sticky', top: 0, zIndex: 5, background: T.surface, borderBottom: `1px solid ${T.lineSoft}`, padding: '10px 16px', display: 'flex', alignItems: 'center', gap: 10 }}>
      <button onClick={onBack} style={{ display: 'inline-flex', alignItems: 'center', gap: 6, padding: '7px 12px', cursor: 'pointer', fontFamily: 'inherit', fontSize: 14.5, fontWeight: 600, color: T.inkSoft, background: T.bone, border: `1px solid ${T.line}`, borderRadius: 10, flexShrink: 0 }}>
        <svg width="16" height="16" viewBox="0 0 24 24" fill="none"><path d="M15 6l-6 6 6 6" stroke={T.inkSoft} strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>
        {D ? D.list_back : ''}
      </button>
      <div style={{ flex: 1 }} />
      {right}
    </div>
  );
}

// 'YYYY-MM-DD' → friendly label (Today / Yesterday / Mon, Jun 2)
function dayLabel(day, D) {
  const now = new Date();
  const k = (d) => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;
  const y = new Date(now); y.setDate(now.getDate() - 1);
  if (day === k(now)) return D.date_today;
  if (day === k(y)) return D.date_yesterday;
  const parts = day.split('-');
  const dt = new Date(+parts[0], +parts[1] - 1, +parts[2]);
  return dt.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' });
}

function Dashboard({ patients, compact, onLogout, account, onDelete, onSeen, scope = 'today', onScope, online, lang = 'en', onLang }) {
  const T = window.TOK, D = window.dict(lang);
  const allMode = scope === 'all';
  const sorted = useMemoDash(() => [...patients].sort((a, b) =>
    (a.day === b.day || !a.day) ? a.serial - b.serial : (a.day < b.day ? 1 : -1)), [patients]);
  const [activeId, setActiveId] = useStateDash(null);
  const [query, setQuery] = useStateDash('');
  const [seenIds, setSeenIds] = useStateDash([]);
  const [pendingDelete, setPendingDelete] = useStateDash(null);
  // hydrate "seen" from the server's per-caregiver flag (online); merges with any local toggles
  React.useEffect(() => {
    const serverSeen = patients.filter(p => p.seen).map(p => p.id);
    if (serverSeen.length) setSeenIds(s => Array.from(new Set([...s, ...serverSeen])));
  }, [patients]);
  const active = patients.find(p => p.id === activeId) || null;
  const isSeen = id => seenIds.includes(id);
  const toggleSeen = id => setSeenIds(s => {
    const next = s.includes(id) ? s.filter(x => x !== id) : [...s, id];
    if (onSeen) onSeen(id, next.includes(id));   // persist to server when online
    return next;
  });
  const confirmDelete = () => {
    if (!pendingDelete) return;
    onDelete(pendingDelete.id);
    setSeenIds(s => s.filter(x => x !== pendingDelete.id));
    if (activeId === pendingDelete.id) setActiveId(null);
    setPendingDelete(null);
  };

  const filtered = sorted.filter(p => {
    const q = query.trim().toLowerCase();
    return !q || p.name.toLowerCase().includes(q) || String(p.serial).includes(q);
  });
  const readyCount = patients.filter(p => p.status === 'submitted').length;
  const unseenCount = patients.filter(p => p.status === 'submitted' && !isSeen(p.id)).length;

  // in "all" mode, render a small date header before each new day group
  const rows = [];
  let lastDay = null;
  filtered.forEach(p => {
    if (allMode && p.day && p.day !== lastDay) {
      lastDay = p.day;
      rows.push(
        <div key={'h_' + p.day} style={{ position: 'sticky', top: 0, zIndex: 1, background: T.bone, padding: '10px 18px 6px', fontSize: 11, fontWeight: 700, letterSpacing: 0.8, textTransform: 'uppercase', color: T.faint, borderBottom: `1px solid ${T.lineSoft}` }}>{dayLabel(p.day, D)}</div>
      );
    }
    rows.push(<Row key={p.id} p={p} active={p.id === activeId} seen={isSeen(p.id)} onClick={() => setActiveId(p.id)} D={D} />);
  });

  const listPane = (
    <div style={{ display: 'flex', flexDirection: 'column', height: '100%', background: T.bone }}>
      <div style={{ padding: '16px 18px 10px', flexShrink: 0 }}>
        {/* scope toggle — Today (the working queue) vs All (the retained history) */}
        {online && onScope && (
          <div style={{ display: 'flex', gap: 3, padding: 3, background: T.lineSoft, borderRadius: 100, marginBottom: 12 }}>
            {[['today', D.scope_today], ['all', D.scope_all]].map(([v, l]) => (
              <button key={v} onClick={() => onScope(v)} style={{ flex: 1, height: 34, cursor: 'pointer', border: 'none', borderRadius: 100, fontFamily: 'inherit', fontSize: 13.5, fontWeight: 600, background: scope === v ? T.surface : 'transparent', color: scope === v ? T.accentDeep : T.muted, boxShadow: scope === v ? '0 1px 3px rgba(17,42,65,0.12)' : 'none' }}>{l}</button>
            ))}
          </div>
        )}
        <div style={{ position: 'relative' }}>
          <svg width="17" height="17" viewBox="0 0 24 24" fill="none" style={{ position: 'absolute', left: 13, top: 14 }}><circle cx="11" cy="11" r="7" stroke={T.faint} strokeWidth="2"/><path d="M16 16l4 4" stroke={T.faint} strokeWidth="2" strokeLinecap="round"/></svg>
          <input value={query} onChange={e => setQuery(e.target.value)} placeholder={D.search_ph}
            style={{ width: '100%', boxSizing: 'border-box', height: 45, padding: '0 14px 0 38px', fontFamily: 'inherit', fontSize: 15, color: T.ink, background: T.surface, border: `1px solid ${T.line}`, borderRadius: 12, outline: 'none' }} />
        </div>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', margin: '15px 4px 2px' }}>
          <div style={{ fontSize: 11.5, fontWeight: 700, letterSpacing: 0.6, color: T.faint }}>{allMode ? D.all_patients : D.todays_queue} · {filtered.length}</div>
          {unseenCount > 0 && <div style={{ fontSize: 11.5, fontWeight: 700, letterSpacing: 0.3, color: T.accentDeep, background: T.accentSoft, padding: '2px 8px', borderRadius: 100 }}>{unseenCount} {D.unseen}</div>}
        </div>
      </div>
      <div style={{ flex: 1, overflowY: 'auto' }}>
        {rows}
      </div>
    </div>
  );

  return (
    <div style={{ height: '100%', position: 'relative', display: 'flex', flexDirection: 'column', background: T.bone, fontFamily: "'Anek Bangla', 'Hind Siliguri', sans-serif" }}>
      <window.StaffTopbar compact={compact} account={account} lang={lang} onLang={onLang} onLogout={onLogout} roleTag={D.role_caregiver}
        right={!compact && <div style={{ fontSize: 13, color: T.muted, marginRight: 4 }}>{unseenCount} {D.unseen} · {readyCount} {D.ready}</div>} />
      <div style={{ flex: 1, display: 'flex', minHeight: 0 }}>
        {compact ? (
          active
            ? <div style={{ flex: 1, display: 'flex', flexDirection: 'column', background: T.surface }}><Detail p={active} compact seen={isSeen(active.id)} onToggleSeen={toggleSeen} onAskDelete={setPendingDelete} onBack={() => setActiveId(null)} D={D} /></div>
            : listPane
        ) : (
          <React.Fragment>
            <div style={{ width: 380, flexShrink: 0, borderRight: `1px solid ${T.line}` }}>{listPane}</div>
            <div style={{ flex: 1, display: 'flex', flexDirection: 'column', minWidth: 0, background: T.surface }}><Detail p={active} seen={active && isSeen(active.id)} onToggleSeen={toggleSeen} onAskDelete={setPendingDelete} D={D} /></div>
          </React.Fragment>
        )}
      </div>

      {pendingDelete && (
        <div className="om-backdrop" onClick={() => setPendingDelete(null)} style={{ position: 'absolute', inset: 0, zIndex: 90, background: 'rgba(17,42,65,0.42)', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 22 }}>
          <div className="om-pop" onClick={e => e.stopPropagation()} style={{ width: '100%', maxWidth: 380, background: T.surface, borderRadius: 20, padding: '26px 24px 22px', boxShadow: '0 24px 70px rgba(17,42,65,0.32)' }}>
            <div style={{ width: 50, height: 50, borderRadius: 14, background: '#FCE9E4', display: 'flex', alignItems: 'center', justifyContent: 'center', marginBottom: 16 }}>
              <svg width="24" height="24" viewBox="0 0 24 24" fill="none"><path d="M5 7h14M10 11v6M14 11v6M6 7l1 13h10l1-13M9 7V4h6v3" stroke="#C0492B" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round"/></svg>
            </div>
            <div style={{ fontSize: 21, fontWeight: 600, color: T.ink, lineHeight: 1.3 }}>{D.del_q}</div>
            <div style={{ fontSize: 14.5, color: T.muted, marginTop: 8, lineHeight: 1.6 }}>
              <span style={{ fontWeight: 600, color: T.inkSoft }}>{D.serial} {pendingDelete.serial} · {pendingDelete.name}</span>{D.del_body_a}
            </div>
            <div style={{ display: 'flex', gap: 10, marginTop: 22 }}>
              <button onClick={() => setPendingDelete(null)} style={{ flex: 1, height: 48, cursor: 'pointer', fontFamily: 'inherit', fontSize: 15.5, fontWeight: 600, color: T.inkSoft, background: T.bone, border: `1px solid ${T.line}`, borderRadius: 12 }}>{D.del_cancel}</button>
              <button onClick={confirmDelete} style={{ flex: 1, height: 48, cursor: 'pointer', fontFamily: 'inherit', fontSize: 15.5, fontWeight: 600, color: '#fff', background: '#C0492B', border: 'none', borderRadius: 12 }}>{D.del_confirm}</button>
            </div>
          </div>
        </div>
      )}
    </div>
  );
}

window.Dashboard = Dashboard;
