const { useState, useRef, useCallback, useEffect } = React;

// Types de document (alignés sur l'enum backend documents.type)
const DOC_TYPES = [
  { value: 'rapport_expert', label: "Rapport d'expertise de l'assureur" },
  { value: 'lettre_indemnisation', label: "Lettre / offre d'indemnisation" },
  { value: 'police_assurance', label: "Police d'assurance (CP + CG)" },
  { value: 'photo', label: 'Photos du sinistre' },
  { value: 'devis', label: 'Devis / facture de réparation' },
  { value: 'courrier', label: "Courriers de l'assureur" },
  { value: 'declaration', label: 'Déclaration de sinistre' },
  { value: 'convocation_expertise', label: 'Convocation à expertise' },
  { value: 'rapport_preliminaire', label: "Rapport d'expertise préliminaire" },
  { value: 'pv_pompiers', label: 'PV / rapport des pompiers' },
  { value: 'constat_amiable_eaux', label: 'Constat amiable dégât des eaux (CADE)' },
  { value: 'arrete_catnat', label: 'Arrêté catastrophe naturelle (JO)' },
  { value: 'expertise_geotechnique', label: 'Étude géotechnique (sol/fondations)' },
  { value: 'autre', label: 'Autre document' }
];

// Libellés lisibles des livrables cibles (renvoyés par /sufficiency)
const LIVRABLE_LABELS = {
  etude_complete: 'Étude complète — analyse des failles du dossier adverse',
  etude_complete_contentieux: 'Étude complète + volet contentieux',
  cadrage_constitution_preuve: 'Cadrage du dossier & constitution de preuve',
  preparation_expertise: "Préparation au rendez-vous d'expertise"
};

const ACCEPTED_EXT = '.pdf,.jpg,.jpeg,.png,.heic,.heif,.docx';
const ACCEPTED_MIME = [
  'application/pdf',
  'image/jpeg',
  'image/png',
  'image/heic',
  'image/heif',
  'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
];
const MAX_SIZE = 25 * 1024 * 1024;
const MAX_FILES = 10;

