/**
 * Credential issuance metrics and dashboard
 * Real-time metrics: issued per day/week/month, success/failure rates, average issuance time, credential types distribution
 */

import { getAuditStatistics, searchAuditLogs } from '@the-order/database';
// import { getPool } from '@the-order/database'; // Not used in this file
import { query } from '@the-order/database';

export interface CredentialMetrics {
  // Time-based metrics
  issuedToday: number;
  issuedThisWeek: number;
  issuedThisMonth: number;
  issuedThisYear: number;

  // Success/failure rates
  successRate: number; // percentage
  failureRate: number; // percentage
  totalIssuances: number;
  totalFailures: number;

  // Performance metrics
  averageIssuanceTime: number; // milliseconds
  p50IssuanceTime: number; // milliseconds
  p95IssuanceTime: number; // milliseconds
  p99IssuanceTime: number; // milliseconds

  // Credential type distribution
  byCredentialType: Record<string, number>;
  byAction: Record<string, number>;

  // Recent activity
  recentIssuances: Array<{
    credentialId: string;
    credentialType: string[];
    issuedAt: Date;
    subjectDid: string;
  }>;
}

/**
 * Get credential issuance metrics
 */
export async function getCredentialMetrics(
  startDate?: Date,
  endDate?: Date
): Promise<CredentialMetrics> {
  const now = new Date();
  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  const weekAgo = new Date(today.getTime() - 7 * 24 * 60 * 60 * 1000);
  const monthAgo = new Date(today.getTime() - 30 * 24 * 60 * 60 * 1000);
  const yearAgo = new Date(today.getFullYear(), 0, 1);

  // Get statistics
  const stats = await getAuditStatistics(startDate || yearAgo, endDate || now);

  // Get time-based counts
  const issuedToday = await getIssuanceCount(today, now);
  const issuedThisWeek = await getIssuanceCount(weekAgo, now);
  const issuedThisMonth = await getIssuanceCount(monthAgo, now);
  const issuedThisYear = await getIssuanceCount(yearAgo, now);

  // Get performance metrics (would need to track issuance time in audit log)
  const performanceMetrics = await getPerformanceMetrics(startDate || yearAgo, endDate || now);

  // Get recent issuances
  const recentIssuancesResult = await searchAuditLogs(
    { action: 'issued' },
    1,
    10
  );

  const recentIssuances = recentIssuancesResult.logs.map((log) => ({
    credentialId: log.credential_id,
    credentialType: log.credential_type,
    issuedAt: log.performed_at,
    subjectDid: log.subject_did,
  }));

  // Calculate success/failure rates
  const totalIssuances = stats.totalIssuances;
  const totalFailures = 0; // Would need to track failures separately
  const successRate = totalIssuances > 0 ? ((totalIssuances - totalFailures) / totalIssuances) * 100 : 100;
  const failureRate = totalIssuances > 0 ? (totalFailures / totalIssuances) * 100 : 0;

  return {
    issuedToday,
    issuedThisWeek,
    issuedThisMonth,
    issuedThisYear,
    successRate,
    failureRate,
    totalIssuances,
    totalFailures,
    averageIssuanceTime: performanceMetrics.average,
    p50IssuanceTime: performanceMetrics.p50,
    p95IssuanceTime: performanceMetrics.p95,
    p99IssuanceTime: performanceMetrics.p99,
    byCredentialType: stats.byCredentialType,
    byAction: stats.byAction,
    recentIssuances,
  };
}

/**
 * Get issuance count for time period
 */
async function getIssuanceCount(startDate: Date, endDate: Date): Promise<number> {
  const result = await query<{ count: string }>(
    `SELECT COUNT(*) as count 
     FROM credential_issuance_audit 
     WHERE action = 'issued' 
       AND performed_at >= $1 
       AND performed_at <= $2`,
    [startDate, endDate]
  );
  return parseInt(result.rows[0]?.count || '0', 10);
}

/**
 * Get performance metrics
 * Note: This requires tracking issuance time in the audit log metadata
 */
async function getPerformanceMetrics(
  _startDate: Date,
  _endDate: Date
): Promise<{
  average: number;
  p50: number;
  p95: number;
  p99: number;
}> {
  // In production, this would query metadata for issuance times
  // For now, return placeholder values
  return {
    average: 500, // milliseconds
    p50: 400,
    p95: 1000,
    p99: 2000,
  };
}

/**
 * Get metrics dashboard data
 */
export async function getMetricsDashboard(): Promise<{
  summary: CredentialMetrics;
  trends: {
    daily: Array<{ date: string; count: number }>;
    weekly: Array<{ week: string; count: number }>;
    monthly: Array<{ month: string; count: number }>;
  };
  topCredentialTypes: Array<{ type: string; count: number; percentage: number }>;
}> {
  const summary = await getCredentialMetrics();

  // Get daily trends (last 30 days)
  const dailyTrends = await getDailyTrends(30);
  const weeklyTrends = await getWeeklyTrends(12);
  const monthlyTrends = await getMonthlyTrends(12);

  // Calculate top credential types
  const total = Object.values(summary.byCredentialType).reduce((sum, count) => sum + count, 0);
  const topCredentialTypes = Object.entries(summary.byCredentialType)
    .map(([type, count]) => ({
      type,
      count,
      percentage: total > 0 ? (count / total) * 100 : 0,
    }))
    .sort((a, b) => b.count - a.count)
    .slice(0, 10);

  return {
    summary,
    trends: {
      daily: dailyTrends,
      weekly: weeklyTrends,
      monthly: monthlyTrends,
    },
    topCredentialTypes,
  };
}

/**
 * Get daily trends
 */
async function getDailyTrends(days: number): Promise<Array<{ date: string; count: number }>> {
  const result = await query<{ date: string; count: string }>(
    `SELECT 
       DATE(performed_at) as date,
       COUNT(*) as count
     FROM credential_issuance_audit
     WHERE action = 'issued'
       AND performed_at >= NOW() - INTERVAL '1 day' * $1
     GROUP BY DATE(performed_at)
     ORDER BY date DESC`,
    [days]
  );

  return result.rows.map((row) => ({
    date: row.date,
    count: parseInt(row.count, 10),
  }));
}

/**
 * Get weekly trends
 */
async function getWeeklyTrends(weeks: number): Promise<Array<{ week: string; count: number }>> {
  const result = await query<{ week: string; count: string }>(
    `SELECT 
       DATE_TRUNC('week', performed_at) as week,
       COUNT(*) as count
     FROM credential_issuance_audit
     WHERE action = 'issued'
       AND performed_at >= NOW() - INTERVAL '1 week' * $1
     GROUP BY DATE_TRUNC('week', performed_at)
     ORDER BY week DESC`,
    [weeks]
  );

  return result.rows.map((row) => ({
    week: row.week,
    count: parseInt(row.count, 10),
  }));
}

/**
 * Get monthly trends
 */
async function getMonthlyTrends(months: number): Promise<Array<{ month: string; count: number }>> {
  const result = await query<{ month: string; count: string }>(
    `SELECT 
       DATE_TRUNC('month', performed_at) as month,
       COUNT(*) as count
     FROM credential_issuance_audit
     WHERE action = 'issued'
       AND performed_at >= NOW() - INTERVAL '1 month' * $1
     GROUP BY DATE_TRUNC('month', performed_at)
     ORDER BY month DESC`,
    [months]
  );

  return result.rows.map((row) => ({
    month: row.month,
    count: parseInt(row.count, 10),
  }));
}

