import { z } from 'zod';

// ============================================================================
// Error Fingerprinting Types
// ============================================================================

export const ErrorFingerprintSchema = z.object({
  id: z.string(), // ef_<uuid>
  productId: z.string(),
  fingerprintHash: z.string(), // SHA-256 of normalized error

  // Normalized error signature
  errorType: z.string(), // Exception class/name
  messageTemplate: z.string(), // Normalized message with placeholders
  stackSignature: z.string(), // Normalized stack frames

  // Source location (normalized)
  sourceLocation: z
    .object({
      file: z.string().optional(),
      function: z.string().optional(),
      line: z.number().optional(),
    })
    .optional(),

  // Metadata
  createdAt: z.string(),
  updatedAt: z.string(),
  occurrenceCount: z.number().default(1),
  uniqueUsers: z.number().default(1),

  // TTL for cleanup
  ttl: z.number().default(90 * 86400), // 90 days
});

export type ErrorFingerprint = z.infer<typeof ErrorFingerprintSchema>;

// ============================================================================
// Error Cluster Types
// ============================================================================

export const ClusterStatusSchema = z.enum(['active', 'investigating', 'resolved', 'ignored']);
export type ClusterStatus = z.infer<typeof ClusterStatusSchema>;

export const CommonContextSchema = z.object({
  osVersions: z.array(z.object({ version: z.string(), count: z.number() })),
  appVersions: z.array(z.object({ version: z.string(), count: z.number() })),
  deviceModels: z.array(z.object({ model: z.string(), count: z.number() })),
  screenContexts: z.array(z.object({ screen: z.string(), count: z.number() })),
});

export type CommonContext = z.infer<typeof CommonContextSchema>;

export const ErrorClusterDocSchema = z.object({
  id: z.string(), // ec_<uuid>
  productId: z.string(), // partition key
  fingerprintHash: z.string(),

  // Cluster metadata
  firstSeenAt: z.string(), // ISO 8601
  lastSeenAt: z.string(),
  occurrenceCount: z.number(), // Total occurrences
  uniqueUsers: z.number(), // Affected user count

  // Error signature
  errorType: z.string(), // Exception class/name
  messageTemplate: z.string(), // Normalized message with placeholders
  stackSignature: z.string(), // Normalized stack frames

  // Vector embedding for semantic search
  embedding: z.array(z.number()).optional(), // 1536-dim from text-embedding-3-small
  embeddingVersion: z.string().optional(), // Model version for re-embedding

  // Context patterns (auto-extracted)
  commonContext: CommonContextSchema.optional(),

  // Related data
  relatedClusterIds: z.array(z.string()).default([]), // Similar clusters (vector similarity)
  mergedIntoClusterId: z.string().optional(), // If deduplicated

  // Resolution tracking
  status: ClusterStatusSchema.default('active'),
  resolvedAt: z.string().optional(),
  resolutionCommit: z.string().optional(), // Link to fix

  // Analysis metadata
  lastAnalyzedAt: z.string().optional(),
  insightId: z.string().optional(), // Link to latest diagnostic insight

  // Timestamps
  createdAt: z.string(),
  updatedAt: z.string(),
  ttl: z.number().default(90 * 86400), // 90 days
});

export type ErrorClusterDoc = z.infer<typeof ErrorClusterDocSchema>;

// ============================================================================
// Cluster Analysis Types
// ============================================================================

export const ClusterAnalysisSchema = z.object({
  id: z.string(), // ca_<uuid>
  clusterId: z.string(),
  productId: z.string(),

  // Analysis metadata
  analyzedAt: z.string(),
  analysisType: z.enum(['root_cause', 'pattern', 'comparison', 'trend']),

  // AI-generated summary
  summary: z.string(), // "This appears to be a memory leak in the image cache..."
  patternDescription: z.string(), // Detailed pattern analysis

  // Key observations
  keyObservations: z.array(
    z.object({
      observation: z.string(),
      evidence: z.string(),
      confidence: z.enum(['high', 'medium', 'low']),
    })
  ),

  // Related clusters
  similarClusters: z.array(
    z.object({
      clusterId: z.string(),
      similarityScore: z.number(),
      reason: z.string(),
    })
  ),

  // Timestamps
  createdAt: z.string(),
  updatedAt: z.string(),
  ttl: z.number().default(90 * 86400),
});

export type ClusterAnalysis = z.infer<typeof ClusterAnalysisSchema>;

