import { z } from 'zod';
import { BILAN_FIELDS } from '../exploitation';

/** Assistant R5 (D1/D2 validées) : sourcé ou silencieux, l'humain valide.
 *  Le web/mobile parlent à l'API NestJS ; le service `siop2-ai` reste
 *  interne (ADR-004 §4). */

export const ASSISTANT_MIN_CHARS = 3;

export const AssistantAskSchema = z.object({
  question: z.string().min(ASSISTANT_MIN_CHARS).max(500),
});
export type AssistantAsk = z.infer<typeof AssistantAskSchema>;

export const AssistantExcerptSchema = z.object({
  sourceType: z.enum(['DOCUMENT', 'WORK_ORDER']),
  documentId: z.uuid().nullable(),
  workOrderId: z.uuid().nullable(),
  title: z.string(), // nom de fichier ou référence d'OT
  locator: z.string(), // « p. 42 », « bilan du 17/07/2026 »
  content: z.string(), // l'extrait EXACT — la citation montre sa source
  score: z.number(),
});
export type AssistantExcerpt = z.infer<typeof AssistantExcerptSchema>;

export const AssistantAnswerSchema = z.object({
  /** REFUSAL = le corpus ne porte pas la réponse — l'assistant le dit (D2). */
  mode: z.enum(['EXTRACTIVE', 'GENERATED', 'REFUSAL']),
  /** Rédaction (mode génératif opt-in, ADR-004 §3) — null en extractif/refus. */
  answer: z.string().nullable(),
  excerpts: z.array(AssistantExcerptSchema),
  /** Ce qui a été cherché — le refus honnête l'affiche (« 6 documents, 214 bilans »). */
  corpus: z.object({
    documents: z.number().int(),
    reports: z.number().int(),
  }),
});
export type AssistantAnswer = z.infer<typeof AssistantAnswerSchema>;

// ————— Suggestion de codes de bilan (sans LLM — ADR-004 §3) —————

export const SuggestBilanSchema = z.object({
  description: z.string().min(10).max(2000),
});
export type SuggestBilan = z.infer<typeof SuggestBilanSchema>;

export const BilanSuggestionSchema = z.object({
  field: z.enum(BILAN_FIELDS),
  /** Toujours un code EXISTANT du référentiel — l'IA n'invente pas de valeur. */
  valueId: z.uuid(),
  label: z.string(),
  confidence: z.enum(['HIGH', 'MEDIUM']),
  /** « N bilans similaires sur ce parc » — la justification vérifiable. */
  similarReports: z.number().int(),
  score: z.number(),
});
export type BilanSuggestion = z.infer<typeof BilanSuggestionSchema>;

export const BilanSuggestionsResponseSchema = z.object({
  suggestions: z.array(BilanSuggestionSchema),
});
export type BilanSuggestionsResponse = z.infer<typeof BilanSuggestionsResponseSchema>;

// ————— Réindexation du corpus (bibliothèque = corpus, D3) —————

export const ReindexResultSchema = z.object({
  documentsIndexed: z.number().int(),
  /** Exclus du corpus (interrupteur) ou format non indexable (non-PDF). */
  documentsSkipped: z.number().int(),
  reportsIndexed: z.number().int(),
  chunks: z.number().int(),
});
export type ReindexResult = z.infer<typeof ReindexResultSchema>;

// ————— Dictée (R5 D5, opt-in) — l'audio ne transite qu'une fois, jamais stocké —————

export const TranscriptionResultSchema = z.object({
  /** À relire avant tout usage (D1) — jamais enregistré tel quel. */
  text: z.string(),
});
export type TranscriptionResult = z.infer<typeof TranscriptionResultSchema>;
