// Botman App - PWA mobile inbox WhatsApp
const { useState, useEffect, useCallback, useRef } = React;

const API_URL = (() => {
  const p = new URLSearchParams(location.search);
  if (p.get('api')) return p.get('api').replace(/\/$/, '');
  if (location.hostname === 'localhost' || location.hostname === '127.0.0.1') return 'http://127.0.0.1:8787';
  // api.botman.ch : activer quand le DNS est configuré ; workers.dev en attendant
  return 'https://ch-botman-api.yannick-zoller.workers.dev';
})();

const STORAGE_TOKEN = 'botman_app_token';
const STORAGE_USER = 'botman_app_user';

const api = {
  token: null,
  async req(path, opts = {}) {
    const h = { 'Content-Type': 'application/json', ...opts.headers };
    if (this.token) h.Authorization = `Bearer ${this.token}`;
    return fetch(`${API_URL}${path}`, { ...opts, headers: h }).then(r => r.json());
  },
  get: p => api.req(p),
  post: (p, b) => api.req(p, { method: 'POST', body: JSON.stringify(b) }),
};

const IconChat = () => (
  <svg viewBox="0 0 24 24" fill="currentColor"><path d="M12 2C6.48 2 2 6.15 2 11c0 1.66.44 3.22 1.21 4.6L2 22l6.5-1.7c1.28.7 2.73 1.1 4.25 1.1 5.52 0 10-4.15 10-9.25S17.52 2 12 2z"/></svg>
);
const IconUser = () => (
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 4-6 8-6s8 2 8 6"/></svg>
);

function fmtTime(s) {
  if (!s) return '';
  const d = new Date(s.endsWith('Z') ? s : s + 'Z');
  return d.toLocaleTimeString('fr-CH', { hour: '2-digit', minute: '2-digit' });
}

function initials(name, phone) {
  const n = name || phone || '?';
  return n.replace(/[^a-zA-Z0-9]/g, '').slice(0, 2).toUpperCase() || '?';
}

// ==================== AUTH ====================
function AuthView({ onLogin }) {
  const [step, setStep] = useState('email');
  const [email, setEmail] = useState('');
  const [code, setCode] = useState('');
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState('');

  useEffect(() => {
    const p = new URLSearchParams(location.search);
    const e = p.get('email');
    const c = p.get('code');
    if (e && c) {
      setLoading(true);
      fetch(`${API_URL}/auth/verify-code`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email: e.toLowerCase(), code: c }),
      })
        .then(r => r.json())
        .then(data => {
          history.replaceState({}, '', location.pathname);
          if (data.success && data.token) onLogin(data.token, data.user);
          else setError(data.error || 'Lien expiré');
        })
        .catch(() => setError('Erreur réseau'))
        .finally(() => setLoading(false));
    } else if (e) { setEmail(e); setStep('code'); }
  }, []);

  const requestCode = async () => {
    if (!email.includes('@')) { setError('Email invalide'); return; }
    setLoading(true); setError('');
    try {
      const resp = await fetch(`${API_URL}/auth/request-code`, {
        method: 'POST', headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email: email.toLowerCase().trim() }),
      });
      const r = await resp.json();
      if (r.success) setStep('code'); else setError(r.error || 'Erreur');
    } catch {
      setError('Impossible de joindre l\'API. Réessayez dans un instant.');
    } finally {
      setLoading(false);
    }
  };

  const verify = async () => {
    setLoading(true); setError('');
    try {
      const resp = await fetch(`${API_URL}/auth/verify-code`, {
        method: 'POST', headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ email: email.toLowerCase().trim(), code: code.trim() }),
      });
      const r = await resp.json();
      if (r.success && r.token) onLogin(r.token, r.user);
      else setError(r.error || 'Code invalide');
    } catch {
      setError('Impossible de joindre l\'API. Réessayez dans un instant.');
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="auth-wrap">
      <div className="auth-box">
        <div className="auth-logo"><span className="icon">💬</span> Botman</div>
        <p style={{ color: 'var(--muted)', fontSize: '0.9rem', marginBottom: '1rem' }}>
          {step === 'email' ? 'Connexion à votre inbox WhatsApp' : 'Code reçu par email'}
        </p>
        {error && <p style={{ color: '#ea0038', fontSize: '0.85rem', marginBottom: '0.5rem' }}>{error}</p>}
        {step === 'email' ? (
          <>
            <input className="auth-input" type="email" placeholder="votre@email.ch" value={email}
              onChange={e => setEmail(e.target.value)} autoComplete="email" />
            <button className="btn-wa" disabled={loading} onClick={requestCode}>{loading ? '…' : 'Recevoir le code'}</button>
          </>
        ) : (
          <>
            <input className="auth-input" type="text" inputMode="numeric" placeholder="Code" value={code}
              onChange={e => setCode(e.target.value)} autoComplete="one-time-code" />
            <button className="btn-wa" disabled={loading} onClick={verify}>{loading ? '…' : 'Connexion'}</button>
            <button className="btn-ghost" onClick={() => { setStep('email'); setCode(''); }}>Changer d'email</button>
          </>
        )}
      </div>
    </div>
  );
}

