import { z } from 'zod';
import { Uuid, DateOnly } from './common';
import { AI_PROPOSAL_TYPE, AI_PROPOSAL_STATUS } from '../enums';

export const AiProposalQuerySchema = z.object({
  warehouseId: Uuid.optional(),
  storerId: Uuid.optional(),
  type: z.enum(AI_PROPOSAL_TYPE).optional(),
  status: z.enum(AI_PROPOSAL_STATUS).optional(),
  severity: z.string().optional(),
});

export const DecideProposalSchema = z.object({
  decision: z.enum(['ACCEPT', 'REJECT']),
  notes: z.string().max(1000).optional(),
  /** For ASN/ORDER proposals: the user may edit the draft before accepting. */
  editedPayload: z.record(z.unknown()).optional(),
});
export type DecideProposalDto = z.infer<typeof DecideProposalSchema>;

/** Document intake: text extracted from a PO / packing list / email, or an uploaded file id. */
export const DocumentIntakeBaseSchema = z.object({
  warehouseId: Uuid,
  storerId: Uuid,
  target: z.enum(['ASN', 'ORDER']),
  text: z.string().max(200000).optional(),
  hints: z.string().max(1000).optional(),
});
/** JSON intake: text is mandatory. The multipart variant (file upload) uses the base schema. */
export const DocumentIntakeSchema = DocumentIntakeBaseSchema.refine((v) => !!v.text, { message: 'text is required (or upload a file on /ai/intake/upload)' });
export type DocumentIntakeDto = z.infer<typeof DocumentIntakeBaseSchema>;

export const NlQuerySchema = z.object({
  warehouseId: Uuid.optional(),
  conversationId: Uuid.optional(),
  question: z.string().min(1).max(2000),
});
export type NlQueryDto = z.infer<typeof NlQuerySchema>;

export const RunAnalysisSchema = z.object({
  warehouseId: Uuid,
  storerId: Uuid.optional(),
  kind: z.enum(['RECEIVING_ANOMALY', 'INVENTORY_ANOMALY', 'BILLING_ANOMALY', 'SLOTTING_RECOMMENDATION', 'WORKLOAD_FORECAST']),
  from: DateOnly.optional(),
  to: DateOnly.optional(),
  horizonDays: z.number().int().min(1).max(90).default(14),
});
export type RunAnalysisDto = z.infer<typeof RunAnalysisSchema>;

export const DraftDiscrepancyEmailSchema = z.object({
  asnId: Uuid,
  tone: z.enum(['FORMAL', 'NEUTRAL', 'BRIEF']).default('FORMAL'),
  language: z.enum(['en', 'ar']).default('en'),
});

/** Structured output contract the LLM must return for document intake (validated server-side). */
export const AiAsnDraftSchema = z.object({
  reference: z.string().optional(),
  supplierName: z.string().optional(),
  expectedDate: z.string().optional(),
  containerNo: z.string().optional(),
  containerSize: z.string().optional(),
  lines: z.array(
    z.object({
      itemCode: z.string().optional(),
      description: z.string().optional(),
      qty: z.number().positive(),
      uom: z.string().optional(),
      lot: z.string().optional(),
      expiryDate: z.string().optional(),
      confidence: z.number().min(0).max(1).optional(),
    }),
  ),
  warnings: z.array(z.string()).default([]),
});
export type AiAsnDraft = z.infer<typeof AiAsnDraftSchema>;

export const AiOrderDraftSchema = z.object({
  reference: z.string().optional(),
  customerName: z.string().optional(),
  deliveryLocationCode: z.string().optional(),
  requestedShipDate: z.string().optional(),
  address: z.string().optional(),
  lines: z.array(
    z.object({
      itemCode: z.string().optional(),
      description: z.string().optional(),
      qty: z.number().positive(),
      uom: z.string().optional(),
      serials: z.array(z.string()).default([]),
      confidence: z.number().min(0).max(1).optional(),
    }),
  ),
  warnings: z.array(z.string()).default([]),
});
export type AiOrderDraft = z.infer<typeof AiOrderDraftSchema>;
