/**
 * ChatGuide.jsx — chat post-paiement avec l'agent GUIDE.
 *
 * Differences avec Chat.jsx (qualification pre-paiement) :
 *  - Source des messages : SSE persistant /api/dossiers/:id/guide/stream
 *    (Supabase Realtime sous le capot, push spontane des transitions)
 *  - Envoi user : POST /api/dossiers/:id/guide/chat -> SSE response
 *  - Affichage : stepper pipeline 5 etapes en haut
 *  - A delivered : encart "Rapport pret" avec bouton telechargement
 */
/* eslint-disable */
const { useState, useEffect, useRef, useCallback } = React;

const PIPELINE = [
  { key: 'paid', label: 'Paiement' },
  { key: 'analysing', label: 'Analyse' },
  { key: 'reviewing', label: 'Juriste' },
  { key: 'challenging', label: 'Verification' },
  { key: 'drafting', label: 'Redaction' },
  { key: 'delivered', label: 'Livre' }
];

function pipelineIndex(statut) {
  return PIPELINE.findIndex((s) => s.key === statut);
}

function formatText(text) {
  if (!text) return '';
  // Basic markdown: **bold**, line breaks, lists
  return String(text)
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/\*\*(.+?)\*\*/g, '<strong>$1</strong>')
    .replace(/^- (.+)$/gm, '• $1')
    .replace(/\n/g, '<br/>');
}

