/**
 * Lead CRM Validators
 * Zod validation schemas for lead generation, CRM, scoring, nurturing, and capture
 */

import { z } from 'zod';

// ═══════════════════════════════════════════════════════════════════════
// Enums
// ═══════════════════════════════════════════════════════════════════════

export const leadActivityTypeSchema = z.enum([
  'NOTE', 'CALL', 'EMAIL', 'MEETING', 'WHATSAPP',
  'STATUS_CHANGE', 'STAGE_CHANGE', 'SCORE_CHANGE', 'AI_QUALIFICATION',
]);

export const leadScoringEventTypeSchema = z.enum([
  'RULE_MATCH', 'AI_SCORE', 'MANUAL_ADJUST', 'DECAY',
]);

export const leadNurtureTriggerSchema = z.enum([
  'ON_CAPTURE', 'ON_STAGE_CHANGE', 'ON_SCORE_THRESHOLD', 'MANUAL',
]);

export const leadNurtureChannelSchema = z.enum([
  'EMAIL', 'WHATSAPP', 'SMS', 'WAIT', 'CONDITION',
]);

export const leadCaptureFormTypeSchema = z.enum([
  'EMBED', 'POPUP', 'LANDING', 'WHATSAPP',
]);

// ═══════════════════════════════════════════════════════════════════════
// Lead CRUD
// ═══════════════════════════════════════════════════════════════════════

export const leadCreateSchema = z.object({
  name: z.string().min(1, 'Name is required').max(200),
  phone: z.string().max(20).optional(),
  email: z.string().email('Invalid email').optional(),
  company: z.string().max(200).optional(),
  source: z.string().min(1, 'Source is required').max(100),
  campaignId: z.string().optional(),
  interest: z.string().max(500).optional(),
  notes: z.string().max(5000).optional(),
  customFields: z.record(z.unknown()).optional(),
  tags: z.array(z.string().max(50)).max(20).optional(),
  language: z.enum(['ar', 'en']).optional(),
  sourceChannel: z.string().max(50).optional(),
  dealValue: z.number().min(0).optional(),
  dealCurrency: z.string().length(3).optional(),
});

export const leadUpdateSchema = z.object({
  name: z.string().min(1).max(200).optional(),
  phone: z.string().max(20).optional(),
  email: z.string().email().optional(),
  company: z.string().max(200).optional(),
  status: z.string().max(50).optional(),
  interest: z.string().max(500).optional(),
  notes: z.string().max(5000).optional(),
  customFields: z.record(z.unknown()).optional(),
  tags: z.array(z.string().max(50)).max(20).optional(),
  assignedTo: z.string().nullable().optional(),
  pipelineStageId: z.string().nullable().optional(),
  dealValue: z.number().min(0).nullable().optional(),
  dealCurrency: z.string().length(3).optional(),
  expectedCloseAt: z.coerce.date().nullable().optional(),
  lostReason: z.string().max(500).optional(),
  language: z.string().max(5).optional(),
});

export const leadBulkSchema = z.object({
  leadIds: z.array(z.string()).min(1, 'At least one lead required').max(100),
  action: z.enum(['assign', 'move_stage', 'add_tag', 'remove_tag', 'delete']),
  value: z.string().optional(),
});

export const leadFiltersSchema = z.object({
  status: z.string().optional(),
  source: z.string().optional(),
  pipelineStageId: z.string().optional(),
  assignedTo: z.string().optional(),
  minScore: z.coerce.number().optional(),
  maxScore: z.coerce.number().optional(),
  tags: z.array(z.string()).optional(),
  dateFrom: z.coerce.date().optional(),
  dateTo: z.coerce.date().optional(),
  search: z.string().optional(),
  page: z.coerce.number().min(1).optional().default(1),
  limit: z.coerce.number().min(1).max(100).optional().default(20),
  sortBy: z.string().optional().default('createdAt'),
  sortOrder: z.enum(['asc', 'desc']).optional().default('desc'),
});

export const leadMoveSchema = z.object({
  pipelineStageId: z.string().min(1, 'Pipeline stage required'),
});

// ═══════════════════════════════════════════════════════════════════════
// Pipeline Stages
// ═══════════════════════════════════════════════════════════════════════

