import { prisma } from '@shieldai/db';
import {
  ReportExposureSummary,
  ReportSpamStats,
  ReportVoiceStats,
  ReportHomeTitleStats,
  ReportRecommendation,
  ReportDataPayload,
} from '@shieldai/types';

export async function collectExposureSummary(
  subscriptionId: string,
  periodStart: Date,
  periodEnd: Date
): Promise<ReportExposureSummary> {
  const exposures = await prisma.exposure.findMany({
    where: {
      subscriptionId,
      detectedAt: {
        gte: periodStart,
        lte: periodEnd,
      },
    },
    select: {
      severity: true,
      source: true,
      isFirstTime: true,
    },
  });

  const totalExposures = exposures.length;
  const newExposures = exposures.filter((e) => e.isFirstTime).length;
  const criticalExposures = exposures.filter((e) => e.severity === 'critical').length;
  const warningExposures = exposures.filter((e) => e.severity === 'warning').length;
  const infoExposures = exposures.filter((e) => e.severity === 'info').length;

  const exposuresBySource: Record<string, number> = {};
  for (const exp of exposures) {
    exposuresBySource[exp.source] = (exposuresBySource[exp.source] || 0) + 1;
  }

  const resolvedExposures = await prisma.alert.count({
    where: {
      subscriptionId,
      type: 'exposure_resolved',
      createdAt: {
        gte: periodStart,
        lte: periodEnd,
      },
    },
  });

  return {
    totalExposures,
    newExposures,
    resolvedExposures,
    criticalExposures,
    warningExposures,
    infoExposures,
    exposuresBySource,
  };
}

export async function collectSpamStats(
  userId: string,
  periodStart: Date,
  periodEnd: Date
): Promise<ReportSpamStats> {
  const feedbacks = await prisma.spamFeedback.findMany({
    where: {
      userId,
      createdAt: {
        gte: periodStart,
        lte: periodEnd,
      },
    },
    select: {
      isSpam: true,
      feedbackType: true,
      metadata: true,
    },
  });

  const spamEvents = feedbacks.filter((f) => f.isSpam);
  const falsePositives = feedbacks.filter((f) => f.feedbackType === 'user_rejection').length;

  const callsBlocked = spamEvents.filter((f) => {
    const meta = f.metadata as Record<string, unknown> | null;
    return meta?.channel === 'call';
  }).length;

  const textsBlocked = spamEvents.filter((f) => {
    const meta = f.metadata as Record<string, unknown> | null;
    return meta?.channel === 'sms';
  }).length;

  const flagged = feedbacks.filter(
    (f) => f.feedbackType === 'initial_detection' && f.isSpam
  ).length;

  return {
    callsBlocked,
    textsBlocked,
    callsFlagged: Math.round(flagged / 2),
    textsFlagged: Math.round(flagged / 2),
    falsePositives,
    totalSpamEvents: spamEvents.length,
  };
}

export async function collectVoiceStats(
  userId: string,
  periodStart: Date,
  periodEnd: Date
): Promise<ReportVoiceStats> {
  const analyses = await prisma.voiceAnalysis.findMany({
    where: {
      userId,
      createdAt: {
        gte: periodStart,
        lte: periodEnd,
      },
    },
    select: {
      isSynthetic: true,
      confidence: true,
      enrollmentId: true,
    },
  });

  const syntheticDetections = analyses.filter((a) => a.isSynthetic).length;

  const enrollments = await prisma.voiceEnrollment.count({
    where: {
      userId,
      isActive: true,
    },
  });

  const threatsDetected = analyses.filter(
    (a) => a.isSynthetic && a.confidence > 0.7
  ).length;

  return {
    analysesRun: analyses.length,
    threatsDetected,
    enrollmentsActive: enrollments,
    syntheticDetections,
    voiceMismatchEvents: threatsDetected,
  };
}

