import { useEffect, useRef, useState, type DragEvent } from 'react';
import {
  DOCUMENT_KIND_LABELS,
  DOCUMENT_KINDS,
  DOCUMENT_MAX_BYTES,
  type DocumentKind,
} from '@siop/shared';
import { useReindexAssistant } from '@/api/assistant';
import { useDeleteDocument, useDocuments, useUploadDocument } from '@/api/gestion';
import { useAssetOptions } from '@/api/referentiel';
import { usePermissions } from '@/auth/use-permissions';
import { tailleLisible, VignetteDoc } from '@/components/carte-documents';
import { Button } from '@/components/ui/button';
import { Modale } from '@/components/ui/modale';

/** Écran 7 des maquettes R3, devenu écran 5 de R5 : la bibliothèque EST le
 *  corpus de l'assistant — statut d'indexation visible, interrupteur
 *  d'exclusion réversible, réindexation par geste explicite (D3). */
export default function PageBibliotheque() {
  const { can } = usePermissions();
  const reindex = useReindexAssistant();
  const [kind, setKind] = useState<DocumentKind | ''>('');
  const [assetId, setAssetId] = useState('');
  const { data: options } = useAssetOptions();
  const { data: documents } = useDocuments({
    ...(kind ? { kind } : {}),
    ...(assetId ? { assetId } : {}),
  });
  const suppression = useDeleteDocument();
  const [modale, setModale] = useState(false);
  const [fichierDepose, setFichierDepose] = useState<File | null>(null);
  const [survol, setSurvol] = useState(false);

  const totalOctets = (documents ?? []).reduce((s, d) => s + d.size, 0);
  const indexes = (documents ?? []).filter((d) => d.indexedAt && d.inCorpus).length;
  const peutEditer = can('WORK_ORDERS', 'edit') || can('ASSETS', 'edit');
  const administreCorpus = can('ASSETS', 'edit');

  const surDepot = (e: DragEvent) => {
    e.preventDefault();
    setSurvol(false);
    const fichier = e.dataTransfer.files?.[0];
    if (!fichier) return;
    setFichierDepose(fichier);
    setModale(true);
  };

  return (
    <>
      <div className="entete-page">
        <h1>Bibliothèque — corpus de l'assistant</h1>
        <span className="filajout">
          {documents?.length ?? 0} documents · {indexes} indexés · {tailleLisible(totalOctets)}
        </span>
        <div className="actions">
          {administreCorpus ? (
            <Button disabled={reindex.isPending} onClick={() => reindex.mutate()}>
              {reindex.isPending ? 'Réindexation…' : 'Réindexer tout'}
            </Button>
          ) : null}
          {peutEditer ? (
            <Button variant="prim" onClick={() => setModale(true)}>Téléverser</Button>
          ) : null}
        </div>
      </div>
      <div className="avert">
        🛡 Loi 09-08 — anonymisation à l'ingestion : noms, téléphones et e-mails des personnes ne
        sont JAMAIS envoyés dans les index ni aux modèles.
      </div>
      {reindex.isSuccess ? (
        <div className="carte" style={{ color: 'var(--encre-2)', fontSize: 13 }}>
          Réindexation terminée : {reindex.data.documentsIndexed} document
          {reindex.data.documentsIndexed > 1 ? 's' : ''} indexé
          {reindex.data.documentsIndexed > 1 ? 's' : ''}, {reindex.data.documentsSkipped} ignoré
          {reindex.data.documentsSkipped > 1 ? 's' : ''} (exclus ou non indexables),{' '}
          {reindex.data.reportsIndexed} bilans, {reindex.data.chunks} extraits.
        </div>
      ) : null}
      {reindex.isError ? (
        <p className="erreur-form" role="alert">{reindex.error.message}</p>
      ) : null}
      <div className="filtres">
        <select
          aria-label="Filtrer par type"
          value={kind}
          onChange={(e) => setKind(e.target.value as DocumentKind | '')}
        >
          <option value="">Type : tous</option>
          {DOCUMENT_KINDS.map((k) => (
            <option key={k} value={k}>{DOCUMENT_KIND_LABELS[k]}</option>
          ))}
        </select>
        <select
          aria-label="Filtrer par appareil"
          value={assetId}
          onChange={(e) => setAssetId(e.target.value)}
        >
          <option value="">Rattaché à : tout le parc</option>
          {(options ?? []).map((a) => (
            <option key={a.id} value={a.id}>
              {a.reference} — {a.siteName}
            </option>
          ))}
        </select>
      </div>
      {peutEditer ? (
        <button
          type="button"
          className="zone-depot"
          data-survol={survol || undefined}
          onClick={() => setModale(true)}
          onDragOver={(e) => {
            e.preventDefault();
            setSurvol(true);
          }}
          onDragLeave={() => setSurvol(false)}
          onDrop={surDepot}
        >
          📂 Glissez un fichier ici — PDF, JPG, PNG · 20 Mo max · rattachez-le à un appareil ou un OT
        </button>
      ) : null}
      {documents?.length ? (
        <div className="docs">
          {documents.map((d) => (
            <VignetteDoc
              key={d.id}
              doc={d}
              corpus={administreCorpus}
              surSuppression={peutEditer ? (id) => suppression.mutate(id) : undefined}
            />
          ))}
        </div>
      ) : (
        <div className="carte" style={{ color: 'var(--encre-2)' }}>Aucun document.</div>
      )}
      <div className="carte" style={{ borderStyle: 'dashed', color: 'var(--encre-2)', fontSize: 13 }}>
        Le corpus de l'assistant, c'est cette bibliothèque (PDF indexés) plus les bilans
        d'intervention codés — rien d'externe. Les réponses citent leurs sources.
      </div>
      {peutEditer ? (
        <ModaleTeleversement
          ouverte={modale}
          fichierInitial={fichierDepose}
          surFermeture={(o) => {
            setModale(o);
            if (!o) setFichierDepose(null);
          }}
        />
      ) : null}
    </>
  );
}

