// Five Nodes Hospital — Patient pipeline kanban
const { useState: useStateP, useEffect: useEffectP, useCallback: useCallbackP } = React;

const STATUS_TO_STAGE = {
  new: 'new', contacted: 'contacted', booked: 'booked',
  attended: 'attended', no_show: 'no_show', cancelled: 'no_show', cold: 'no_show'
};
function statusToStage(s) { return STATUS_TO_STAGE[s] || null; }
function daysSince(iso) { return !iso ? 0 : Math.max(0, Math.floor((Date.now() - new Date(iso).getTime()) / 86400000)); }
function displayName(p) { return (p.name && p.name !== 'New Patient') ? p.name : 'New patient · ' + String(p.phone || '').slice(-5); }

function specialtyName(code) {
  const s = (window.__data.specialties || []).find(x => x.code === code);
  return s ? s.name : (code || '—');
}

function mapLivePatient(p, analysis) {
  const stage = statusToStage(p.status);
  if (!stage) return null;
  const reason = analysis?.reason_for_visit || p.reason_for_visit || '—';
  return {
    id: 'live-' + p.id,
    liveId: p.id, livePhone: p.phone,
    isLive: true,
    stage, name: displayName(p),
    reason,
    specialty: analysis?.preferred_specialty || p.preferred_specialty || '',
    score: analysis?.lead_score || 3,
    days: daysSince(p.created_at),
    src: (p.source || 'web').slice(0, 4)
  };
}

const PatientCard = ({ p, dragging, onDragStart, onDragEnd }) => {
  const isHot = p.score >= 4;
  return (
    <div className={`lead-card ${dragging ? 'dragging' : ''}`}
      draggable
      onDragStart={(e) => { e.dataTransfer.effectAllowed = 'move'; onDragStart(p.id); }}
      onDragEnd={onDragEnd}>
      <div className="top">
        <div style={{ flex: 1, minWidth: 0 }}>
          <div className="name" style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
            {p.name}
            {!p.isLive && <span style={{ fontSize: 8, fontWeight: 600, padding: '1px 5px', borderRadius: 3, background: 'rgba(180,83,9,0.14)', color: 'var(--warn)', letterSpacing: '0.04em' }}>DEMO</span>}
          </div>
          <div className="program">{p.reason}</div>
        </div>
      </div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end' }}>
        <div className="mono" style={{ fontSize: 10, color: 'var(--fg-3)', letterSpacing: '0.06em', textTransform: 'uppercase' }}>{specialtyName(p.specialty)}</div>
        <span className={`score ${isHot ? 'hot' : ''}`}>
          {isHot ? 'HOT' : 'WARM'}
          <span className="bar">{[0,1,2,3,4].map(i => <i key={i} className={i < p.score ? 'on' : ''} />)}</span>
        </span>
      </div>
      <div className="foot">
        <div className="a">AI</div>
        <span>{p.src || 'Web'}</span>
        <span>{p.days}d</span>
      </div>
    </div>
  );
};