function DocumentUpload({ dossierId, accessToken, onComplete }) {
  const [items, setItems] = useState([]); // { localId, file, name, size, type, status, docId, error }
  const [suff, setSuff] = useState(null); // évaluation de suffisance (stade, manquants…)
  const [isStarting, setIsStarting] = useState(false);
  const [dragActive, setDragActive] = useState(false);
  const [loadError, setLoadError] = useState('');
  const [startError, setStartError] = useState('');
  const fileInputRef = useRef(null);
  const counterRef = useRef(0);

  const authHeaders = useCallback((extra) => ({
    'x-access-token': accessToken,
    ...(extra || {})
  }), [accessToken]);

  // Évaluation de suffisance (stade + pièces manquantes). Même source que le
  // verrou serveur : la checklist reflète exactement ce que start-analysis exige.
  const fetchSufficiency = useCallback(async () => {
    if (!dossierId || !accessToken) return;
    try {
      const res = await fetch(`/api/dossiers/${dossierId}/sufficiency`, { headers: authHeaders() });
      if (res.ok) setSuff(await res.json());
    } catch (e) { /* non bloquant : le verrou serveur reste la garde finale */ }
  }, [dossierId, accessToken, authHeaders]);

  // Charger les documents déjà uploadés (reprise via lien email)
  useEffect(() => {
    if (!dossierId || !accessToken) return;
    (async () => {
      try {
        const res = await fetch(`/api/dossiers/${dossierId}/documents`, {
          headers: authHeaders()
        });
        if (!res.ok) return;
        const data = await res.json();
        if (Array.isArray(data.documents) && data.documents.length > 0) {
          setItems(data.documents.map((d) => ({
            localId: `srv-${d.id}`,
            name: d.nom,
            size: d.taille,
            type: d.type,
            status: 'uploaded',
            docId: d.id
          })));
        }
      } catch (e) {
        setLoadError('Impossible de charger vos documents existants.');
      }
      await fetchSufficiency();
    })();
  }, [dossierId, accessToken, authHeaders, fetchSufficiency]);

  const fileToBase64 = (file) => new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result.split(',')[1]);
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });

  const uploadOne = useCallback(async (item) => {
    setItems((prev) => prev.map((it) => it.localId === item.localId ? { ...it, status: 'uploading', error: null } : it));
    try {
      const base64 = await fileToBase64(item.file);
      const res = await fetch(`/api/dossiers/${dossierId}/documents`, {
        method: 'POST',
        headers: authHeaders({ 'Content-Type': 'application/json' }),
        body: JSON.stringify({
          fileName: item.name,
          fileType: item.file.type,
          fileData: base64,
          category: item.type
        })
      });
      const data = await res.json();
      if (res.ok) {
        setItems((prev) => prev.map((it) => it.localId === item.localId
          ? { ...it, status: 'uploaded', docId: data.documentId, duplicate: data.duplicate }
          : it));
        fetchSufficiency(); // recalcule le stade / les pièces manquantes
      } else {
        setItems((prev) => prev.map((it) => it.localId === item.localId
          ? { ...it, status: 'failed', error: data.error || 'Échec' }
          : it));
      }
    } catch (err) {
      setItems((prev) => prev.map((it) => it.localId === item.localId
        ? { ...it, status: 'failed', error: err.message }
        : it));
    }
  }, [dossierId, authHeaders, fetchSufficiency]);

  const addFiles = useCallback((fileList) => {
    const incoming = Array.from(fileList);
    const accepted = [];
    for (const f of incoming) {
      if (items.length + accepted.length >= MAX_FILES) {
        alert(`Maximum ${MAX_FILES} documents.`);
        break;
      }
      if (f.size > MAX_SIZE) { alert(`${f.name} dépasse 25 Mo.`); continue; }
      if (!ACCEPTED_MIME.includes(f.type) && f.type !== '') {
        alert(`${f.name} : format non accepté (PDF, JPG, PNG, HEIC, DOCX).`);
        continue;
      }
      const localId = `loc-${counterRef.current++}`;
      // Pré-sélection du type via le nom de fichier (suggestion non contraignante)
      const lower = f.name.toLowerCase();
      let guess = 'autre';
      if (/expert|saretec|rapport/.test(lower)) guess = 'rapport_expert';
      else if (/indemn|offre/.test(lower)) guess = 'lettre_indemnisation';
      else if (/devis|facture/.test(lower)) guess = 'devis';
      else if (/courrier|lettre|courriel/.test(lower)) guess = 'courrier';
      else if (/photo|img|jpg|jpeg|png|heic/.test(lower)) guess = 'photo';
      accepted.push({ localId, file: f, name: f.name, size: f.size, type: guess, status: 'pending' });
    }
    if (accepted.length > 0) {
      setItems((prev) => [...prev, ...accepted]);
      // Upload immédiat
      accepted.forEach((it) => uploadOne(it));
    }
  }, [items.length, uploadOne]);

  const setItemType = useCallback((localId, type) => {
    setItems((prev) => prev.map((it) => it.localId === localId ? { ...it, type } : it));
  }, []);

  const retryItem = useCallback((localId) => {
    const it = items.find((x) => x.localId === localId);
    if (it && it.file) uploadOne(it);
  }, [items, uploadOne]);

  const removeItem = useCallback(async (item) => {
    if (item.docId) {
      try {
        await fetch(`/api/dossiers/${dossierId}/documents/${item.docId}`, {
          method: 'DELETE',
          headers: authHeaders()
        });
      } catch (e) { /* best-effort */ }
    }
    setItems((prev) => prev.filter((it) => it.localId !== item.localId));
    fetchSufficiency(); // le retrait d'une pièce peut faire repasser sous le seuil
  }, [dossierId, authHeaders, fetchSufficiency]);

  const onDrop = useCallback((e) => {
    e.preventDefault(); e.stopPropagation(); setDragActive(false);
    addFiles(e.dataTransfer.files);
  }, [addFiles]);

  const uploadedCount = items.filter((it) => it.status === 'uploaded').length;
  const pendingCount = items.filter((it) => it.status === 'uploading' || it.status === 'pending').length;
  const hasFailures = items.some((it) => it.status === 'failed');

  const startAnalysis = useCallback(async () => {
    setIsStarting(true);
    setStartError('');
    try {
      const res = await fetch(`/api/dossiers/${dossierId}/start-analysis`, {
        method: 'POST',
        headers: authHeaders({ 'Content-Type': 'application/json' }),
        body: JSON.stringify({})
      });
      if (res.ok || res.status === 200) {
        if (onComplete) onComplete();
      } else {
        const data = await res.json().catch(() => ({}));
        // 409 = seuil de suffisance non atteint : on remet à jour la checklist
        // et on nomme les pièces manquantes plutôt qu'un alert opaque.
        if (res.status === 409 && Array.isArray(data.manquants)) {
          setSuff((prev) => ({ ...(prev || {}), ...data, suffisant: false }));
          setStartError(
            'Pièces insuffisantes pour lancer l\'analyse : '
            + data.manquants.join(', ') + '.'
          );
        } else {
          setStartError(data.error || "Impossible de lancer l'analyse. Réessayez.");
        }
        setIsStarting(false);
      }
    } catch (err) {
      setStartError('Erreur de connexion. Réessayez.');
      setIsStarting(false);
    }
  }, [dossierId, authHeaders, onComplete]);

  const fmtSize = (b) => b == null ? '' : (b < 1024 * 1024 ? `${Math.max(1, Math.round(b / 1024))} Ko` : `${(b / 1024 / 1024).toFixed(1)} Mo`);

  return (
    <div className="min-h-screen bg-ink-50">
      <header className="glass px-4 md:px-6 py-4 border-b border-ink-200/70">
        <div className="flex items-center gap-3 max-w-3xl mx-auto">
          <img src="/brand/sinistrai-app-icon.svg" alt="SinistrAI Expert" className="w-9 h-9 rounded-lg flex-shrink-0" />
          <span className="font-display font-bold text-ink-900">SinistrAI Expert</span>
          <span className="ml-auto text-xs text-ink-400">Dossier {dossierId?.slice(0, 8).toUpperCase()}</span>
        </div>
      </header>

      <main className="max-w-3xl mx-auto px-5 md:px-8 py-8 anim-fade-up">
        <div className="mb-6">
          <div className="inline-flex items-center gap-2 text-xs font-semibold px-3 py-1.5 rounded-full bg-emerald-50 text-emerald-600 mb-4">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M5 13l4 4L19 7"/></svg>
            Paiement confirmé
          </div>
          <h1 className="font-display font-bold text-2xl md:text-3xl text-ink-900 mb-2">Téléversez vos documents</h1>
          <p className="text-ink-500 text-sm md:text-base leading-relaxed">
            Plus vous fournissez de pièces, plus l'analyse est précise. Nos agents lisent
            le contenu de vos documents (rapport d'expert, devis, courriers, photos) pour
            identifier les failles du dossier adverse.
          </p>
        </div>

        {/* Checklist dynamique selon le stade détecté (source : /sufficiency) */}
        {suff && (
          <div className="bg-white rounded-2xl border border-ink-200 p-5 mb-5">
            <div className="flex items-center justify-between mb-3">
              <p className="text-xs font-bold text-ink-400 uppercase tracking-wider">Stade du dossier</p>
              <span className={`text-xs font-semibold px-2.5 py-1 rounded-full ${suff.suffisant ? 'bg-emerald-50 text-emerald-600' : 'bg-amber-50 text-amber-700'}`}>
                {suff.stade_label || '—'}
              </span>
            </div>

            <div className="flex items-center gap-2 text-sm mb-3">
              <span className="text-ink-400">Livrable :</span>
              <span className="font-medium text-ink-800">{LIVRABLE_LABELS[suff.livrable_cible] || suff.livrable_cible}</span>
            </div>

            {/* Pièces manquantes BLOQUANTES */}
            {Array.isArray(suff.manquants) && suff.manquants.length > 0 && (
              <div className="rounded-xl bg-red-50 border border-red-100 p-3 mb-2">
                <p className="text-xs font-bold text-red-600 mb-1.5">Pièces requises manquantes</p>
                <ul className="space-y-1">
                  {suff.manquants.map((m, i) => (
                    <li key={i} className="flex items-start gap-2 text-sm text-ink-700">
                      <span className="w-1.5 h-1.5 rounded-full bg-red-500 mt-1.5 flex-shrink-0"></span>{m}
                    </li>
                  ))}
                </ul>
              </div>
            )}

            {/* Pièces recommandées (non bloquantes) */}
            {Array.isArray(suff.recommandes_manquants) && suff.recommandes_manquants.length > 0 && (
              <div className="rounded-xl bg-amber-50 border border-amber-100 p-3 mb-2">
                <p className="text-xs font-bold text-amber-700 mb-1.5">Recommandé (renforce l'analyse)</p>
                <ul className="space-y-1">
                  {suff.recommandes_manquants.map((m, i) => (
                    <li key={i} className="flex items-start gap-2 text-sm text-ink-700">
                      <span className="w-1.5 h-1.5 rounded-full bg-amber-500 mt-1.5 flex-shrink-0"></span>{m}
                    </li>
                  ))}
                </ul>
              </div>
            )}

            {/* Formats non exploitables */}
            {Array.isArray(suff.warnings) && suff.warnings.length > 0 && (
              <ul className="space-y-1 mt-2">
                {suff.warnings.map((w, i) => (
                  <li key={i} className="text-xs text-amber-600">⚠ {w}</li>
                ))}
              </ul>
            )}

            {suff.suffisant && (
              <p className="text-sm text-emerald-600 font-medium flex items-center gap-2 mt-1">
                <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M5 13l4 4L19 7"/></svg>
                Seuil atteint — vous pouvez lancer l'analyse.
              </p>
            )}
          </div>
        )}

        {/* Drop zone */}
        <div
          onDrop={onDrop}
          onDragOver={(e) => { e.preventDefault(); setDragActive(true); }}
          onDragLeave={(e) => { e.preventDefault(); setDragActive(false); }}
          onClick={() => fileInputRef.current?.click()}
          className={`border-2 border-dashed rounded-2xl p-8 text-center cursor-pointer transition-all duration-200 mb-5 ${dragActive ? 'border-brand-500 bg-brand-50' : 'border-ink-200 hover:border-brand-400 hover:bg-brand-50'}`}
        >
          <div className="w-12 h-12 rounded-xl bg-brand-100 mx-auto mb-3 flex items-center justify-center">
            <svg width="22" height="22" viewBox="0 0 24 24" fill="none" stroke="#d97706" strokeWidth="2"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="17 8 12 3 7 8"/><line x1="12" x2="12" y1="3" y2="15"/></svg>
          </div>
          <p className="text-ink-700 font-semibold">Glissez vos fichiers ici ou cliquez pour ajouter</p>
          <p className="text-xs text-ink-400 mt-1">PDF, JPG, PNG, HEIC, DOCX — max 25 Mo / fichier, {MAX_FILES} fichiers</p>
        </div>
        <input ref={fileInputRef} type="file" accept={ACCEPTED_EXT} multiple onChange={(e) => addFiles(e.target.files)} className="hidden" />

        {loadError && <p className="text-xs text-red-500 mb-3">{loadError}</p>}

        {/* Liste des fichiers */}
        {items.length > 0 && (
          <div className="space-y-2 mb-6">
            {items.map((it) => (
              <div key={it.localId} className="flex items-center gap-3 bg-white border border-ink-200 rounded-xl px-3 py-2.5">
                <span className="flex-shrink-0">
                  {it.status === 'uploaded' && <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#059669" strokeWidth="2.5"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><path d="m9 11 3 3L22 4"/></svg>}
                  {(it.status === 'uploading' || it.status === 'pending') && <svg className="anim-spin-slow" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#f59e0b" strokeWidth="2.5"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg>}
                  {it.status === 'failed' && <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#ef4444" strokeWidth="2.5"><circle cx="12" cy="12" r="10"/><line x1="12" x2="12" y1="8" y2="12"/><line x1="12" x2="12.01" y1="16" y2="16"/></svg>}
                </span>
                <div className="flex-1 min-w-0">
                  <p className="text-sm text-ink-800 font-medium truncate">{it.name}</p>
                  <p className="text-xs text-ink-400">
                    {fmtSize(it.size)}
                    {it.status === 'failed' && <span className="text-red-500"> — {it.error}</span>}
                    {it.duplicate && <span className="text-ink-400"> — déjà ajouté</span>}
                  </p>
                </div>
                <select
                  value={it.type}
                  onChange={(e) => setItemType(it.localId, e.target.value)}
                  disabled={it.status === 'uploaded'}
                  className="text-xs border border-ink-200 rounded-lg px-2 py-1.5 bg-white text-ink-700 flex-shrink-0 focus:outline-none focus:border-brand-500 disabled:opacity-60"
                >
                  {DOC_TYPES.map((t) => <option key={t.value} value={t.value}>{t.label}</option>)}
                </select>
                {it.status === 'failed' && (
                  <button onClick={() => retryItem(it.localId)} className="text-xs text-brand-600 font-semibold flex-shrink-0">Réessayer</button>
                )}
                <button onClick={() => removeItem(it)} className="text-ink-300 hover:text-red-500 flex-shrink-0" title="Supprimer">
                  <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M3 6h18"/><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
                </button>
              </div>
            ))}
          </div>
        )}

        {/* Actions */}
        <div className="sticky bottom-0 bg-ink-50 pt-4 pb-6 -mx-5 px-5 md:-mx-8 md:px-8 border-t border-ink-200/70">
          {/* Le bouton reste désactivé tant que le seuil n'est pas atteint.
              Le verrou serveur (start-analysis → 409) reste la garde finale. */}
          <button
            onClick={startAnalysis}
            disabled={isStarting || pendingCount > 0 || (suff && !suff.suffisant)}
            className="btn-primary w-full font-semibold text-base px-6 py-4 rounded-xl text-white disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2"
          >
            {isStarting
              ? (<><svg className="anim-spin-slow" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg> Lancement de l'analyse...</>)
              : pendingCount > 0
                ? `Upload en cours (${pendingCount})...`
                : (suff && !suff.suffisant)
                  ? 'Déposez les pièces requises pour lancer'
                  : `Lancer mon analyse${uploadedCount > 0 ? ` (${uploadedCount} document${uploadedCount > 1 ? 's' : ''})` : ''}`}
          </button>

          {hasFailures && (
            <p className="text-xs text-red-500 text-center mt-2">Certains fichiers ont échoué — réessayez ou supprimez-les avant de lancer.</p>
          )}

          {startError && (
            <p className="text-xs text-red-500 text-center mt-2">{startError}</p>
          )}
        </div>
      </main>
    </div>
  );
}
