import { z } from 'zod';

// Define the schema for a call log record
const callLogSchema = z.object({
  caller_name: z.string().optional(),
  caller_number: z.string().optional(),
  client_id: z.string({ required_error: 'Client ID is required' }).uuid('Invalid Client ID format'),
  call_type: z.enum(['inbound', 'outbound', 'email', 'voicemail'], {
    errorMap: () => ({ message: "Call type must be one of: inbound, outbound, email, voicemail" }),
  }).default('inbound'),
  status: z.string().default('pending'),
  duration: z.number().nonnegative('Duration must be a positive number').optional(),
  notes: z.string().optional(),
  created_at: z.string().optional(), // Allow existing timestamps for restoration/import
});

/**
 * Validates a single call log record against the schema.
 * @param {Object} record - The call log record to validate.
 * @returns {Object} - { valid: boolean, errors: string[] }
 */
export function validateCallLogRecord(record) {
  // Pre-process numeric fields if they come as strings
  const processedRecord = {
    ...record,
    duration: typeof record.duration === 'string' ? parseInt(record.duration, 10) : record.duration,
  };

  const result = callLogSchema.safeParse(processedRecord);
  if (result.success) {
    return { valid: true, errors: [], sanitizedRecord: result.data };
  } else {
    const formattedErrors = result.error.errors.map(err => `${err.path.join('.')}: ${err.message}`);
    return { valid: false, errors: formattedErrors };
  }
}

/**
 * Validates a list of call log records.
 * @param {Array} records - Array of call log objects.
 * @param {Set} validClientIds - Set of valid client UUIDs to check existence against.
 * @returns {Object} - { valid: boolean, errors: Array<{row: number, messages: string[]}>, sanitizedRecords: Array }
 */
export function validateCallLogImport(records, validClientIds = new Set()) {
  const errors = [];
  const sanitizedRecords = [];

  records.forEach((record, index) => {
    const rowErrors = [];
    const rowNum = index + 1;

    // 1. Schema Validation
    const validationResult = validateCallLogRecord(record);
    if (!validationResult.valid) {
      rowErrors.push(...validationResult.errors);
    }

    // 2. Data Integrity: Client ID Existence
    if (record.client_id && validClientIds.size > 0 && !validClientIds.has(record.client_id)) {
      rowErrors.push(`Client ID '${record.client_id}' does not exist in the system.`);
    }

    // 3. Data Integrity: Check for future dates if created_at is provided
    if (record.created_at) {
        const date = new Date(record.created_at);
        if (isNaN(date.getTime())) {
            rowErrors.push('Invalid date format for created_at');
        } else if (date > new Date()) {
            rowErrors.push('Call log date cannot be in the future');
        }
    }

    // 4. Sanitization (Basic XSS prevention is handled by React usually, but we ensure string types)
    // Zod schema ensures types, but let's trim strings
    const cleanRecord = validationResult.sanitizedRecord;
    if (cleanRecord) {
        if (cleanRecord.notes) cleanRecord.notes = cleanRecord.notes.trim();
        if (cleanRecord.caller_name) cleanRecord.caller_name = cleanRecord.caller_name.trim();
    }

    if (rowErrors.length > 0) {
      errors.push({ row: rowNum, messages: rowErrors });
    } else if (cleanRecord) {
      sanitizedRecords.push(cleanRecord);
    }
  });

  return {
    valid: errors.length === 0,
    errors,
    sanitizedRecords: errors.length === 0 ? sanitizedRecords : [] // All or nothing approach usually safer for bulk
  };
}