// Brook Consultancy — Operator Queue (v2 pass 2)
//
// Top-level view when ?role=operator. No sidebar — the queue is the work.
// Operator filters between waiting consultations, in-progress consultations,
// and today's bookings; clicks Claim & open to land in AI Assist on a session.

function OperatorQueue({ store, log, onClaim, onOpen, onConvertBooking, onMarkArrived, onNewConsultation }) {
  const [filter, setFilter] = React.useState('waiting'); // waiting | mine | bookings | all
  const [, forceTick] = React.useState(0);

  const deviceId = store?.deviceId;

  // Re-render every 15s so "time waiting" stays fresh.
  React.useEffect(() => {
    const id = setInterval(() => forceTick(t => t + 1), 15_000);
    return () => clearInterval(id);
  }, []);

  // Bucket the entries
  const bucketed = React.useMemo(() => {
    const waiting   = [];
    const mine      = [];
    const bookings  = [];
    const today     = new Date().toISOString().slice(0, 10);
    const allToday  = [];

    log.forEach(entry => {
      if (entry.kind === 'booking') {
        bookings.push(entry);
        if ((entry.consultation_date || '').slice(0, 10) === today) allToday.push(entry);
        return;
      }
      if (entry.status === 'ready_for_analysis') waiting.push(entry);
      if (entry.status === 'analysing' && entry.claimedBy === deviceId) mine.push(entry);
      if ((entry.consultation_date || '').slice(0, 10) === today
          || (entry.updatedAt || '').slice(0, 10) === today) {
        allToday.push(entry);
      }
    });

    // Waiting: oldest first
    waiting.sort((a, b) => (a.updatedAt || '').localeCompare(b.updatedAt || ''));
    // Bookings: by slot time
    bookings.sort((a, b) => (a.slot_iso || '').localeCompare(b.slot_iso || ''));
    return { waiting, mine, bookings, allToday };
  }, [log, deviceId]);

  const counts = {
    waiting: bucketed.waiting.length,
    mine: bucketed.mine.length,
    bookings: bucketed.bookings.filter(b => b.status === 'booked' || b.status === 'arrived').length,
    all: bucketed.allToday.length
  };

  const list = filter === 'waiting'   ? bucketed.waiting
            : filter === 'mine'       ? bucketed.mine
            : filter === 'bookings'   ? bucketed.bookings
            : bucketed.allToday;

  return (
    <div className="op-queue">
      <div className="op-queue-header">
        <div>
          <div className="eyebrow">Operator</div>
          <h1>Live session queue</h1>
          <p className="op-queue-sub">
            Consultants flip sessions to <strong>Ready for analysis</strong> when their call ends. Claim a session to run the AI step, approve the TV insight, and email the prospect their one-pager.
          </p>
        </div>
        <div className="op-queue-actions">
          <button className="btn" onClick={onNewConsultation}>+ New consultation</button>
        </div>
      </div>

      <div className="op-filter-row">
        <FilterChip label="Waiting"      count={counts.waiting}  active={filter === 'waiting'}  onClick={() => setFilter('waiting')} />
        <FilterChip label="With me"      count={counts.mine}     active={filter === 'mine'}     onClick={() => setFilter('mine')} />
        <FilterChip label="Bookings today" count={counts.bookings} active={filter === 'bookings'} onClick={() => setFilter('bookings')} />
        <FilterChip label="All today"    count={counts.all}      active={filter === 'all'}      onClick={() => setFilter('all')} />
      </div>

      {list.length === 0 ? (
        <EmptyQueue filter={filter} />
      ) : (
        <table className="op-queue-table">
          <thead>
            <tr>
              {filter === 'bookings' ? (
                <>
                  <th style={{ width: 130 }}>Slot</th>
                  <th>Business</th>
                  <th>Contact</th>
                  <th>Zone</th>
                  <th>Headline challenge</th>
                  <th>Status</th>
                  <th></th>
                </>
              ) : (
                <>
                  <th>Organisation</th>
                  <th>Consultant</th>
                  <th style={{ width: 140 }}>Started</th>
                  <th style={{ width: 140 }}>Waiting</th>
                  <th>Status</th>
                  <th></th>
                </>
              )}
            </tr>
          </thead>
          <tbody>
            {list.map(entry => entry.kind === 'booking'
              ? <BookingRow key={entry.id} entry={entry} onConvertBooking={onConvertBooking} onMarkArrived={onMarkArrived} onOpen={onOpen} />
              : <ConsultationRow key={entry.id} entry={entry} deviceId={deviceId} onClaim={onClaim} onOpen={onOpen} />
            )}
          </tbody>
        </table>
      )}
    </div>
  );
}

function FilterChip({ label, count, active, onClick }) {
  return (
    <button className={`op-filter-chip${active ? ' active' : ''}`} onClick={onClick}>
      {label}
      <span className="op-filter-count">{count}</span>
    </button>
  );
}

function EmptyQueue({ filter }) {
  const msg = filter === 'waiting'
    ? 'No sessions waiting for analysis. The queue will populate as consultants flip sessions to "Ready for analysis".'
    : filter === 'mine'
    ? "You haven't claimed any sessions yet. Pick one from the Waiting tab."
    : filter === 'bookings'
    ? 'No bookings yet. When prospects scan the QR code and book a slot, they will appear here.'
    : 'No activity yet today.';
  return (
    <div className="op-empty">
      <div className="op-empty-icon">⏳</div>
      <div>{msg}</div>
    </div>
  );
}