function ChatGuide({ dossierId, accessToken, initialPortalData }) {
  const [messages, setMessages] = useState([]);
  const [statut, setStatut] = useState(initialPortalData?.dossier?.statut || 'paid');
  const [rapportUrl, setRapportUrl] = useState(initialPortalData?.rapport_url || null);
  const [email, setEmail] = useState(initialPortalData?.dossier?.email || '');
  const [input, setInput] = useState('');
  const [isSending, setIsSending] = useState(false);
  const [streamError, setStreamError] = useState(null);
  // Garantie PJ + expert partenaire
  const [garantiePjStatus, setGarantiePjStatus] = useState(initialPortalData?.dossier?.garantie_pj_status || null);
  const [expertRequestedAt, setExpertRequestedAt] = useState(initialPortalData?.dossier?.expert_partenaire_requested_at || null);
  const [expertRequesting, setExpertRequesting] = useState(false);
  const messagesEndRef = useRef(null);
  const inputRef = useRef(null);
  const seenIdsRef = useRef(new Set()); // dedup messages on reconnect

  // ── Auto-scroll ───────────────────────────────────────
  useEffect(() => {
    messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [messages.length]);

  // ── SSE persistant : ecoute les messages du GUIDE ────
  useEffect(() => {
    if (!dossierId) return;

    let cancelled = false;
    let abortCtrl = new AbortController();

    async function listen() {
      try {
        const res = await fetch(`/api/dossiers/${dossierId}/guide/stream`, {
          signal: abortCtrl.signal
        });
        if (!res.ok) {
          setStreamError(`Stream HTTP ${res.status}`);
          return;
        }
        const reader = res.body.getReader();
        const decoder = new TextDecoder();
        let buffer = '';

        while (!cancelled) {
          const { done, value } = await reader.read();
          if (done) break;
          buffer += decoder.decode(value, { stream: true });

          // SSE separator = blank line ("\n\n")
          const lines = buffer.split('\n\n');
          buffer = lines.pop() || '';

          for (const block of lines) {
            const line = block.split('\n').find((l) => l.startsWith('data: '));
            if (!line) continue;
            try {
              const evt = JSON.parse(line.slice(6));
              handleEvent(evt);
            } catch (_) { /* ignore */ }
          }
        }
      } catch (err) {
        if (err.name !== 'AbortError') {
          console.error('[ChatGuide] stream error:', err.message);
          setStreamError(err.message);
        }
      }
    }

    function handleEvent(evt) {
      if (evt.type === 'message') {
        const msg = evt; // already in shape { role, content, kind, transition, ts, ... }
        // Dedup via ts+kind (replay can re-emit historique)
        const id = `${msg.ts || ''}|${msg.kind || ''}|${(msg.content || '').slice(0, 50)}`;
        if (seenIdsRef.current.has(id)) return;
        seenIdsRef.current.add(id);

        setMessages((prev) => [...prev, msg]);

        // Update statut from transition meta
        if (msg.transition && msg.transition.to) {
          setStatut(msg.transition.to);
        }
      } else if (evt.type === 'done') {
        // pipeline final reached
        if (evt.final_statut) setStatut(evt.final_statut);
      } else if (evt.type === 'warn') {
        setStreamError(evt.message || 'Realtime indisponible');
      } else if (evt.type === 'error') {
        setStreamError(evt.message || 'Erreur stream');
      }
    }

    listen();

    return () => {
      cancelled = true;
      abortCtrl.abort();
    };
  }, [dossierId]);

  // ── Fetch infos dossier (rapport_url + email + statut + PJ) ──
  useEffect(() => {
    if (!dossierId) return;
    let interval;
    async function poll() {
      try {
        const res = await fetch(`/api/session/${dossierId}`);
        if (!res.ok) return;
        const data = await res.json();
        if (data.statut) setStatut(data.statut);
        if (data.rapport_url) setRapportUrl(data.rapport_url);
        if (data.email) setEmail(data.email);
        if (data.garantie_pj_status !== undefined) setGarantiePjStatus(data.garantie_pj_status);
        if (data.expert_partenaire_requested_at !== undefined) setExpertRequestedAt(data.expert_partenaire_requested_at);
        if (data.statut === 'delivered' && interval) clearInterval(interval);
      } catch (_) {}
    }
    poll();
    interval = setInterval(poll, 8000);
    return () => clearInterval(interval);
  }, [dossierId]);

  // ── Demande mise en relation expert partenaire ─────────
  const requestExpert = useCallback(async () => {
    if (expertRequesting || expertRequestedAt) return;
    if (!confirm('Confirmer : demander une mise en relation avec Fabien Berthier (expert d\'assure CoCREATA) ? Il vous contactera sous 48h.')) return;

    setExpertRequesting(true);
    try {
      const body = accessToken ? { token: accessToken } : {};
      const res = await fetch(`/api/dossiers/${dossierId}/expert-request`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body)
      });
      const data = await res.json();
      if (!res.ok) {
        alert(data.error || 'Erreur lors de la demande');
        return;
      }
      setExpertRequestedAt(data.requested_at || new Date().toISOString());
    } catch (err) {
      alert('Erreur reseau : ' + err.message);
    } finally {
      setExpertRequesting(false);
    }
  }, [dossierId, accessToken, expertRequesting, expertRequestedAt]);

  // ── Envoi d'une question au GUIDE ─────────────────────
  const sendQuestion = useCallback(async (text) => {
    const userText = (text || input).trim();
    if (!userText || isSending) return;

    const sanitized = userText.replace(/</g, '&lt;').replace(/>/g, '&gt;').slice(0, 5000);

    setMessages((prev) => [
      ...prev,
      { role: 'user', content: sanitized, ts: new Date().toISOString(), local: true }
    ]);
    setInput('');
    setIsSending(true);

    try {
      const res = await fetch(`/api/dossiers/${dossierId}/guide/chat`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ message: sanitized })
      });
      if (!res.ok) throw new Error(`HTTP ${res.status}`);

      const reader = res.body.getReader();
      const decoder = new TextDecoder();
      let buffer = '';

      while (true) {
        const { done, value } = await reader.read();
        if (done) break;
        buffer += decoder.decode(value, { stream: true });
        const lines = buffer.split('\n\n');
        buffer = lines.pop() || '';
        for (const block of lines) {
          const line = block.split('\n').find((l) => l.startsWith('data: '));
          if (!line) continue;
          try {
            const evt = JSON.parse(line.slice(6));
            if (evt.type === 'message') {
              const id = `${evt.ts || ''}|answer|${(evt.content || '').slice(0, 50)}`;
              if (!seenIdsRef.current.has(id)) {
                seenIdsRef.current.add(id);
                setMessages((prev) => [...prev, evt]);
              }
            }
          } catch (_) {}
        }
      }
    } catch (err) {
      setMessages((prev) => [...prev, {
        role: 'assistant',
        content: 'Erreur de connexion. Verifiez votre reseau.',
        ts: new Date().toISOString()
      }]);
    } finally {
      setIsSending(false);
      inputRef.current?.focus();
    }
  }, [dossierId, input, isSending]);

  function handleKeyDown(e) {
    if (e.key === 'Enter' && !e.shiftKey) {
      e.preventDefault();
      sendQuestion();
    }
  }

  const activeIdx = pipelineIndex(statut);
  const isDelivered = statut === 'delivered';
  // Eligibilite expert partenaire : garantie PJ confirmee, inconnue, ou detectee
  // (refuser uniquement si client a explicitement dit 'denied')
  const pjEligible =
    garantiePjStatus === 'confirmed' ||
    garantiePjStatus === 'unknown' ||
    garantiePjStatus === 'detected_in_contract' ||
    garantiePjStatus === null ||
    garantiePjStatus === undefined;
  const showExpertCTA = isDelivered && pjEligible && !expertRequestedAt;

  return (
    <div style={{ display: 'flex', flexDirection: 'column', flex: 1, overflow: 'hidden' }}>

      {/* ── Stepper pipeline ──────────────────────────── */}
      <div style={{
        background: '#fff', borderBottom: '1px solid #E5E7EB',
        padding: '.75rem 1.5rem', display: 'flex', alignItems: 'center', gap: 0,
        overflowX: 'auto', scrollbarWidth: 'none'
      }}>
        {PIPELINE.map((step, i) => (
          <React.Fragment key={step.key}>
            {i > 0 && (
              <div style={{
                width: 18, height: 1, margin: '0 4px', flexShrink: 0,
                background: i <= activeIdx ? '#1B4332' : '#E5E7EB'
              }}></div>
            )}
            <div style={{ display: 'flex', alignItems: 'center', gap: 6, whiteSpace: 'nowrap' }}>
              <div style={{
                width: 22, height: 22, borderRadius: '50%',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
                fontSize: '.6rem', fontWeight: 700, flexShrink: 0, transition: 'all .3s',
                ...(i < activeIdx
                  ? { background: '#1B4332', color: '#fff' }
                  : i === activeIdx
                    ? { background: '#0F2B3C', color: '#fff', boxShadow: '0 0 0 3px rgba(15,43,60,.15)' }
                    : { background: '#FAFAF8', color: '#9ca3af', border: '1px solid #E5E7EB' })
              }}>
                {i < activeIdx ? '✓' : i + 1}
              </div>
              <span style={{
                fontSize: '.65rem',
                color: i === activeIdx ? '#0F2B3C' : '#9ca3af',
                fontWeight: i === activeIdx ? 600 : 400
              }}>
                {step.label}
              </span>
            </div>
          </React.Fragment>
        ))}
      </div>

      {/* ── Expert partenaire CTA ─────────────────────── */}
      {showExpertCTA && (
        <div className="anim-fade-in" style={{
          background: 'linear-gradient(135deg, rgba(245,158,11,.10), rgba(217,119,6,.06))',
          borderBottom: '1px solid rgba(245,158,11,.25)',
          padding: '1rem 1.5rem'
        }}>
          <div style={{ display: 'flex', alignItems: 'flex-start', gap: '.75rem', flexWrap: 'wrap' }}>
            <div style={{
              width: 36, height: 36, borderRadius: 10,
              background: '#0F2B3C', color: '#fff',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontSize: '1.1rem', fontWeight: 700, flexShrink: 0
            }}>★</div>
            <div style={{ flex: 1, minWidth: 240 }}>
              <p style={{ fontSize: '.9rem', fontWeight: 700, color: '#B8860B' }}>
                Vous pourriez beneficier d'un expert d'assure independant
              </p>
              <p style={{ fontSize: '.8rem', color: '#6B7280', lineHeight: 1.5, marginTop: 4 }}>
                Selon votre contrat (garantie protection juridique / honoraires d'expert),
                les frais d'un vrai expert d'assure pourraient etre pris en charge par
                votre assurance. <strong>Fabien Berthier</strong> (expert d'assure CoCREATA)
                peut prendre le relais de cette analyse IA et negocier directement.
              </p>
              <p style={{ fontSize: '.7rem', color: '#9ca3af', marginTop: 6, fontStyle: 'italic' }}>
                La prise en charge depend de votre contrat exact — Fabien la verifiera avec vous.
              </p>
            </div>
            <button
              onClick={requestExpert}
              disabled={expertRequesting}
              style={{
                display: 'inline-flex', alignItems: 'center', gap: 8,
                background: '#B8860B', color: '#fff', padding: '10px 18px',
                borderRadius: 10, fontSize: '.85rem', fontWeight: 600,
                border: 'none', cursor: expertRequesting ? 'not-allowed' : 'pointer',
                opacity: expertRequesting ? 0.6 : 1, flexShrink: 0
              }}
            >
              {expertRequesting ? 'Envoi...' : 'Demander une mise en relation'}
            </button>
          </div>
        </div>
      )}

      {expertRequestedAt && isDelivered && (
        <div className="anim-fade-in" style={{
          background: 'rgba(16,185,129,.08)',
          borderBottom: '1px solid rgba(16,185,129,.25)',
          padding: '.75rem 1.5rem',
          display: 'flex', alignItems: 'center', gap: '.75rem'
        }}>
          <div style={{
            width: 28, height: 28, borderRadius: 8,
            background: '#1B4332', color: '#fff',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            fontSize: '.85rem', fontWeight: 700, flexShrink: 0
          }}>✓</div>
          <p style={{ fontSize: '.85rem', color: '#143528', fontWeight: 600 }}>
            Demande envoyee. Fabien Berthier vous contactera sous 48h.
          </p>
        </div>
      )}

      {/* ── Banner livraison ──────────────────────────── */}
      {isDelivered && rapportUrl && (
        <div className="anim-fade-in" style={{
          background: 'linear-gradient(135deg, rgba(16,185,129,.08), rgba(5,150,105,.04))',
          borderBottom: '1px solid rgba(16,185,129,.2)',
          padding: '1rem 1.5rem',
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          gap: '1rem', flexWrap: 'wrap'
        }}>
          <div style={{ display: 'flex', alignItems: 'center', gap: '.75rem', flex: 1, minWidth: 0 }}>
            <div style={{
              width: 36, height: 36, borderRadius: 10,
              background: '#1B4332', color: '#fff',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontSize: '1.1rem', fontWeight: 700, flexShrink: 0
            }}>✓</div>
            <div>
              <p style={{ fontSize: '.9rem', fontWeight: 700, color: '#143528' }}>
                Votre rapport est pret
              </p>
              <p style={{ fontSize: '.75rem', color: '#047857' }}>
                Une copie a aussi ete envoyee a {email ? `${email.charAt(0)}***@${email.split('@')[1] || '...'}` : 'votre email'}
              </p>
            </div>
          </div>
          <a href={rapportUrl} target="_blank" rel="noopener noreferrer" style={{
            display: 'inline-flex', alignItems: 'center', gap: 8,
            background: '#1B4332', color: '#fff', padding: '10px 18px',
            borderRadius: 10, fontSize: '.85rem', fontWeight: 600,
            textDecoration: 'none', transition: 'all .2s', flexShrink: 0
          }}>
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
              <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
              <polyline points="7 10 12 15 17 10"/>
              <line x1="12" x2="12" y1="15" y2="3"/>
            </svg>
            Telecharger le PDF
          </a>
        </div>
      )}

      {/* ── Messages ──────────────────────────────────── */}
      <div className="chat-scroll" style={{
        flex: 1, overflowY: 'auto', padding: '1.5rem',
        display: 'flex', flexDirection: 'column', gap: '1rem'
      }}>
        {messages.length === 0 && (
          <div style={{ textAlign: 'center', color: '#9ca3af', fontSize: '.85rem', padding: '2rem 0' }}>
            Connexion au guide en cours...
          </div>
        )}

        {messages.map((msg, i) => (
          <div key={i} className="anim-fade-in" style={{
            display: 'flex', gap: '.75rem', maxWidth: '85%',
            alignSelf: msg.role === 'user' ? 'flex-end' : 'flex-start',
            flexDirection: msg.role === 'user' ? 'row-reverse' : 'row'
          }}>
            <div style={{
              width: 32, height: 32, borderRadius: 10, flexShrink: 0,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontSize: '.7rem', fontWeight: 700,
              ...(msg.role === 'assistant'
                ? { background: 'linear-gradient(135deg, #0F2B3C, #0c2230)', color: '#fff' }
                : { background: '#111827', color: '#fff' })
            }}>
              {msg.role === 'assistant' ? 'AI' : (
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
                  <path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/>
                  <circle cx="12" cy="7" r="4"/>
                </svg>
              )}
            </div>
            <div style={{
              padding: '.875rem 1.125rem', borderRadius: 16, fontSize: '.875rem', lineHeight: 1.6,
              ...(msg.role === 'user'
                ? { background: '#111827', color: '#fff', borderBottomRightRadius: 4 }
                : { background: '#fff', border: '1px solid #E5E7EB', color: '#111827', borderBottomLeftRadius: 4 })
            }}>
              <span dangerouslySetInnerHTML={{ __html: formatText(msg.content) }} />
              {msg.kind === 'transition' && msg.transition && (
                <div style={{
                  marginTop: 8, fontSize: '.65rem', color: '#9ca3af',
                  textTransform: 'uppercase', letterSpacing: '.05em'
                }}>
                  Etape : {msg.transition.to}
                </div>
              )}
            </div>
          </div>
        ))}

        {isSending && (
          <div className="anim-fade-in" style={{ display: 'flex', gap: '.75rem', alignSelf: 'flex-start' }}>
            <div style={{
              width: 32, height: 32, borderRadius: 10,
              background: 'linear-gradient(135deg, #0F2B3C, #0c2230)', color: '#fff',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontSize: '.7rem', fontWeight: 700
            }}>AI</div>
            <div style={{
              display: 'flex', gap: 4, padding: '1rem 1.125rem',
              background: '#fff', border: '1px solid #E5E7EB',
              borderRadius: 16, borderBottomLeftRadius: 4, width: 'fit-content'
            }}>
              <span className="typing-dot" style={{ width: 6, height: 6, borderRadius: '50%', background: '#9ca3af' }}></span>
              <span className="typing-dot" style={{ width: 6, height: 6, borderRadius: '50%', background: '#9ca3af' }}></span>
              <span className="typing-dot" style={{ width: 6, height: 6, borderRadius: '50%', background: '#9ca3af' }}></span>
            </div>
          </div>
        )}

        {streamError && (
          <div style={{
            fontSize: '.75rem', color: '#B8860B', background: '#F3F4F6',
            padding: '.5rem .75rem', borderRadius: 8, alignSelf: 'flex-start'
          }}>
            {streamError}
          </div>
        )}

        <div ref={messagesEndRef} />
      </div>

      {/* ── Input ───────────────────────────────────────── */}
      <div style={{
        background: '#fff', borderTop: '1px solid #E5E7EB', padding: '1rem 1.5rem'
      }}>
        <div style={{ display: 'flex', gap: '.75rem', alignItems: 'flex-end' }}>
          <textarea
            ref={inputRef}
            value={input}
            onChange={(e) => setInput(e.target.value)}
            onKeyDown={handleKeyDown}
            placeholder={isDelivered
              ? "Posez une question sur votre rapport..."
              : "Posez une question pendant l'analyse..."}
            rows={1}
            maxLength={5000}
            disabled={isSending}
            style={{
              flex: 1, padding: '.75rem 1rem', borderRadius: 12,
              border: '1px solid #E5E7EB', background: '#FAFAF8',
              fontSize: '.875rem', fontFamily: 'inherit', resize: 'none',
              outline: 'none', minHeight: 42, maxHeight: 120,
              transition: 'border .2s', color: '#111827',
              opacity: isSending ? 0.5 : 1
            }}
            onFocus={(e) => (e.target.style.borderColor = '#0F2B3C')}
            onBlur={(e) => (e.target.style.borderColor = '#E5E7EB')}
          />
          <button
            onClick={() => sendQuestion()}
            disabled={isSending || !input.trim()}
            style={{
              width: 42, height: 42, borderRadius: 12, border: 'none',
              cursor: input.trim() && !isSending ? 'pointer' : 'not-allowed',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              color: '#fff', flexShrink: 0,
              background: input.trim() && !isSending ? '#0F2B3C' : '#d1d5db',
              opacity: isSending || !input.trim() ? 0.5 : 1
            }}
          >
            <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5">
              <path d="m22 2-7 20-4-9-9-4Z"/><path d="M22 2 11 13"/>
            </svg>
          </button>
        </div>
        <p style={{ textAlign: 'center', fontSize: '.65rem', color: '#9ca3af', marginTop: 6 }}>
          Vos echanges restent disponibles pendant 30 jours puis sont supprimes (RGPD)
        </p>
      </div>
    </div>
  );
}
