import {
  AlertSource,
  AlertCategory,
  Severity,
  EntityType,
  NormalizedAlertInput,
  CorrelationGroupOutput,
  CorrelatedAlertOutput,
  CorrelationQuery,
} from "@shieldai/types";
import { alertNormalizer, AlertNormalizer } from "./normalizer";
import { correlationEngine, CorrelationEngine } from "./engine";

export class CorrelationService {
  private normalizer: AlertNormalizer;
  private engine: CorrelationEngine;

  constructor(
    normalizer: AlertNormalizer = alertNormalizer,
    engine: CorrelationEngine = correlationEngine
  ) {
    this.normalizer = normalizer;
    this.engine = engine;
  }

  public async ingestDarkWatchAlert(
    userId: string,
    sourceAlertId: string,
    payload: {
      exposureId: string;
      breachName: string;
      severity: string;
      channel: string;
      dataType?: string[];
      dataSource?: string;
    },
    timestamp?: Date
  ): Promise<CorrelatedAlertOutput> {
    const normalized = this.normalizer.normalizeDarkWatchAlert(
      userId,
      sourceAlertId,
      payload,
      timestamp
    );
    return this.engine.ingestAlert(normalized);
  }

  public async ingestSpamShieldAlert(
    userId: string,
    sourceAlertId: string,
    payload: {
      phoneNumber: string;
      decision: string;
      confidence: number;
      reasons?: string[];
      channel?: "call" | "sms";
      hiyaReputationScore?: number;
      truecallerSpamScore?: number;
    },
    timestamp?: Date
  ): Promise<CorrelatedAlertOutput> {
    const normalized = this.normalizer.normalizeSpamShieldAlert(
      userId,
      sourceAlertId,
      payload,
      timestamp
    );
    return this.engine.ingestAlert(normalized);
  }

  public async ingestVoicePrintAlert(
    userId: string,
    sourceAlertId: string,
    payload: {
      jobId: string;
      verdict: string;
      syntheticScore: number;
      confidence: number;
      matchedEnrollmentId?: string;
      matchedSimilarity?: number;
      analysisType?: string;
    },
    timestamp?: Date
  ): Promise<CorrelatedAlertOutput> {
    const normalized = this.normalizer.normalizeVoicePrintAlert(
      userId,
      sourceAlertId,
      payload,
      timestamp
    );
    return this.engine.ingestAlert(normalized);
  }

  public async ingestCallAnalysisAlert(
    userId: string,
    sourceAlertId: string,
    payload: {
      callId: string;
      eventType?: string;
      mosScore?: number;
      anomaly?: string;
      sentiment?: { label: string; score: number };
    },
    timestamp?: Date
  ): Promise<CorrelatedAlertOutput> {
    const normalized = this.normalizer.normalizeCallAnalysisAlert(
      userId,
      sourceAlertId,
      payload,
      timestamp
    );
    return this.engine.ingestAlert(normalized);
  }

  public async ingestGenericAlert(
    input: NormalizedAlertInput
  ): Promise<CorrelatedAlertOutput> {
    return this.engine.ingestAlert(input);
  }

  public getCorrelatedAlerts(query: CorrelationQuery) {
    return this.engine.getCorrelatedAlerts(query);
  }

  public getCorrelationGroups(query: CorrelationQuery) {
    return this.engine.getCorrelationGroups(query);
  }

  public getGroupById(groupId: string, userId: string) {
    return this.engine.getGroupById(groupId, userId);
  }

  public resolveGroup(groupId: string, userId: string, status?: string) {
    return this.engine.resolveGroup(groupId, userId, status as any);
  }

  public getDashboardData(userId: string, timeWindowMinutes?: number) {
    return this.engine.getDashboardData(userId, timeWindowMinutes);
  }
}

export const correlationService = new CorrelationService();
export { alertNormalizer, correlationEngine };