// ============================================================================
// Diagnostic Insight Types
// ============================================================================

export const RootCauseCategorySchema = z.enum([
  'config',
  'dependency',
  'logic',
  'resource',
  'external',
  'unknown',
]);
export type RootCauseCategory = z.infer<typeof RootCauseCategorySchema>;

export const EvidenceTypeSchema = z.enum([
  'stack_trace',
  'telemetry_pattern',
  'device_correlation',
  'api_failure',
  'similar_issue',
  'config_mismatch',
  'version_regression',
]);
export type EvidenceType = z.infer<typeof EvidenceTypeSchema>;

export const EvidenceSchema = z.object({
  type: EvidenceTypeSchema,
  description: z.string(),
  strength: z.enum(['strong', 'moderate', 'weak']),
  data: z.record(z.unknown()).optional(),
});

export type Evidence = z.infer<typeof EvidenceSchema>;

export const SimilarResolvedIssueSchema = z.object({
  clusterId: z.string(),
  resolution: z.string(),
  confidence: z.number(), // 0.0-1.0
});

export type SimilarResolvedIssue = z.infer<typeof SimilarResolvedIssueSchema>;

export const FeedbackStatsSchema = z.object({
  helpful: z.number().default(0),
  notHelpful: z.number().default(0),
  engineerNotes: z.array(z.string()).default([]),
});

export type FeedbackStats = z.infer<typeof FeedbackStatsSchema>;

export const DiagnosticInsightDocSchema = z.object({
  id: z.string(), // di_<uuid>
  clusterId: z.string(), // partition key (with productId)
  productId: z.string(),

  // AI-generated analysis
  analysisType: z.enum(['root_cause', 'pattern', 'comparison', 'trend']),
  generatedAt: z.string(),

  // LLM output
  rootCauseCategory: RootCauseCategorySchema,
  hypothesis: z.string(), // Natural language explanation
  reasoning: z.string(), // Why LLM thinks this
  confidence: z.enum(['high', 'medium', 'low']),
  confidenceScore: z.number(), // 0.0-1.0

  // Evidence
  evidence: z.array(EvidenceSchema),

  // Suggested actions
  suggestedInvestigation: z.array(z.string()),
  potentialFixDirection: z.string().optional(),
  similarResolvedIssues: z.array(SimilarResolvedIssueSchema).optional(),

  // Feedback
  feedbackStats: FeedbackStatsSchema.default({ helpful: 0, notHelpful: 0, engineerNotes: [] }),

  // LLM metadata
  modelUsed: z.string(), // gpt-4o, gpt-4o-mini
  promptTokens: z.number(),
  completionTokens: z.number(),

  // Correlation IDs for context
  correlationIds: z.array(z.string()).optional(),
  telemetryEventIds: z.array(z.string()).optional(),

  createdAt: z.string(),
  updatedAt: z.string(),
  ttl: z.number().default(90 * 86400),
});

export type DiagnosticInsightDoc = z.infer<typeof DiagnosticInsightDocSchema>;

// ============================================================================
// Natural Language Query Types
// ============================================================================

export const QueryIntentSchema = z.enum([
  'root_cause',
  'pattern_search',
  'comparison',
  'trend',
  'impact',
]);
export type QueryIntent = z.infer<typeof QueryIntentSchema>;

export const ExtractedEntitiesSchema = z.object({
  products: z.array(z.string()).optional(),
  timeRange: z.object({ start: z.string(), end: z.string() }).optional(),
  errorTypes: z.array(z.string()).optional(),
  platforms: z.array(z.string()).optional(),
  userSegments: z.array(z.string()).optional(),
  clusterIds: z.array(z.string()).optional(),
});

export type ExtractedEntities = z.infer<typeof ExtractedEntitiesSchema>;

export const SupportingDataSchema = z.object({
  type: z.enum(['cluster', 'telemetry', 'session', 'insight', 'trend', 'comparison']),
  id: z.string(),
  relevanceScore: z.number(),
  title: z.string().optional(),
  data: z.record(z.unknown()).optional(),
});

export type SupportingData = z.infer<typeof SupportingDataSchema>;

