const { useState, useEffect, useCallback, useRef } = React;
const API = 'https://api.vocal.ch';

const api = {
  token: () => localStorage.getItem('center_token'),
  setToken: (t) => localStorage.setItem('center_token', t),
  clear: () => localStorage.removeItem('center_token'),
  async req(path, opts = {}) {
    const headers = { 'Content-Type': 'application/json', ...(opts.headers || {}) };
    const t = this.token(); if (t) headers['Authorization'] = 'Bearer ' + t;
    const r = await fetch(API + path, { ...opts, headers });
    if (r.status === 401) { this.clear(); location.reload(); return null; }
    return r.json();
  },
  get(p) { return this.req(p); },
  post(p, b) { return this.req(p, { method: 'POST', body: JSON.stringify(b || {}) }); },
};

const fmtDur = (s) => {
  const m = Math.floor(s / 60); const r = s % 60;
  return `${m}:${String(r).padStart(2, '0')}`;
};

function LoginView({ onLogin }) {
  const [email, setEmail] = useState('');
  const [code, setCode] = useState('');
  const [step, setStep] = useState('email');
  const [loading, setLoading] = useState(false);
  const [err, setErr] = useState(null);

  const sendCode = async () => {
    setLoading(true); setErr(null);
    try {
      const r = await api.post('/auth/request-code', { email });
      if (r?.error) setErr(r.error);
      else setStep('code');
    } catch (e) { setErr('Erreur réseau'); }
    finally { setLoading(false); }
  };
  const verify = async () => {
    setLoading(true); setErr(null);
    try {
      const r = await api.post('/auth/verify-code', { email, code });
      if (r?.error) setErr(r.error);
      else { api.setToken(r.token); onLogin(); }
    } catch (e) { setErr('Erreur réseau'); }
    finally { setLoading(false); }
  };
  return (
    <div className="login-card">
      <h1>Vocal Center</h1>
      <p>Centre de supervision live de vos lignes ouvertes</p>
      {err && <div style={{ color: 'var(--danger)', fontSize: '0.875rem', marginBottom: '0.75rem' }}>{err}</div>}
      {step === 'email' ? (
        <>
          <input type="email" placeholder="email@exemple.ch" value={email} onChange={e => setEmail(e.target.value)} />
          <button className="btn btn-primary" onClick={sendCode} disabled={loading || !email}>{loading ? 'Envoi…' : 'Recevoir le code'}</button>
        </>
      ) : (
        <>
          <input type="text" placeholder="Code reçu par email" value={code} onChange={e => setCode(e.target.value)} maxLength={6} />
          <button className="btn btn-primary" onClick={verify} disabled={loading || !code}>{loading ? 'Vérification…' : 'Connexion'}</button>
          <button className="btn" onClick={() => { setStep('email'); setCode(''); }} style={{ marginTop: '0.5rem' }}>Retour</button>
        </>
      )}
    </div>
  );
}