function ModaleTeleversement({
  ouverte,
  fichierInitial,
  surFermeture,
}: {
  ouverte: boolean;
  fichierInitial?: File | null;
  surFermeture: (o: boolean) => void;
}) {
  const { data: options } = useAssetOptions();
  const upload = useUploadDocument();
  const fichierRef = useRef<HTMLInputElement>(null);
  const [kind, setKind] = useState<DocumentKind>('NOTICE');
  const [assetId, setAssetId] = useState('');
  const [fichier, setFichier] = useState<File | null>(null);

  // Fichier arrivé par glisser-déposer : la modale s'ouvre déjà remplie.
  useEffect(() => {
    if (fichierInitial) setFichier(fichierInitial);
  }, [fichierInitial]);

  const envoyer = () => {
    if (!fichier || !assetId) return;
    if (fichier.size > DOCUMENT_MAX_BYTES) {
      window.alert('Fichier trop lourd (20 Mo max).');
      return;
    }
    upload.mutate(
      { file: fichier, kind, assetId },
      {
        onSuccess: () => {
          setFichier(null);
          surFermeture(false);
        },
      },
    );
  };

  return (
    <Modale titre="Téléverser un document" ouverte={ouverte} surFermeture={surFermeture}>
      <div className="flex flex-col gap-3">
        <div className="champ">
          <label htmlFor="tv-appareil">Rattacher à l'appareil *</label>
          <select id="tv-appareil" value={assetId} onChange={(e) => setAssetId(e.target.value)}>
            <option value="">Sélectionner…</option>
            {(options ?? []).map((a) => (
              <option key={a.id} value={a.id}>
                {a.reference} — {a.siteName}
              </option>
            ))}
          </select>
        </div>
        <div className="champ">
          <label htmlFor="tv-type">Type *</label>
          <select id="tv-type" value={kind} onChange={(e) => setKind(e.target.value as DocumentKind)}>
            {DOCUMENT_KINDS.map((k) => (
              <option key={k} value={k}>{DOCUMENT_KIND_LABELS[k]}</option>
            ))}
          </select>
        </div>
        <input
          ref={fichierRef}
          type="file"
          accept="application/pdf,image/jpeg,image/png"
          aria-label="Choisir un fichier"
          className="hidden"
          onChange={(e) => setFichier(e.target.files?.[0] ?? null)}
        />
        <button type="button" className="zone-photo" onClick={() => fichierRef.current?.click()}>
          {fichier
            ? `📄 ${fichier.name} (${tailleLisible(fichier.size)})`
            : '📁 Choisir un fichier — PDF, JPG, PNG · 20 Mo max'}
        </button>
        <p className="note-douce">
          Les photos prises sur une intervention se téléversent plutôt depuis la fiche OT —
          elles restent rattachées à l'intervention.
        </p>
        {upload.isError ? <p className="erreur-form">{upload.error.message}</p> : null}
        <div className="pied">
          <Button onClick={() => surFermeture(false)}>Annuler</Button>
          <Button variant="prim" disabled={!fichier || !assetId || upload.isPending} onClick={envoyer}>
            Téléverser
          </Button>
        </div>
      </div>
    </Modale>
  );
}
