// AAP — Main app (QA testure — branch feat/interface-testure-qa)
const { useState, useRef, useEffect } = React;

// ============================================================
// QA Tracking helpers
// ============================================================
const QA_SESSION_UUID = crypto.randomUUID();
const QA_ACCESS_CODE  = 'QA-aap-v8@2026';

// Lire les params URL ?tester=Jeremy&email=jeremy@...
function getUrlParam(key) {
  return new URLSearchParams(window.location.search).get(key) || '';
}
const QA_TESTER = {
  name:  getUrlParam('tester') || localStorage.getItem('qa_tester_name') || 'Jeremy',
  email: getUrlParam('email')  || localStorage.getItem('qa_tester_email') || 'jeremy.garcia@calipso-assurances.fr',
};
if (getUrlParam('tester')) localStorage.setItem('qa_tester_name',  QA_TESTER.name);
if (getUrlParam('email'))  localStorage.setItem('qa_tester_email', QA_TESTER.email);

// Fire-and-forget — silencieux si le serveur QA est indisponible
function track(event, data) {
  try {
    const body = JSON.stringify({
      event,
      session_uuid:  QA_SESSION_UUID,
      tester_name:   QA_TESTER.name,
      tester_email:  QA_TESTER.email,
      ...(data || {}),
    });
    if (event === 'session_end') {
      // sendBeacon garantit l'envoi même si l'onglet se ferme
      navigator.sendBeacon('/track', new Blob([body], { type: 'application/json' }));
    } else {
      fetch('/track', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body })
        .catch(() => {});
    }
  } catch (_) {}
}

// ============================================================
// App principale
// ============================================================
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
  "accentColor": "#2D6BFF",
  "showParticles": true,
  "density": "comfortable"
}/*EDITMODE-END*/;