export const pipelineStageCreateSchema = z.object({
  name: z.string().min(1, 'Name is required').max(50),
  nameAr: z.string().max(50).optional(),
  color: z.string().regex(/^#[0-9a-fA-F]{6}$/, 'Invalid color hex').optional(),
  sortOrder: z.number().min(0).optional(),
  isDefault: z.boolean().optional(),
  isWon: z.boolean().optional(),
  isLost: z.boolean().optional(),
});

export const pipelineStageUpdateSchema = pipelineStageCreateSchema.partial();

export const pipelineStageReorderSchema = z.object({
  stages: z.array(z.object({
    id: z.string(),
    sortOrder: z.number().min(0),
  })).min(1),
});

// ═══════════════════════════════════════════════════════════════════════
// Activities
// ═══════════════════════════════════════════════════════════════════════

export const leadActivityCreateSchema = z.object({
  type: leadActivityTypeSchema,
  title: z.string().min(1, 'Title required').max(200),
  description: z.string().max(5000).optional(),
  metadata: z.record(z.unknown()).optional(),
});

// ═══════════════════════════════════════════════════════════════════════
// Scoring Rules
// ═══════════════════════════════════════════════════════════════════════

export const scoringConditionSchema = z.object({
  field: z.string().optional(),
  operator: z.enum(['equals', 'contains', 'gt', 'lt', 'exists', 'not_exists', 'in', 'event']),
  value: z.union([z.string(), z.number(), z.boolean(), z.array(z.string())]).optional(),
  eventType: z.string().optional(),
});

export const scoringRuleCreateSchema = z.object({
  name: z.string().min(1, 'Name required').max(100),
  category: z.string().min(1, 'Category required').max(50),
  condition: scoringConditionSchema,
  points: z.number().min(-100).max(100),
  isActive: z.boolean().optional().default(true),
});

export const scoringRuleUpdateSchema = scoringRuleCreateSchema.partial();

// ═══════════════════════════════════════════════════════════════════════
// Nurture Sequences
// ═══════════════════════════════════════════════════════════════════════

export const nurtureStepSchema = z.object({
  stepOrder: z.number().min(0),
  channel: leadNurtureChannelSchema,
  delayHours: z.number().min(0).max(8760), // max 1 year
  subject: z.string().max(200).optional(),
  content: z.string().max(10000).optional(),
  config: z.record(z.unknown()).optional(),
});

export const nurtureSequenceCreateSchema = z.object({
  name: z.string().min(1, 'Name required').max(100),
  description: z.string().max(500).optional(),
  triggerType: leadNurtureTriggerSchema,
  triggerConditions: z.record(z.unknown()).optional(),
  steps: z.array(nurtureStepSchema).min(1, 'At least one step required').max(50),
});

export const nurtureSequenceUpdateSchema = z.object({
  name: z.string().min(1).max(100).optional(),
  description: z.string().max(500).optional(),
  triggerType: leadNurtureTriggerSchema.optional(),
  triggerConditions: z.record(z.unknown()).optional(),
  isActive: z.boolean().optional(),
  steps: z.array(nurtureStepSchema).min(1).max(50).optional(),
});

// ═══════════════════════════════════════════════════════════════════════
// Capture Forms
// ═══════════════════════════════════════════════════════════════════════

export const captureFormFieldSchema = z.object({
  name: z.string().min(1).max(50),
  label: z.string().min(1).max(100),
  labelAr: z.string().max(100).optional(),
  type: z.enum(['text', 'email', 'phone', 'select', 'textarea', 'checkbox']),
  required: z.boolean(),
  placeholder: z.string().max(200).optional(),
  options: z.array(z.string().max(100)).optional(),
});

export const captureFormStylingSchema = z.object({
  primaryColor: z.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
  backgroundColor: z.string().regex(/^#[0-9a-fA-F]{6}$/).optional(),
  fontFamily: z.string().max(100).optional(),
  borderRadius: z.string().max(20).optional(),
  buttonText: z.string().max(50).optional(),
  buttonTextAr: z.string().max(50).optional(),
  successMessage: z.string().max(200).optional(),
  successMessageAr: z.string().max(200).optional(),
});

export const captureFormCreateSchema = z.object({
  name: z.string().min(1, 'Name required').max(100),
  formType: leadCaptureFormTypeSchema,
  fields: z.array(captureFormFieldSchema).min(1, 'At least one field required').max(20),
  styling: captureFormStylingSchema.optional(),
});

export const captureFormUpdateSchema = captureFormCreateSchema.partial();

export const captureFormSubmissionSchema = z.object({
  formId: z.string().min(1, 'Form ID required'),
  data: z.record(z.string()),
  sourceChannel: z.string().max(50).optional(),
  metadata: z.record(z.unknown()).optional(),
});

// ═══════════════════════════════════════════════════════════════════════
// Inferred Types
// ═══════════════════════════════════════════════════════════════════════

export type LeadCreateValidated = z.infer<typeof leadCreateSchema>;
export type LeadUpdateValidated = z.infer<typeof leadUpdateSchema>;
export type LeadBulkValidated = z.infer<typeof leadBulkSchema>;
export type LeadFiltersValidated = z.infer<typeof leadFiltersSchema>;
export type PipelineStageCreateValidated = z.infer<typeof pipelineStageCreateSchema>;
export type PipelineStageReorderValidated = z.infer<typeof pipelineStageReorderSchema>;
export type LeadActivityCreateValidated = z.infer<typeof leadActivityCreateSchema>;
export type ScoringRuleCreateValidated = z.infer<typeof scoringRuleCreateSchema>;
export type NurtureSequenceCreateValidated = z.infer<typeof nurtureSequenceCreateSchema>;
export type NurtureSequenceUpdateValidated = z.infer<typeof nurtureSequenceUpdateSchema>;
export type CaptureFormCreateValidated = z.infer<typeof captureFormCreateSchema>;
export type CaptureFormSubmissionValidated = z.infer<typeof captureFormSubmissionSchema>;
