/**
 * Knowledge Base Validators
 * Zod schemas for validating KB requests
 */

import { z } from 'zod';
import {
  ALLOWED_FILE_TYPES,
  ALLOWED_MEDIA_TYPES,
  MAX_FILE_SIZE,
  MAX_MEDIA_SIZE,
  DOCUMENT_CATEGORIES,
} from '@/lib/types/knowledge-base.types';

// Document upload validation
export const uploadDocumentSchema = z.object({
  title: z.string().min(1).max(255).optional(),
  description: z.string().max(1000).optional(),
  category: z.enum(DOCUMENT_CATEGORIES.map(c => c.value) as [string, ...string[]]).optional().default('general'),
});

// File validation helper (document-only, legacy)
export function validateUploadedFile(file: File): { valid: boolean; error?: string } {
  if (!file) {
    return { valid: false, error: 'No file provided' };
  }

  if (file.size > MAX_FILE_SIZE) {
    return { valid: false, error: `File size exceeds ${MAX_FILE_SIZE / (1024 * 1024)}MB limit` };
  }

  const allowedTypes = ALLOWED_FILE_TYPES as readonly string[];
  if (!allowedTypes.includes(file.type)) {
    return { valid: false, error: `File type ${file.type} is not allowed` };
  }

  return { valid: true };
}

// Multimodal file validation (documents, images, videos, audio)
export function validateUploadedMedia(file: File): { valid: boolean; error?: string } {
  if (!file) {
    return { valid: false, error: 'No file provided' };
  }

  if (file.size > MAX_MEDIA_SIZE) {
    return { valid: false, error: `File size exceeds ${MAX_MEDIA_SIZE / (1024 * 1024)}MB limit` };
  }

  const allowedTypes = ALLOWED_MEDIA_TYPES as readonly string[];
  if (!allowedTypes.includes(file.type)) {
    return { valid: false, error: `File type ${file.type} is not allowed. Supported: PDF, Word, Text, CSV, PNG, JPEG, WebP, MP4, MOV, MP3, WAV, M4A` };
  }

  return { valid: true };
}

// RAG query validation (dashboard)
export const ragQuerySchema = z.object({
  query: z.string().min(1).max(2000),
  language: z.enum(['en', 'ar']).optional().default('ar'),
  maxResults: z.number().min(1).max(20).optional().default(5),
  includeCitations: z.boolean().optional().default(true),
});

// N8N RAG query validation
export const n8nRagQuerySchema = z.object({
  auth_token: z.string().min(1),
  user_id: z.string().min(1),
  query: z.string().min(1).max(2000),
  language: z.enum(['en', 'ar']).optional().default('ar'),
  max_results: z.number().min(1).max(20).optional().default(5),
  include_citations: z.boolean().optional().default(true),
});

// Settings update validation
export const updateKBSettingsSchema = z.object({
  isEnabled: z.boolean().optional(),
  maxChunksPerQuery: z.number().min(1).max(20).optional(),
  similarityThreshold: z.number().min(0).max(1).optional(),
  welcomeMessage: z.string().max(500).nullable().optional(),
  customInstructions: z.string().max(2000).nullable().optional(),
});

// Document update validation
export const updateDocumentSchema = z.object({
  title: z.string().min(1).max(255).optional(),
  description: z.string().max(1000).optional(),
  category: z.enum(DOCUMENT_CATEGORIES.map(c => c.value) as [string, ...string[]]).optional(),
});

// N8N KB Sync validation - for syncing documents uploaded directly to Gemini
export const n8nKBSyncSchema = z.object({
  auth_token: z.string().min(1),
  user_id: z.string().min(1),
  gemini_file_name: z.string().min(1), // e.g., "files/abc123"
  gemini_store_name: z.string().min(1), // e.g., "fileSearchStores/xyz789"
  original_name: z.string().min(1),
  mime_type: z.string().min(1),
  file_size: z.number().positive(),
  title: z.string().max(255).optional(),
  category: z.enum(DOCUMENT_CATEGORIES.map(c => c.value) as [string, ...string[]]).optional().default('general'),
});

// Export types for use in routes
export type UploadDocumentInput = z.infer<typeof uploadDocumentSchema>;
export type RAGQueryInput = z.infer<typeof ragQuerySchema>;
export type N8NRAGQueryInput = z.infer<typeof n8nRagQuerySchema>;
export type UpdateKBSettingsInput = z.infer<typeof updateKBSettingsSchema>;
export type UpdateDocumentInput = z.infer<typeof updateDocumentSchema>;
export type N8NKBSyncInput = z.infer<typeof n8nKBSyncSchema>;