function ConsultationRow({ entry, deviceId, onClaim, onOpen }) {
  const sm = window.statusMeta(entry.status);
  const startedAt = entry.updatedAt ? new Date(entry.updatedAt) : null;
  const waitingMs = startedAt ? Date.now() - startedAt.getTime() : 0;
  const waitingMin = Math.floor(waitingMs / 60_000);
  const waitingClass = waitingMin >= 6 ? 'op-wait-critical' : waitingMin >= 3 ? 'op-wait-warning' : '';

  const isWaiting   = entry.status === 'ready_for_analysis';
  const isMine      = entry.claimedBy === deviceId;
  const isClaimed   = !!entry.claimedBy && !isMine;

  return (
    <tr>
      <td>
        <strong>{entry.org_name}</strong>
        {entry.client_name && <div className="op-row-sub">{entry.client_name}</div>}
        <div style={{ display: 'flex', gap: 8, marginTop: 2 }}>
          {entry.autofill_used && <span style={{ fontSize: 10.5, color: 'var(--brook-amber)', fontWeight: 600 }}>✦ AI-assisted</span>}
          {entry.audio?.fileId && <span style={{ fontSize: 10.5, color: 'var(--brook-teal)', fontWeight: 600 }} title={`Audio recording attached${entry.audio.durationSec ? ` (${window.fmtDuration(entry.audio.durationSec)})` : ''}`}>✎ Audio</span>}
          {entry.audio?.uploadStatus === 'uploading' && <span style={{ fontSize: 10.5, color: '#5eaaab', fontWeight: 600 }}>✎ Uploading {entry.audio.uploadProgress || 0}%</span>}
          {entry.audio?.uploadStatus === 'failed' && <span style={{ fontSize: 10.5, color: 'var(--danger)', fontWeight: 600 }}>✎ Upload failed</span>}
        </div>
      </td>
      <td style={{ fontSize: 12.5 }}>{entry.consultant_name || '—'}</td>
      <td style={{ fontSize: 12.5, color: 'var(--text-muted)' }}>
        {startedAt ? startedAt.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) : '—'}
      </td>
      <td>
        {isWaiting
          ? <span className={`op-wait ${waitingClass}`}>{waitingMin === 0 ? 'just now' : `${waitingMin} min`}</span>
          : <span style={{ color: 'var(--text-muted)', fontSize: 12 }}>—</span>}
      </td>
      <td>
        <span className="status-pill" style={{ color: sm.color, background: sm.bg }}>{sm.label}</span>
        {isClaimed && <div className="op-row-sub">claimed elsewhere</div>}
      </td>
      <td style={{ whiteSpace: 'nowrap', textAlign: 'right' }}>
        {isWaiting && (
          <button className="btn btn-amber" style={{ padding: '6px 14px', fontSize: 13, fontWeight: 600 }} onClick={() => onClaim(entry.id)}>
            Claim &amp; open →
          </button>
        )}
        {!isWaiting && isMine && (
          <button className="btn btn-primary" style={{ padding: '6px 14px', fontSize: 13 }} onClick={() => onOpen(entry.id)}>
            Resume
          </button>
        )}
        {!isWaiting && !isMine && (
          <button className="btn" style={{ padding: '6px 12px', fontSize: 12 }} onClick={() => onOpen(entry.id)}>
            Open
          </button>
        )}
      </td>
    </tr>
  );
}

function BookingRow({ entry, onConvertBooking, onMarkArrived, onOpen }) {
  const sm = window.statusMeta(entry.status);
  const slotDate = entry.slot_iso ? new Date(entry.slot_iso) : null;
  const slotLabel = slotDate
    ? slotDate.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
    : (entry.slot_label || '—');
  const slotPast = slotDate ? slotDate.getTime() < Date.now() : false;

  // Look up the booking detail from the underlying record so we can show
  // the headline challenge inline.
  const headlineChallenge = (entry._headline_challenge || '');

  return (
    <tr>
      <td>
        <strong>{slotLabel}</strong>
        {slotDate && <div className="op-row-sub">{slotDate.toLocaleDateString('en-GB', { day: 'numeric', month: 'short' })}</div>}
      </td>
      <td>
        <strong>{entry.org_name}</strong>
        {entry.org_type && <div className="op-row-sub">{entry.org_type}</div>}
      </td>
      <td style={{ fontSize: 12.5 }}>{entry.client_name || '—'}</td>
      <td style={{ fontSize: 12.5 }}>{entry.preferred_zone || '—'}</td>
      <td style={{ fontSize: 12.5, color: 'var(--text-soft)', maxWidth: 280 }}>
        {headlineChallenge || <span style={{ color: 'var(--text-muted)' }}>—</span>}
      </td>
      <td>
        <span className="status-pill" style={{ color: sm.color, background: sm.bg }}>{sm.label}</span>
      </td>
      <td style={{ whiteSpace: 'nowrap', textAlign: 'right' }}>
        {entry.status === 'booked' && (
          <>
            <button className="btn btn-amber" style={{ padding: '6px 12px', fontSize: 12, marginRight: 4 }} onClick={() => onConvertBooking(entry.id)}>
              Start consultation →
            </button>
            <button className="btn" style={{ padding: '6px 10px', fontSize: 12 }} onClick={() => onMarkArrived(entry.id)} title="Mark arrived (without starting yet)">
              Arrived
            </button>
          </>
        )}
        {entry.status === 'arrived' && (
          <button className="btn btn-amber" style={{ padding: '6px 12px', fontSize: 12 }} onClick={() => onConvertBooking(entry.id)}>
            Start consultation →
          </button>
        )}
        {entry.status === 'converted' && (
          <button className="btn" style={{ padding: '6px 10px', fontSize: 12 }} onClick={() => onOpen(entry.id)}>
            View booking
          </button>
        )}
      </td>
    </tr>
  );
}

Object.assign(window, { OperatorQueue });
