/**
 * Predictive Analytics Types
 * Data models for churn prediction, health scoring, and retention campaigns
 */

import { z } from 'zod';
import type { CompleteFeatureVector } from './feature-extractor.js';

// ============================================================================
// Churn Prediction Types
// ============================================================================

export const RiskSegmentEnum = z.enum(['critical', 'high', 'medium', 'low']);
export const ModelTypeEnum = z.enum(['xgboost', 'neural', 'ensemble']);
export const PredictionHorizonEnum = z.enum(['7', '14', '30']);

export const ChurnPredictionSchema = z.object({
  userId: z.string(),
  productId: z.string(),
  predictionHorizon: z.coerce.number().int().min(7).max(30),
  churnProbability: z.number().min(0).max(1),
  riskSegment: RiskSegmentEnum,
  confidenceScore: z.number().min(0).max(1),
  features: z.record(z.number()),
  featureVersion: z.string(),
  modelVersion: z.string(),
  modelType: ModelTypeEnum,
  predictionTimestamp: z.string().datetime(),
});

export type ChurnPredictionInput = z.infer<typeof ChurnPredictionSchema>;

export interface RiskFactor {
  feature: string;
  contribution: number;
  direction: 'positive' | 'negative';
  description: string;
}

export interface ChurnExplanation {
  topRiskFactors: RiskFactor[];
  globalFeatureImportance: Array<{ feature: string; importance: number }>;
  nlExplanation: string;
  suggestedActions: string[];
}

export interface UserChurnPredictionDoc extends ChurnPredictionInput {
  id: string;
  pk: string;
  explanation: ChurnExplanation;
  interventionHistory: Array<{
    action: string;
    timestamp: string;
    outcome?: 'responded' | 'ignored' | 'churned' | 'retained';
  }>;
  actualChurned?: boolean;
  validationDate?: string;
  createdAt: string;
  ttl: number;
}

// ============================================================================
// Health Score Types
// ============================================================================

export const HealthStatusEnum = z.enum(['critical', 'warning', 'healthy']);
export const TrendEnum = z.enum(['improving', 'stable', 'declining']);

export interface HealthDimension {
  score: number;
  metrics: Record<string, number>;
  trend: 'improving' | 'stable' | 'declining';
}

export interface ProductHealthDimensions {
  acquisition: HealthDimension;
  activation: HealthDimension;
  retention: HealthDimension;
  engagement: HealthDimension;
  revenue: HealthDimension;
  stability: HealthDimension;
}

export interface HealthAnomaly {
  metric: string;
  expectedValue: number;
  actualValue: number;
  deviationPercent: number;
  severity: 'critical' | 'warning';
  suggestedCause?: string;
}

export interface HealthForecast {
  expectedHealthScore: number;
  confidenceInterval: [number, number];
}

export interface ProductHealthScoreDoc {
  id: string;
  productId: string;
  date: string;
  overallHealthScore: number;
  healthStatus: 'critical' | 'warning' | 'healthy';
  dimensions: ProductHealthDimensions;
  anomalies: HealthAnomaly[];
  forecasts: {
    next7Days: HealthForecast;
    next30Days: HealthForecast;
  };
  vsBaseline7Day: number;
  vsBaseline30Day: number;
  createdAt: string;
  ttl: number;
}

// ============================================================================
// Feature Store Types
// ============================================================================

export interface UserFeatureVectorDoc {
  id: string;
  userId: string;
  productId: string;
  features: CompleteFeatureVector;
  normalizedFeatures: Record<string, number>;
  featureSchemaVersion: string;
  computedAt: string;
  observationWindow: {
    start: string;
    end: string;
  };
  ttl: number;
}

export interface FeatureDefinition {
  id: string;
  productId: string;
  name: string;
  description: string;
  category: 'behavior' | 'engagement' | 'performance' | 'social' | 'revenue' | 'product_specific';
  dataType: 'numeric' | 'boolean' | 'categorical';
  normalization: 'min_max' | 'z_score' | 'none';
  defaultValue: number;
  importanceWeight: number;
  isEnabled: boolean;
  createdAt: string;
}

// ============================================================================
// Campaign Types
// ============================================================================

export const CampaignStatusEnum = z.enum(['draft', 'active', 'paused', 'completed']);
export const CampaignTriggerTypeEnum = z.enum(['churn_risk', 'health_score_drop', 'behavioral', 'scheduled']);
export const CampaignChannelEnum = z.enum(['email', 'push', 'in_app', 'slack_cs']);

export const CampaignConditionSchema = z.object({
  field: z.string(),
  operator: z.enum(['gt', 'lt', 'eq', 'in', 'contains']),
  value: z.unknown(),
});

export const CampaignMessageSchema = z.object({
  channel: CampaignChannelEnum,
  templateId: z.string(),
  variant: z.string().optional(),
  delayHours: z.number().min(0).optional(),
  conditions: z.array(CampaignConditionSchema).optional(),
});

export const CreateCampaignSchema = z.object({
  name: z.string().min(1).max(200),
  description: z.string(),
  productId: z.string(),
  trigger: z.object({
    type: CampaignTriggerTypeEnum,
    conditions: z.array(CampaignConditionSchema),
  }),
  audience: z.object({
    riskSegments: z.array(z.string()).optional(),
    products: z.array(z.string()).optional(),
    userSegments: z.array(z.string()).optional(),
    excludeRecentContact: z.number().optional(),
  }),
  messages: z.array(CampaignMessageSchema).min(1),
});

export type CreateCampaignInput = z.infer<typeof CreateCampaignSchema>;

export interface RetentionCampaignDoc extends CreateCampaignInput {
  id: string;
  status: 'draft' | 'active' | 'paused' | 'completed';
  stats: {
    triggered: number;
    sent: number;
    opened: number;
    clicked: number;
    converted: number;
    controlGroupSize: number;
    controlChurnRate: number;
    treatmentChurnRate: number;
  };
  createdAt: string;
  updatedAt: string;
  ttl: number;
}

// ============================================================================
// API Types
// ============================================================================

export const ChurnScoreRequestSchema = z.object({
  userId: z.string(),
  productId: z.string(),
  horizon: PredictionHorizonEnum.default('30'),
});

export const ChurnBatchRequestSchema = z.object({
  productId: z.string(),
  userIds: z.array(z.string()).max(100),
  horizon: PredictionHorizonEnum.default('30'),
});

export const AtRiskUsersQuerySchema = z.object({
  productId: z.string().optional(),
  segment: RiskSegmentEnum.optional(),
  limit: z.coerce.number().int().min(1).max(200).default(50),
  offset: z.coerce.number().int().min(0).default(0),
});

export const CampaignTriggerSchema = z.object({
  campaignId: z.string(),
  testUserId: z.string().optional(),
});

// ============================================================================
// Model Performance Types
// ============================================================================

export interface ModelPerformanceMetrics {
  modelVersion: string;
  modelType: string;
  trainedAt: string;
  auc: number;
  precisionAt10: number;
  recallAt10: number;
  calibrationSlope: number;
  calibrationIntercept: number;
  perProductPerformance: Record<string, { auc: number; sampleSize: number }>;
  featureImportance: Array<{ feature: string; importance: number }>;
}

export interface ModelPerformanceDoc {
  id: string;
  metrics: ModelPerformanceMetrics;
  isActive: boolean;
  createdAt: string;
  ttl: number;
}
