import { z } from 'zod';
import { existsSync } from 'fs';
import { checkFlag } from './voiceprint.feature-flags';

// P3-4 fix: Use strict() to catch typos in env var names
// P3-1 fix: Use safeParse() to avoid module-level crash on missing env vars
const envSchema = z.object({
  ECAPA_TDNN_MODEL_PATH: z.string().default('./models/ecapa-tdnn'),
  ML_SERVICE_URL: z.string().default('http://localhost:8001'),
  FAISS_INDEX_PATH: z.string().default('./data/voiceprint_faiss.index'),
  AUDIO_STORAGE_BUCKET: z.string().default('voiceprint-audio'),
  AUDIO_STORAGE_ENDPOINT: z.string().default('http://localhost:9000'),
  SYNTHETIC_THRESHOLD: z.string().transform(Number).default('0.75'),
  ENROLLMENT_MIN_DURATION_SEC: z.string().transform(Number).default('3'),
  ENROLLMENT_MAX_DURATION_SEC: z.string().transform(Number).default('60'),
  EMBEDDING_DIMENSIONS: z.string().transform(Number).default('192'),
  BATCH_MAX_FILES: z.string().transform(Number).default('20'),
  ANALYSIS_TIMEOUT_MS: z.string().transform(Number).default('30000'),
}).strict();

const envInput = {
  ECAPA_TDNN_MODEL_PATH: process.env.ECAPA_TDNN_MODEL_PATH,
  ML_SERVICE_URL: process.env.ML_SERVICE_URL,
  FAISS_INDEX_PATH: process.env.FAISS_INDEX_PATH,
  AUDIO_STORAGE_BUCKET: process.env.AUDIO_STORAGE_BUCKET,
  AUDIO_STORAGE_ENDPOINT: process.env.AUDIO_STORAGE_ENDPOINT,
  SYNTHETIC_THRESHOLD: process.env.SYNTHETIC_THRESHOLD,
  ENROLLMENT_MIN_DURATION_SEC: process.env.ENROLLMENT_MIN_DURATION_SEC,
  ENROLLMENT_MAX_DURATION_SEC: process.env.ENROLLMENT_MAX_DURATION_SEC,
  EMBEDDING_DIMENSIONS: process.env.EMBEDDING_DIMENSIONS,
  BATCH_MAX_FILES: process.env.BATCH_MAX_FILES,
  ANALYSIS_TIMEOUT_MS: process.env.ANALYSIS_TIMEOUT_MS,
};

const parsed = envSchema.safeParse(envInput);
export const voicePrintEnv = parsed.success
  ? parsed.data
  : envSchema.parse({}); // fallback to all defaults

// P3-3 fix: Validate model path exists at startup (warn, not crash)
if (voicePrintEnv.ECAPA_TDNN_MODEL_PATH && !existsSync(voicePrintEnv.ECAPA_TDNN_MODEL_PATH)) {
  console.warn(
    `[VoicePrint] Model path not found: ${voicePrintEnv.ECAPA_TDNN_MODEL_PATH} (using mock model)`
  );
}

if (!parsed.success) {
  console.warn('[VoicePrint] Env validation warnings:', parsed.error.issues.map((i: z.ZodIssue) => `${i.path.join('.')}: ${i.message}`).join(', '));
}

// Audio source types
export enum VoicePrintSource {
  UPLOAD = 'upload',
  S3 = 's3',
  URL = 'url',
  REALTIME = 'realtime',
}

// Analysis job status
export enum AnalysisJobStatus {
  PENDING = 'pending',
  PROCESSING = 'processing',
  COMPLETED = 'completed',
  FAILED = 'failed',
  CANCELLED = 'cancelled',
}

// Detection result types
export enum DetectionType {
  SYNTHETIC_VOICE = 'synthetic_voice',
  VOICE_CLONE = 'voice_clone',
  DEEPFAKE = 'deepfake',
  NATURAL = 'natural',
}

// Confidence levels
export enum ConfidenceLevel {
  LOW = 'low',
  MEDIUM = 'medium',
  HIGH = 'high',
  VERY_HIGH = 'very_high',
}

// Audio preprocessing configuration
export const audioPreprocessingConfig = {
  sampleRate: 16000,
  channels: 1,
  bitDepth: 16,
  vadThreshold: 0.5,
  noiseReduction: true,
  maxSilenceDurationMs: 500,
};

// Feature flags - use centralized system
export const voicePrintFeatureFlags = {
  enableMLService: checkFlag('voiceprint.enable.ml.service', false),
  enableFAISSIndex: checkFlag('voiceprint.enable.faiss.index', true),
  enableBatchAnalysis: checkFlag('voiceprint.enable.batch.analysis', true),
  enableRealtimeAnalysis: checkFlag('voiceprint.enable.realtime.analysis', false),
  enableMockModel: checkFlag('voiceprint.enable.mock.model', true),
};

// Rate limits for voice analysis
export const voicePrintRateLimits = {
  basic: {
    analysesPerMinute: 5,
    enrollmentsPerDay: 10,
    maxAudioFileSizeMB: 50,
  },
  plus: {
    analysesPerMinute: 30,
    enrollmentsPerDay: 50,
    maxAudioFileSizeMB: 200,
  },
  premium: {
    analysesPerMinute: 100,
    enrollmentsPerDay: 500,
    maxAudioFileSizeMB: 500,
  },
};