export async function collectHomeTitleStats(
  subscriptionId: string,
  periodStart: Date,
  periodEnd: Date
): Promise<ReportHomeTitleStats> {
  const addressWatchlistItems = await prisma.watchlistItem.findMany({
    where: {
      subscriptionId,
      type: 'address',
      isActive: true,
    },
  });

  const propertyAlerts = await prisma.alert.count({
    where: {
      subscriptionId,
      createdAt: {
        gte: periodStart,
        lte: periodEnd,
      },
    },
  });

  return {
    propertiesMonitored: addressWatchlistItems.length,
    changesDetected: Math.round(propertyAlerts * 0.3),
    alertsTriggered: propertyAlerts,
  };
}

export function generateRecommendations(
  exposureSummary: ReportExposureSummary,
  spamStats: ReportSpamStats,
  voiceStats: ReportVoiceStats,
  protectionScore: number
): ReportRecommendation[] {
  const recommendations: ReportRecommendation[] = [];

  if (exposureSummary.criticalExposures > 0) {
    recommendations.push({
      category: 'dark_web',
      priority: 'high',
      title: 'Address Critical Exposures',
      description: `${exposureSummary.criticalExposures} critical exposure(s) detected. Consider updating passwords and enabling 2FA on affected accounts.`,
    });
  }

  if (exposureSummary.newExposures > 5) {
    recommendations.push({
      category: 'dark_web',
      priority: 'medium',
      title: 'Review New Exposures',
      description: `${exposureSummary.newExposures} new exposures found this period. Review details in your dashboard and take action on high-severity items.`,
    });
  }

  if (spamStats.totalSpamEvents > 20) {
    recommendations.push({
      category: 'spam',
      priority: 'medium',
      title: 'High Spam Activity Detected',
      description: `${spamStats.totalSpamEvents} spam events blocked. Consider adding custom blocking rules for frequently seen numbers.`,
    });
  }

  if (voiceStats.syntheticDetections > 0) {
    recommendations.push({
      category: 'voice',
      priority: 'high',
      title: 'Voice Cloning Threat Detected',
      description: `${voiceStats.syntheticDetections} synthetic voice detection(s). Verify voice calls from family members using a personal passphrase.`,
    });
  }

  if (voiceStats.enrollmentsActive === 0) {
    recommendations.push({
      category: 'voice',
      priority: 'low',
      title: 'Enroll Family Voices',
      description: 'Add voice profiles for family members to improve voice cloning detection accuracy.',
    });
  }

  if (protectionScore < 50) {
    recommendations.push({
      category: 'general',
      priority: 'high',
      title: 'Improve Protection Score',
      description: 'Your protection score is below 50. Upgrade to Premium for comprehensive identity and home title monitoring.',
    });
  }

  return recommendations;
}

export function calculateProtectionScore(
  exposureSummary: ReportExposureSummary,
  spamStats: ReportSpamStats,
  voiceStats: ReportVoiceStats
): number {
  let score = 100;

  score -= exposureSummary.criticalExposures * 10;
  score -= exposureSummary.warningExposures * 5;
  score -= exposureSummary.infoExposures * 2;
  score -= Math.min(spamStats.totalSpamEvents, 20);
  score -= voiceStats.syntheticDetections * 8;

  if (voiceStats.enrollmentsActive === 0) {
    score -= 5;
  }

  return Math.max(0, Math.min(100, score));
}

export async function collectAllReportData(
  userId: string,
  subscriptionId: string,
  reportType: string,
  periodStart: Date,
  periodEnd: Date
): Promise<ReportDataPayload> {
  const [exposureSummary, spamStats, voiceStats] = await Promise.all([
    collectExposureSummary(subscriptionId, periodStart, periodEnd),
    collectSpamStats(userId, periodStart, periodEnd),
    collectVoiceStats(userId, periodStart, periodEnd),
  ]);

  const protectionScore = calculateProtectionScore(exposureSummary, spamStats, voiceStats);
  const recommendations = generateRecommendations(
    exposureSummary,
    spamStats,
    voiceStats,
    protectionScore
  );

  const payload: ReportDataPayload = {
    exposureSummary,
    spamStats,
    voiceStats,
    recommendations,
    protectionScore,
  };

  if (reportType === 'ANNUAL_PREMIUM') {
    payload.homeTitleStats = await collectHomeTitleStats(
      subscriptionId,
      periodStart,
      periodEnd
    );
  }

  return payload;
}