function Dashboard({ user, onLogout }) {
  const [calls, setCalls] = useState([]);
  const [tick, setTick] = useState(0);
  const [monitor, setMonitor] = useState(null); // { sessionId, callSid, mode }
  const [toast, setToast] = useState(null);
  const deviceRef = useRef(null);
  const callRef = useRef(null);

  const showToast = (msg, kind = 'success') => {
    setToast({ msg, kind });
    setTimeout(() => setToast(null), 3500);
  };

  const loadCalls = useCallback(async () => {
    const r = await api.get('/my/live/active-calls');
    setCalls(r?.active_calls || []);
  }, []);

  useEffect(() => { loadCalls(); }, [loadCalls]);
  useEffect(() => {
    const id = setInterval(() => { loadCalls(); setTick(t => t + 1); }, 3000);
    return () => clearInterval(id);
  }, [loadCalls]);

  const startMonitor = async (callSid, mode = 'monitor') => {
    try {
      const r = await api.post('/my/live/start', { call_sid: callSid, mode });
      if (r?.error) { showToast(r.error, 'error'); return; }
      const tokR = await api.get('/my/live/listen-token?session_id=' + r.session_id);
      if (tokR?.error) { showToast(tokR.error, 'error'); return; }
      const Device = window.Twilio?.Device;
      if (!Device) { showToast('SDK Twilio non chargé', 'error'); return; }
      if (deviceRef.current) { try { deviceRef.current.destroy(); } catch (e) {} }
      const dev = new Device(tokR.token, { logLevel: 1, codecPreferences: ['opus', 'pcmu'] });
      deviceRef.current = dev;
      await dev.register();
      const params = { conferenceName: tokR.conference_name, mode };
      const conn = await dev.connect({ params });
      callRef.current = conn;
      conn.on('disconnect', () => { setMonitor(null); callRef.current = null; });
      setMonitor({ sessionId: r.session_id, callSid, mode, conferenceName: tokR.conference_name });
      showToast('Surveillance active', 'success');
    } catch (e) {
      showToast('Erreur: ' + e.message, 'error');
    }
  };

  const stopMonitor = async () => {
    if (callRef.current) { try { callRef.current.disconnect(); } catch (e) {} callRef.current = null; }
    if (deviceRef.current) { try { await deviceRef.current.destroy(); } catch (e) {} deviceRef.current = null; }
    if (monitor) {
      await api.post('/my/live/sessions/' + monitor.sessionId + '/stop');
    }
    setMonitor(null);
    showToast('Surveillance arrêtée', 'success');
  };

  const stats = {
    active: calls.filter(c => c.status === 'in-progress').length,
    ringing: calls.filter(c => c.status === 'ringing').length,
    total: calls.length,
  };

  return (
    <div className="app">
      <div className="app-header">
        <h1>
          <span className="live-pulse"></span>
          Vocal Center
        </h1>
        <div className="user-info">
          <span>{user?.email}</span>
          {monitor && <span style={{ color: 'var(--primary)' }}>● Surveillance {monitor.mode} · {fmtDur(0)}</span>}
          <button className="btn btn-sm" onClick={onLogout}>Déconnexion</button>
        </div>
      </div>

      <div className="dashboard">
        <div className="stats-grid">
          <div className="stat-card"><div className="stat-label">Appels actifs</div><div className="stat-value live-color">{stats.active}</div></div>
          <div className="stat-card"><div className="stat-label">En sonnerie</div><div className="stat-value">{stats.ringing}</div></div>
          <div className="stat-card"><div className="stat-label">Total</div><div className="stat-value">{stats.total}</div></div>
        </div>

        <div className="section-title">Appels en cours · auto-refresh 3s</div>

        {calls.length === 0 ? (
          <div className="empty-state">
            <h2>Aucun appel en cours</h2>
            <p>Les appels actifs apparaîtront ici en temps réel.</p>
          </div>
        ) : (
          <div className="calls-grid">
            {calls.map(c => {
              const isMonitored = monitor?.callSid === c.call_sid;
              const elapsed = Math.floor((Date.now() - new Date(c.started_at + 'Z').getTime()) / 1000);
              return (
                <div key={c.call_sid} className={'call-card live' + (isMonitored ? ' monitoring' : '')}>
                  <div className="call-header">
                    <div>
                      <div className="call-from">{c.from_number || '?'}</div>
                      <div className="call-line">→ {c.line_label || c.line_phone}</div>
                    </div>
                    <span className={'call-status ' + c.status}>{c.status}</span>
                  </div>
                  <div className="call-meta">
                    <span>⏱ {fmtDur(elapsed)}</span>
                    <span>{c.direction === 'inbound' ? '↓ Entrant' : '↑ Sortant'}</span>
                    {c.bot_id && <span>🤖 Bot</span>}
                  </div>
                  <div className="call-actions">
                    {!isMonitored && (
                      <>
                        <button className="btn btn-sm btn-primary" onClick={() => startMonitor(c.call_sid, 'monitor')} title="Écouter discrètement">🎧 Écouter</button>
                        <button className="btn btn-sm" onClick={() => startMonitor(c.call_sid, 'whisper')} title="Souffler à l'agent">💬 Whisper</button>
                        <button className="btn btn-sm" onClick={() => startMonitor(c.call_sid, 'barge')} title="Prendre la main">📢 Barge-in</button>
                      </>
                    )}
                    {isMonitored && (
                      <button className="btn btn-sm btn-danger" onClick={stopMonitor}>■ Arrêter</button>
                    )}
                  </div>
                </div>
              );
            })}
          </div>
        )}
      </div>

      {toast && <div className={'toast ' + toast.kind}>{toast.msg}</div>}
    </div>
  );
}

function App() {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    if (!api.token()) { setLoading(false); return; }
    api.get('/my/profile').then(r => {
      if (r && !r.error) setUser(r.profile || r.user || { email: 'connecté' });
      setLoading(false);
    });
  }, []);

  if (loading) return <div style={{ padding: '4rem', textAlign: 'center', color: 'var(--text-muted)' }}><div className="spinner"></div></div>;
  if (!user) return <LoginView onLogin={() => { window.location.reload(); }} />;
  return <Dashboard user={user} onLogout={() => { api.clear(); setUser(null); }} />;
}

ReactDOM.createRoot(document.getElementById('root')).render(<App />);