export const NaturalLanguageQueryDocSchema = z.object({
  id: z.string(), // nq_<uuid>
  userId: z.string(), // Admin who asked
  productId: z.string().optional(), // Optional filter

  // Query
  rawQuery: z.string(), // "Why did iOS keyboard crash yesterday?"
  parsedIntent: QueryIntentSchema,
  extractedEntities: ExtractedEntitiesSchema,

  // Execution
  executedQuery: z.string().optional(), // Translated Cosmos query
  dataSources: z.array(z.string()).default([]), // Clusters, telemetry, sessions accessed
  executionTimeMs: z.number().optional(),

  // Response
  aiResponse: z.string().optional(), // Generated answer
  confidence: z.number().optional(), // Overall confidence
  supportingData: z.array(SupportingDataSchema).optional(),

  // Feedback
  userRating: z.enum(['helpful', 'not_helpful']).optional(),
  userComment: z.string().optional(),

  createdAt: z.string(),
  ttl: z.number().default(30 * 86400), // 30 days
});

export type NaturalLanguageQueryDoc = z.infer<typeof NaturalLanguageQueryDocSchema>;

// ============================================================================
// Analysis Request/Response Types
// ============================================================================

export const AnalyzeClusterRequestSchema = z.object({
  clusterId: z.string(),
  analysisType: z.enum(['root_cause', 'pattern', 'comparison', 'trend']).default('root_cause'),
  modelPreference: z.enum(['gpt-4o-mini', 'gpt-4o']).default('gpt-4o-mini'),
  includeTelemetry: z.boolean().default(true),
  includeSimilarClusters: z.boolean().default(true),
});

export type AnalyzeClusterRequest = z.infer<typeof AnalyzeClusterRequestSchema>;

export const SubmitFeedbackRequestSchema = z.object({
  insightId: z.string(),
  rating: z.enum(['helpful', 'not_helpful']),
  note: z.string().optional(),
});

export type SubmitFeedbackRequest = z.infer<typeof SubmitFeedbackRequestSchema>;

export const QueryDiagnosticsRequestSchema = z.object({
  query: z.string(),
  productId: z.string().optional(),
  timeRange: z.object({ start: z.string(), end: z.string() }).optional(),
});

export type QueryDiagnosticsRequest = z.infer<typeof QueryDiagnosticsRequestSchema>;

export const SearchErrorsRequestSchema = z.object({
  query: z.string(), // Semantic search query
  productId: z.string().optional(),
  limit: z.number().default(10),
  similarityThreshold: z.number().default(0.75),
});

export type SearchErrorsRequest = z.infer<typeof SearchErrorsRequestSchema>;

// ============================================================================
// Error Event Types (for ingestion from telemetry)
// ============================================================================

export const ErrorEventSchema = z.object({
  id: z.string(),
  productId: z.string(),
  correlationId: z.string().optional(),

  // Error details
  errorType: z.string(),
  message: z.string(),
  stackTrace: z.string().optional(),

  // Context
  platform: z.string().optional(), // ios, android, web, desktop
  osVersion: z.string().optional(),
  appVersion: z.string().optional(),
  deviceModel: z.string().optional(),
  screen: z.string().optional(),
  userId: z.string().optional(),

  // Telemetry linking
  precedingEvents: z.array(z.record(z.unknown())).optional(),

  // Timestamp
  timestamp: z.string(),
});

export type ErrorEvent = z.infer<typeof ErrorEventSchema>;

// ============================================================================
// Proactive Alert Types
// ============================================================================

export const AlertTypeSchema = z.enum([
  'new_cluster',
  'cluster_spike',
  'new_error_type',
  'regression_detected',
  'anomaly_detected',
]);
export type AlertType = z.infer<typeof AlertTypeSchema>;

export const ProactiveAlertSchema = z.object({
  id: z.string(), // pa_<uuid>
  productId: z.string(),
  alertType: AlertTypeSchema,

  // Target
  clusterId: z.string().optional(),
  errorType: z.string().optional(),

  // Alert details
  severity: z.enum(['critical', 'high', 'medium', 'low']),
  title: z.string(),
  description: z.string(),

  // Metrics
  baselineCount: z.number().optional(),
  currentCount: z.number(),
  spikeRatio: z.number().optional(),

  // AI analysis
  aiSummary: z.string().optional(),
  suggestedAction: z.string().optional(),

  // Status
  acknowledgedAt: z.string().optional(),
  acknowledgedBy: z.string().optional(),
  resolvedAt: z.string().optional(),

  createdAt: z.string(),
  ttl: z.number().default(30 * 86400),
});

export type ProactiveAlert = z.infer<typeof ProactiveAlertSchema>;
