import { createHash } from 'crypto';

export type AuditClassificationType = 'sms' | 'call';

export interface AuditClassificationEntry {
  id: string;
  timestamp: string;
  type: AuditClassificationType;
  phoneNumberHash: string;
  decision: 'spam' | 'ham' | 'block' | 'flag' | 'allow';
  confidence: number;
  reasons: string[];
  featureFlags: Record<string, boolean>;
  metadata?: Record<string, unknown>;
}

const MAX_AUDIT_LOG_SIZE = 10_000;

class AuditLogger {
  private entries: AuditClassificationEntry[] = [];

  logClassification(entry: Omit<AuditClassificationEntry, 'id' | 'timestamp'>): AuditClassificationEntry {
    const record: AuditClassificationEntry = {
      id: `audit-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,
      timestamp: new Date().toISOString(),
      ...entry,
    };

    this.entries.push(record);

    if (this.entries.length > MAX_AUDIT_LOG_SIZE) {
      this.entries.shift();
    }

    console.log(
      `[SpamShield:Audit] type=${record.type} decision=${record.decision} ` +
      `confidence=${record.confidence.toFixed(3)} reasons=${record.reasons.join(',') || 'none'} ` +
      `phoneHash=${record.phoneNumberHash}`
    );

    return record;
  }

  getEntries(
    filters?: {
      type?: AuditClassificationType;
      decision?: string;
      startDate?: Date;
      endDate?: Date;
      limit?: number;
    }
  ): AuditClassificationEntry[] {
    let results = this.entries;

    if (filters?.type) {
      results = results.filter(e => e.type === filters.type);
    }

    if (filters?.decision) {
      results = results.filter(e => e.decision === filters.decision);
    }

    if (filters?.startDate) {
      results = results.filter(e => new Date(e.timestamp) >= filters.startDate!);
    }

    if (filters?.endDate) {
      results = results.filter(e => new Date(e.timestamp) <= filters.endDate!);
    }

    if (filters?.limit) {
      results = results.slice(-filters.limit);
    }

    return results;
  }

  getSummary(): {
    totalEntries: number;
    spamCount: number;
    hamCount: number;
    blockCount: number;
    flagCount: number;
    allowCount: number;
    avgConfidence: number;
  } {
    const spamCount = this.entries.filter(e => e.decision === 'spam' || e.decision === 'block').length;
    const hamCount = this.entries.filter(e => e.decision === 'ham' || e.decision === 'allow').length;
    const blockCount = this.entries.filter(e => e.decision === 'block').length;
    const flagCount = this.entries.filter(e => e.decision === 'flag').length;
    const allowCount = this.entries.filter(e => e.decision === 'allow').length;
    const avgConfidence =
      this.entries.length > 0
        ? this.entries.reduce((s, e) => s + e.confidence, 0) / this.entries.length
        : 0;

    return {
      totalEntries: this.entries.length,
      spamCount,
      hamCount,
      blockCount,
      flagCount,
      allowCount,
      avgConfidence: Math.round(avgConfidence * 1000) / 1000,
    };
  }

  clear(): void {
    this.entries = [];
  }
}

export const spamAuditLogger = new AuditLogger();

export function hashPhoneNumber(phoneNumber: string): string {
  const hash = createHash('sha256').update(phoneNumber.trim()).digest('hex');
  return `sha256_${hash}`;
}
