import { useRef, useState } from 'react';
import { Link, useNavigate } from 'react-router-dom';
import type { AssistantAnswer, AssistantExcerpt } from '@siop/shared';
import { useAskAssistant } from '@/api/assistant';
import { ouvrirDocument } from '@/api/gestion';
import { usePermissions } from '@/auth/use-permissions';
import { Button } from '@/components/ui/button';

/** Écrans 1-2 des maquettes R5 : chat « sourcé ou silencieux » (D2).
 *  Chaque réponse cite ses extraits EXACTS ; sans source au-dessus du seuil,
 *  le refus est honnête et chiffré (ce qui a été cherché). L'avertissement
 *  « l'IA propose, vous validez » est permanent, pas un disclaimer caché. */

interface Echange {
  question: string;
  reponse?: AssistantAnswer;
  erreur?: string;
}

function Source({ extrait, no }: { extrait: AssistantExcerpt; no: number }) {
  const navigate = useNavigate();
  const ouvrir = () => {
    if (extrait.sourceType === 'DOCUMENT' && extrait.documentId) {
      void ouvrirDocument(extrait.documentId);
    } else if (extrait.workOrderId) {
      navigate(`/ot/${extrait.workOrderId}`);
    }
  };
  return (
    <div className="source">
      <span className="no">{no}</span>
      <div>
        <b>{extrait.title}</b>
        <div className="ou">
          {extrait.sourceType === 'DOCUMENT' ? 'Bibliothèque' : 'Historique'} · {extrait.locator}
        </div>
        <div className="extrait">« {extrait.content} »</div>
      </div>
      <button type="button" className="ouvrir" onClick={ouvrir}>
        {extrait.sourceType === 'DOCUMENT' ? 'Ouvrir' : "Ouvrir l'OT"}
      </button>
    </div>
  );
}

function Reponse({ reponse, surReformuler }: { reponse: AssistantAnswer; surReformuler: () => void }) {
  const { can } = usePermissions();
  if (reponse.mode === 'REFUSAL') {
    return (
      <div className="refus">
        <b>Je ne trouve pas de source fiable dans votre bibliothèque — je préfère ne pas inventer.</b>
        <div className="pourquoi">
          J'ai cherché dans {reponse.corpus.documents} document
          {reponse.corpus.documents > 1 ? 's' : ''} indexé
          {reponse.corpus.documents > 1 ? 's' : ''} et {reponse.corpus.reports} bilan
          {reponse.corpus.reports > 1 ? 's' : ''} d'intervention : rien d'assez proche de votre
          question.
        </div>
        <div className="actions-sug">
          {can('ASSETS', 'edit') ? (
            <Link to="/bibliotheque" className="btn prim">
              Téléverser la notice dans la bibliothèque
            </Link>
          ) : null}
          <Button onClick={surReformuler}>Reformuler ma question</Button>
        </div>
      </div>
    );
  }
  return (
    <div className="msg-r">
      {reponse.mode === 'GENERATED' && reponse.answer ? (
        <p style={{ whiteSpace: 'pre-wrap' }}>{reponse.answer}</p>
      ) : (
        <p>
          Voici ce que portent vos sources — les extraits sont cités tels quels
          {reponse.excerpts.map((_, i) => (
            <span key={i} className="cite">{i + 1}</span>
          ))}
          .
        </p>
      )}
      <div className="sources">
        {reponse.excerpts.map((extrait, i) => (
          <Source key={`${extrait.locator}-${i}`} extrait={extrait} no={i + 1} />
        ))}
      </div>
      <div className="avert">⚠ L'IA propose, vous validez : vérifiez la notice avant d'agir sur l'appareil.</div>
    </div>
  );
}

export default function PageAssistant() {
  const ask = useAskAssistant();
  const [question, setQuestion] = useState('');
  const [echanges, setEchanges] = useState<Echange[]>([]);
  const saisieRef = useRef<HTMLInputElement>(null);

  const envoyer = () => {
    const q = question.trim();
    if (q.length < 3 || ask.isPending) return;
    setQuestion('');
    setEchanges((liste) => [...liste, { question: q }]);
    ask.mutate(
      { question: q },
      {
        onSuccess: (reponse) =>
          setEchanges((liste) =>
            liste.map((e, i) => (i === liste.length - 1 ? { ...e, reponse } : e)),
          ),
        onError: (erreur) =>
          setEchanges((liste) =>
            liste.map((e, i) => (i === liste.length - 1 ? { ...e, erreur: erreur.message } : e)),
          ),
      },
    );
  };

  return (
    <>
      <div className="entete-page">
        <h1>Assistant</h1>
        <span className="filajout">répond UNIQUEMENT depuis votre bibliothèque et vos historiques</span>
      </div>
      <div className="chat" aria-live="polite">
        {echanges.length === 0 ? (
          <div className="carte" style={{ color: 'var(--encre-2)', maxWidth: 760 }}>
            Posez une question sur vos notices, vos historiques d'intervention ou vos procédures —
            chaque réponse cite ses sources (document et page, ou bilan d'OT). Quand le corpus ne
            porte pas la réponse, l'assistant le dit au lieu d'inventer.
          </div>
        ) : null}
        {echanges.map((echange, i) => (
          <div key={i} style={{ display: 'contents' }}>
            <div className="msg-q">{echange.question}</div>
            {echange.reponse ? (
              <Reponse reponse={echange.reponse} surReformuler={() => saisieRef.current?.focus()} />
            ) : echange.erreur ? (
              <div className="refus" role="alert">
                <b>{echange.erreur}</b>
              </div>
            ) : (
              <div className="msg-r" style={{ color: 'var(--encre-3)' }}>Recherche dans le corpus…</div>
            )}
          </div>
        ))}
      </div>
      <div className="saisie-chat">
        <input
          ref={saisieRef}
          value={question}
          maxLength={500}
          placeholder="Poser une question (notices, historiques, procédures)…"
          aria-label="Poser une question"
          onChange={(e) => setQuestion(e.target.value)}
          onKeyDown={(e) => {
            if (e.key === 'Enter') envoyer();
          }}
        />
        <Button variant="prim" disabled={question.trim().length < 3 || ask.isPending} onClick={envoyer}>
          Envoyer
        </Button>
      </div>
    </>
  );
}