const Patients = () => {
  const t = (k) => window.__t ? window.__t(k) : k;
  const mockPatients = window.__data.patients.map(p => ({ ...p, isLive: false }));
  const [livePatients, setLivePatients] = useStateP([]);
  const [liveLoading, setLiveLoading] = useStateP(true);
  const [draggedId, setDraggedId] = useStateP(null);
  const [hoverStage, setHoverStage] = useStateP(null);
  // Translate stage labels from translations dictionary
  const STAGE_LABELS = {
    new: t('patients.col.new'), contacted: t('patients.col.contacted'),
    booked: t('patients.col.booked'), attended: t('patients.col.attended'),
    no_show: t('patients.col.noshow')
  };
  const stages = window.__data.patientStages.map(s => ({ ...s, label: STAGE_LABELS[s.key] || s.label }));

  const loadLive = useCallbackP(async () => {
    try {
      const user = await window.__api.getUser();
      if (!user) { setLivePatients([]); setLiveLoading(false); return; }
      const [patientRows, analysisRows] = await Promise.all([
        window.__api.sbGet('hsp_patients', {
          'select': 'id,phone,name,status,source,reason_for_visit,preferred_specialty,created_at,updated_at',
          'order': 'updated_at.desc', 'limit': '100'
        }).catch(() => []),
        window.__api.sbGet('hsp_conversation_analysis', {
          'select': 'phone_number,lead_score,preferred_specialty,reason_for_visit,priority',
          'order': 'analyzed_at.desc', 'limit': '200'
        }).catch(() => [])
      ]);
      const byPhone = {};
      (analysisRows || []).forEach(a => { if (!byPhone[a.phone_number]) byPhone[a.phone_number] = a; });
      const mapped = (patientRows || []).map(p => mapLivePatient(p, byPhone[p.phone])).filter(Boolean);
      setLivePatients(mapped);
    } catch (e) { console.warn('[patients]', e.message); }
    finally { setLiveLoading(false); }
  }, []);

  useEffectP(() => {
    loadLive();
    const id = setInterval(loadLive, 30000);
    const onFocus = () => loadLive();
    window.addEventListener('focus', onFocus);
    return () => { clearInterval(id); window.removeEventListener('focus', onFocus); };
  }, [loadLive]);

  const allPatients = [...livePatients, ...mockPatients];

  const onDrop = async (e, stageKey) => {
    e.preventDefault(); setHoverStage(null);
    const id = draggedId; setDraggedId(null);
    if (!id || !id.startsWith('live-')) return;
    const p = livePatients.find(x => x.id === id);
    if (!p) return;
    setLivePatients(prev => prev.map(x => x.id === id ? { ...x, stage: stageKey } : x));
    try {
      await window.__api.sbPatch('hsp_patients', { id: 'eq.' + p.liveId }, { status: stageKey });
    } catch (err) { console.warn('[patient patch]', err.message); loadLive(); }
  };

  return (
    <div className="content view">
      <div className="section-head">
        <div>
          <div className="sub">
            {allPatients.length} {t('patients.sub')}
            {livePatients.length > 0 && <> · <span style={{ color: 'var(--accent-deep)' }}>{livePatients.length} {t('patients.live')}</span></>}
          </div>
          <h2>{t('patients.title').replace(t('patients.title.em'), '').trim()} <em>{t('patients.title.em')}</em></h2>
        </div>
        <button className="btn" onClick={loadLive} disabled={liveLoading}>{liveLoading ? <span className="spinner sm" /> : <Icon name="filter" size={12} />} {liveLoading ? '' : t('common.refresh')}</button>
      </div>

      <div className="kanban">
        {stages.map((s) => {
          const sPats = allPatients.filter(p => p.stage === s.key);
          return (
            <div key={s.key} className={`col ${hoverStage === s.key ? 'drop-target' : ''}`}
              onDragOver={(e) => { e.preventDefault(); setHoverStage(s.key); }}
              onDragLeave={() => setHoverStage(h => h === s.key ? null : h)}
              onDrop={(e) => onDrop(e, s.key)}>
              <div className="col-head">
                <div className="row">
                  <div className="name"><span className={`dot ${s.key === 'attended' ? 'win' : ''}`} />{s.label}</div>
                  <div className="count">{sPats.length}</div>
                </div>
              </div>
              <div className="col-body">
                {sPats.map(p => <PatientCard key={p.id} p={p} dragging={draggedId === p.id} onDragStart={setDraggedId} onDragEnd={() => { setDraggedId(null); setHoverStage(null); }} />)}
                {sPats.length === 0 && <div className="col-empty">{t('patients.empty')}</div>}
              </div>
            </div>
          );
        })}
      </div>
      <div style={{ marginTop: 18, fontFamily: 'var(--mono)', fontSize: 9.5, color: 'var(--fg-4)', textTransform: 'uppercase', letterSpacing: '0.12em' }}>
        {t('patients.tip')}
      </div>
    </div>
  );
};

window.Patients = Patients;