function App() {
  const [tweaks, setTweak] = window.useTweaks ? window.useTweaks(TWEAK_DEFAULTS) : [TWEAK_DEFAULTS, () => {}];

  // ── Login gate ──
  const [unlocked, setUnlocked] = useState(
    localStorage.getItem('qa_unlocked') === 'true'
  );

  // ── Chat state ──
  const [conv, setConv]             = useState([]); // {role:'user'|'ai', text, status?, latency_ms?, score?}
  const [streaming, setStreaming]   = useState(false);
  const [activeId, setActiveId]     = useState(null);  // session_id AAP actif
  const [conversations, setConversations] = useState([]); // sessions réelles depuis ia_aap_sessions
  const [issuesOpen, setIssuesOpen] = useState(false);
  const [issues, setIssues]         = useState(() => window.loadIssues ? window.loadIssues() : []);
  const [draftQuote, setDraftQuote] = useState(null);
  const scrollRef = useRef(null);

  useEffect(() => { if (window.saveIssues) window.saveIssues(issues); }, [issues]);

  useEffect(() => {
    if (tweaks.accentColor) {
      document.documentElement.style.setProperty('--accent', tweaks.accentColor);
    }
  }, [tweaks.accentColor]);

  useEffect(() => {
    if (scrollRef.current) scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
  });

  // Tracking session au déverrouillage
  useEffect(() => {
    if (!unlocked) return;
    track('session_start');
    const onUnload = () => track('session_end');
    window.addEventListener('beforeunload', onUnload);
    return () => window.removeEventListener('beforeunload', onUnload);
  }, [unlocked]);

  // Chargement de l'historique réel depuis ia_aap_sessions
  const refreshConversations = () => {
    fetch(`/conversations?email=${encodeURIComponent(QA_TESTER.email)}`)
      .then(r => r.ok ? r.json() : { conversations: [] })
      .then(d => setConversations(d.conversations || []))
      .catch(() => {});
  };
  useEffect(() => {
    if (!unlocked) return;
    refreshConversations();
  }, [unlocked]);

  // ── Handlers ──
  const handleUnlock = () => {
    localStorage.setItem('qa_unlocked', 'true');
    setUnlocked(true);
  };

  // Appel réel à l'AAP via le proxy QA (tracking_server.py)
  const handleSend = async (text) => {
    if (streaming) return;
    setConv(c => [...c, { role: 'user', text }]);
    setStreaming(true);

    try {
      const res = await fetch('/ask', {
        method:  'POST',
        headers: { 'Content-Type': 'application/json' },
        body:    JSON.stringify({
          question:     text,
          email:        QA_TESTER.email,   // suivi QA interne
          user_email:   QA_TESTER.email,   // champ attendu par l'AAP
          session_id:   activeId || '',     // sessionId AAP — vide = nouvelle session
          session_uuid: QA_SESSION_UUID,
          tester_name:  QA_TESTER.name,
          qa_code:      QA_ACCESS_CODE,
        }),
      });

      if (!res.ok) {
        const err = await res.json().catch(() => ({ detail: `HTTP ${res.status}` }));
        throw new Error(err.detail || `Erreur ${res.status}`);
      }

      const data = await res.json();
      // Mettre à jour le session_id AAP — pour continuer la même conversation
      if (data.session_id && !activeId) {
        setActiveId(data.session_id);
      }
      setConv(c => [...c, {
        role:       'ai',
        text:       data.response || '(Aucune réponse)',
        status:     data.status,
        latency_ms: data.latency_ms,
        score:      data.watchdog_score,
        animate:    true,
      }]);
    } catch (err) {
      setConv(c => [...c, {
        role:   'ai',
        text:   `⚠️ Erreur lors de la connexion à l'AAP : ${err.message}`,
        status: 'FAILED',
      }]);
    } finally {
      setStreaming(false);
      // Rafraîchir la sidebar — l'AAP a pu créer une nouvelle session
      refreshConversations();
    }
  };

  // Charger une conversation existante depuis ia_chat_history
  const handleSelectConv = async (session_id) => {
    if (streaming) return;
    setActiveId(session_id);
    setStreaming(true);
    try {
      const res = await fetch(`/conversations/${session_id}`);
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const data = await res.json();
      const loaded = (data.messages || []).map(m => ({
        role: m.role === 'human' ? 'user' : 'ai',
        text: m.content || '',
      }));
      setConv(loaded);
    } catch (e) {
      // Si la conversation ne charge pas, on reste sur l'état actuel
    } finally {
      setStreaming(false);
    }
  };

  const handleNew = () => {
    setConv([]);
    setStreaming(false);
    setActiveId(null);
  };

  const empty = conv.length === 0;
  const openWithDraft = (quote) => { setDraftQuote(quote || null); setIssuesOpen(true); };
  const activeCount = issues.filter(i => !i.resolved).length;

  // ── Login gate ──
  if (!unlocked) {
    return <LoginGate onUnlock={handleUnlock} />;
  }

  return (
    <div className="app">
      <Sidebar
        activeId={activeId}
        onNew={handleNew}
        onSelect={handleSelectConv}
        conversations={conversations}
        testerName={QA_TESTER.name}
      />
      <div className="main">
        <div className="chat-header">
          <div className="chat-title-wrap">
            <div className="live-dot"/>
            <div className="chat-title">
              AAP · Assistant Calipso
              <span className="sub">
                {empty
                  ? `Session QA — ${QA_TESTER.name}`
                  : `${conv.filter(m => m.role === 'user').length} message(s)`}
              </span>
            </div>
          </div>
          <div className="header-actions">
            <button
              className={"issues-toggle" + (activeCount > 0 ? ' has-items' : '')}
              onClick={() => setIssuesOpen(true)}
              title="Banc de test — anomalies"
            >
              <svg width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                <path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1z"/>
                <line x1="4" y1="22" x2="4" y2="15"/>
              </svg>
              Banc de test
              <span className="badge">{issues.length}</span>
            </button>
            <span className="chip green"><Icon.Check s={10}/> Modèle v3.4</span>
          </div>
        </div>

        <div className="messages-wrap" ref={scrollRef}>
          {empty ? (
            <Welcome onPick={handleSend}/>
          ) : (
            <div className="messages">
              {conv.map((m, i) => {
                if (m.role === 'user') return <UserMessage key={i} text={m.text}/>;
                return (
                  <AAPResponse
                    key={i}
                    text={m.text}
                    status={m.status}
                    latencyMs={m.latency_ms}
                    score={m.score}
                    animate={m.animate === true}
                    onFlag={(quote) => openWithDraft(quote)}
                  />
                );
              })}
              {streaming && <AAPResponse key="loading" text="" streaming={true} onFlag={() => {}}/>}
            </div>
          )}
        </div>

        <Composer onSend={handleSend} streaming={streaming} onStop={() => setStreaming(false)}/>
      </div>

      {window.IssuesDrawer && (
        <window.IssuesDrawer
          open={issuesOpen}
          onClose={() => { setIssuesOpen(false); setDraftQuote(null); }}
          issues={issues}
          setIssues={setIssues}
          draftFromMessage={draftQuote}
          clearDraft={() => setDraftQuote(null)}
          sessionUuid={QA_SESSION_UUID}
          testerName={QA_TESTER.name}
          testerEmail={QA_TESTER.email}
        />
      )}

      {window.TweaksPanel && (
        <window.TweaksPanel title="Tweaks QA">
          <window.TweakSection title="Apparence">
            <window.TweakColor label="Couleur d'accent" value={tweaks.accentColor} onChange={v => setTweak('accentColor', v)}/>
            <window.TweakToggle label="Particules animées" value={tweaks.showParticles} onChange={v => setTweak('showParticles', v)}/>
          </window.TweakSection>
        </window.TweaksPanel>
      )}
    </div>
  );
}

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