// ==================== CHAT LIST ====================
function ChatListView({ onSelect }) {
  const [list, setList] = useState([]);
  const [loading, setLoading] = useState(true);

  const load = useCallback(async (silent) => {
    if (!silent) setLoading(true);
    const r = await api.get('/conversations');
    setList(r.conversations || []);
    setLoading(false);
  }, []);

  useEffect(() => {
    load();
    const id = setInterval(() => load(true), 10000);
    return () => clearInterval(id);
  }, [load]);

  if (loading) return <div className="empty">Chargement…</div>;
  if (!list.length) return <div className="empty">Aucune conversation pour l'instant.</div>;

  return (
    <div className="conv-list">
      {list.map(c => (
        <div key={c.id} className="conv-row" onClick={() => onSelect(c)}>
          <div className="conv-avatar">{initials(c.contact_name, c.contact_number)}</div>
          <div className="conv-body">
            <div className="conv-top">
              <span className="conv-name">{c.contact_name || c.contact_number}</span>
              <span className="conv-time">{fmtTime(c.last_message_at)}</span>
            </div>
            <div className="conv-preview">{c.last_message_body || '(média)'}</div>
          </div>
          {c.unread_count > 0 && <span className="badge">{c.unread_count}</span>}
        </div>
      ))}
    </div>
  );
}

// ==================== THREAD ====================
function ThreadView({ conv, onBack }) {
  const [messages, setMessages] = useState([]);
  const [draft, setDraft] = useState('');
  const [sending, setSending] = useState(false);
  const scrollRef = useRef(null);

  const load = useCallback(async (silent) => {
    const r = await api.get(`/conversations/${conv.id}/messages`);
    setMessages(r.messages || []);
    if (!silent) setTimeout(() => { if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight; }, 40);
  }, [conv.id]);

  useEffect(() => {
    load();
    const id = setInterval(() => load(true), 8000);
    return () => clearInterval(id);
  }, [load]);

  const send = async () => {
    const text = draft.trim();
    if (!text) return;
    setSending(true);
    const r = await api.post(`/conversations/${conv.id}/reply`, { body: text, take_over: 1 });
    setSending(false);
    if (!r.error) { setDraft(''); load(); }
  };

  return (
    <>
      <header className="app-header">
        <button type="button" className="back" onClick={onBack}>←</button>
        <h1>{conv.contact_name || conv.contact_number}</h1>
      </header>
      <div className="thread" ref={scrollRef}>
        {messages.map(m => (
          <div key={m.id} className={`msg ${m.direction === 'outbound' ? 'out' : 'in'}`}>
            {m.body || '📎 Média'}
            <div className="msg-meta">{fmtTime(m.created_at)}{m.sent_by === 'bot' ? ' · bot' : ''}</div>
          </div>
        ))}
      </div>
      <div className="compose-bar">
        <textarea rows={1} placeholder="Message…" value={draft}
          onChange={e => setDraft(e.target.value)}
          onKeyDown={e => { if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); send(); } }} />
        <button type="button" className="send-btn" disabled={sending || !draft.trim()} onClick={send}>➤</button>
      </div>
    </>
  );
}

// ==================== ACCOUNT ====================
function AccountView({ user, onLogout }) {
  return (
    <div className="account">
      <div className="account-card">
        <strong>{user.name || user.email}</strong>
        <span>{user.email}</span>
      </div>
      <p style={{ fontSize: '0.85rem', color: 'var(--muted)', marginBottom: '1rem' }}>
        Version app mobile Botman
      </p>
      <a href="https://my.botman.ch" style={{ display: 'block', marginBottom: '0.75rem', color: 'var(--wa-dark)', fontWeight: 600 }}>
        Ouvrir la version desktop →
      </a>
      <button className="btn-wa" style={{ background: '#667781' }} onClick={onLogout}>Déconnexion</button>
    </div>
  );
}

// ==================== APP ====================
function App() {
  const [user, setUser] = useState(null);
  const [booting, setBooting] = useState(true);
  const [tab, setTab] = useState('chats');
  const [activeConv, setActiveConv] = useState(null);
  const [toast, setToast] = useState(null);

  useEffect(() => {
    const token = localStorage.getItem(STORAGE_TOKEN);
    const saved = localStorage.getItem(STORAGE_USER);
    if (token) {
      api.token = token;
      if (saved) try { setUser(JSON.parse(saved)); } catch {}
      api.get('/me').then(r => {
        if (r.error) {
          localStorage.removeItem(STORAGE_TOKEN);
          localStorage.removeItem(STORAGE_USER);
          api.token = null;
          setUser(null);
        } else if (r.user) setUser(r.user);
      }).finally(() => setBooting(false));
    } else setBooting(false);
  }, []);

  const onLogin = (token, u) => {
    api.token = token;
    localStorage.setItem(STORAGE_TOKEN, token);
    localStorage.setItem(STORAGE_USER, JSON.stringify(u));
    setUser(u);
  };

  const onLogout = () => {
    localStorage.removeItem(STORAGE_TOKEN);
    localStorage.removeItem(STORAGE_USER);
    api.token = null;
    setUser(null);
    setActiveConv(null);
  };

  if (booting) return <div className="app-loading"><div className="spinner" /></div>;
  if (!user) return <AuthView onLogin={onLogin} />;

  if (activeConv) {
    return (
      <div className="app-root">
        <ThreadView conv={activeConv} onBack={() => setActiveConv(null)} />
      </div>
    );
  }

  return (
    <div className="app-root">
      <header className="app-header">
        <h1>{tab === 'chats' ? 'Conversations' : 'Compte'}</h1>
      </header>
      <main className="app-main">
        {tab === 'chats' && <ChatListView onSelect={setActiveConv} />}
        {tab === 'account' && <AccountView user={user} onLogout={onLogout} />}
      </main>
      <nav className="bottom-nav">
        <button type="button" className={`nav-tab ${tab === 'chats' ? 'active' : ''}`} onClick={() => setTab('chats')}>
          <IconChat /> Chats
        </button>
        <button type="button" className={`nav-tab ${tab === 'account' ? 'active' : ''}`} onClick={() => setTab('account')}>
          <IconUser /> Compte
        </button>
      </nav>
      {toast && <div className="toast">{toast}</div>}
    </div>
  );
}

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