/**
 * Report Customization System
 * Allow admins to customize report parameters, filters, and recipients
 */

export interface ReportCustomization {
  id: string;
  reportId: string;
  name: string;
  type: 'payment' | 'reconciliation' | 'fraud' | 'withdrawal' | 'analytics';
  
  // Date Range
  dateRange: {
    type: 'predefined' | 'custom';
    predefined?: '7d' | '30d' | '90d' | 'ytd' | 'all';
    customStart?: Date;
    customEnd?: Date;
  };
  
  // Metrics Selection
  metrics: {
    payment?: string[];
    reconciliation?: string[];
    fraud?: string[];
    withdrawal?: string[];
    analytics?: string[];
  };
  
  // Filters
  filters: {
    paymentMethods?: string[];
    providers?: string[];
    status?: string[];
    riskLevel?: string[];
    userSegment?: string[];
  };
  
  // Grouping
  grouping: {
    byDate?: boolean;
    byProvider?: boolean;
    byPaymentMethod?: boolean;
    byStatus?: boolean;
  };
  
  // Recipients
  recipients: {
    emails: string[];
    roles?: string[];
    includeOwner?: boolean;
  };
  
  // Delivery
  delivery: {
    frequency: 'once' | 'daily' | 'weekly' | 'monthly';
    time?: string;
    timezone?: string;
    format: 'html' | 'pdf' | 'csv' | 'json';
    includeAttachment?: boolean;
  };
  
  // Notifications
  notifications: {
    onSuccess?: boolean;
    onFailure?: boolean;
    onDelay?: boolean;
  };
  
  createdAt: Date;
  updatedAt: Date;
  enabled: boolean;
}

/**
 * Available metrics by report type
 */
export const availableMetrics = {
  payment: [
    'totalRevenue',
    'totalTransactions',
    'averageTransaction',
    'successRate',
    'failureRate',
    'fraudRate',
    'retrySuccessRate',
  ],
  reconciliation: [
    'totalRecords',
    'totalMatched',
    'matchRate',
    'totalDiscrepancies',
    'discrepanciesByType',
    'providerComparison',
  ],
  fraud: [
    'totalAnalyzed',
    'criticalCount',
    'highCount',
    'mediumCount',
    'lowCount',
    'blockRate',
    'topIndicators',
    'riskDistribution',
  ],
  withdrawal: [
    'totalWithdrawals',
    'totalAmount',
    'approvedCount',
    'pendingCount',
    'rejectedCount',
    'averageAmount',
    'processingTime',
  ],
  analytics: [
    'totalRevenue',
    'totalTransactions',
    'successRate',
    'fraudRate',
    'retrySuccessRate',
    'paymentMethodBreakdown',
    'dailyTrends',
  ],
};

/**
 * Available filters by report type
 */
export const availableFilters = {
  paymentMethods: ['Square', 'PayPal', 'Google Pay', 'Chime', 'Cash App', 'Bank Transfer', 'Check', 'Money Order'],
  providers: ['Square', 'PayPal', 'Chime', 'Google'],
  status: ['completed', 'pending', 'failed', 'cancelled', 'refunded'],
  riskLevel: ['critical', 'high', 'medium', 'low'],
  userSegment: ['new_users', 'active_users', 'high_value', 'at_risk', 'vip'],
};

/**
 * Create custom report configuration
 */
export function createReportCustomization(
  reportId: string,
  name: string,
  type: ReportCustomization['type']
): ReportCustomization {
  return {
    id: `CUSTOM-${Date.now()}`,
    reportId,
    name,
    type,
    dateRange: {
      type: 'predefined',
      predefined: '7d',
    },
    metrics: {
      [type]: availableMetrics[type as keyof typeof availableMetrics],
    },
    filters: {},
    grouping: {
      byDate: true,
    },
    recipients: {
      emails: [],
      includeOwner: true,
    },
    delivery: {
      frequency: 'daily',
      time: '09:00',
      timezone: 'UTC',
      format: 'html',
      includeAttachment: false,
    },
    notifications: {
      onSuccess: true,
      onFailure: true,
      onDelay: false,
    },
    createdAt: new Date(),
    updatedAt: new Date(),
    enabled: true,
  };
}

/**
 * Update report customization
 */
export function updateReportCustomization(
  customization: ReportCustomization,
  updates: Partial<ReportCustomization>
): ReportCustomization {
  return {
    ...customization,
    ...updates,
    updatedAt: new Date(),
  };
}

/**
 * Add recipient to customization
 */
export function addRecipient(
  customization: ReportCustomization,
  email: string
): ReportCustomization {
  return {
    ...customization,
    recipients: {
      ...customization.recipients,
      emails: [...new Set([...customization.recipients.emails, email])],
    },
    updatedAt: new Date(),
  };
}

/**
 * Remove recipient from customization
 */
export function removeRecipient(
  customization: ReportCustomization,
  email: string
): ReportCustomization {
  return {
    ...customization,
    recipients: {
      ...customization.recipients,
      emails: customization.recipients.emails.filter(e => e !== email),
    },
    updatedAt: new Date(),
  };
}

/**
 * Add metric to customization
 */
export function addMetric(
  customization: ReportCustomization,
  metric: string
): ReportCustomization {
  const metricsKey = customization.type as keyof typeof customization.metrics;
  const currentMetrics = customization.metrics[metricsKey] || [];

  return {
    ...customization,
    metrics: {
      ...customization.metrics,
      [metricsKey]: [...new Set([...currentMetrics, metric])],
    },
    updatedAt: new Date(),
  };
}

/**
 * Remove metric from customization
 */
export function removeMetric(
  customization: ReportCustomization,
  metric: string
): ReportCustomization {
  const metricsKey = customization.type as keyof typeof customization.metrics;
  const currentMetrics = customization.metrics[metricsKey] || [];

  return {
    ...customization,
    metrics: {
      ...customization.metrics,
      [metricsKey]: currentMetrics.filter(m => m !== metric),
    },
    updatedAt: new Date(),
  };
}

/**
 * Add filter to customization
 */
export function addFilter(
  customization: ReportCustomization,
  filterType: string,
  value: string
): ReportCustomization {
  const currentFilters = (customization.filters as any)[filterType] || [];

  return {
    ...customization,
    filters: {
      ...customization.filters,
      [filterType]: [...new Set([...currentFilters, value])],
    },
    updatedAt: new Date(),
  };
}

/**
 * Remove filter from customization
 */
export function removeFilter(
  customization: ReportCustomization,
  filterType: string,
  value: string
): ReportCustomization {
  const currentFilters = (customization.filters as any)[filterType] || [];

  return {
    ...customization,
    filters: {
      ...customization.filters,
      [filterType]: currentFilters.filter((f: string) => f !== value),
    },
    updatedAt: new Date(),
  };
}

/**
 * Set date range for customization
 */
export function setDateRange(
  customization: ReportCustomization,
  type: 'predefined' | 'custom',
  predefined?: '7d' | '30d' | '90d' | 'ytd' | 'all',
  customStart?: Date,
  customEnd?: Date
): ReportCustomization {
  return {
    ...customization,
    dateRange: {
      type,
      predefined,
      customStart,
      customEnd,
    },
    updatedAt: new Date(),
  };
}

/**
 * Validate customization
 */
export function validateCustomization(customization: ReportCustomization): {
  valid: boolean;
  errors: string[];
} {
  const errors: string[] = [];

  if (!customization.name || customization.name.trim() === '') {
    errors.push('Report name is required');
  }

  if (customization.recipients.emails.length === 0 && !customization.recipients.includeOwner) {
    errors.push('At least one recipient is required');
  }

  const metricsKey = customization.type as keyof typeof customization.metrics;
  const metrics = customization.metrics[metricsKey] || [];
  if (metrics.length === 0) {
    errors.push('At least one metric must be selected');
  }

  if (customization.dateRange.type === 'custom') {
    if (!customization.dateRange.customStart || !customization.dateRange.customEnd) {
      errors.push('Custom date range requires both start and end dates');
    }
    if (customization.dateRange.customStart && customization.dateRange.customEnd) {
      if (customization.dateRange.customStart >= customization.dateRange.customEnd) {
        errors.push('Start date must be before end date');
      }
    }
  }

  if (customization.delivery.frequency !== 'once' && !customization.delivery.time) {
    errors.push('Delivery time is required for recurring reports');
  }

  return {
    valid: errors.length === 0,
    errors,
  };
}

/**
 * Get customization summary
 */
export function getCustomizationSummary(customization: ReportCustomization): string {
  const metricsKey = customization.type as keyof typeof customization.metrics;
  const metrics = customization.metrics[metricsKey] || [];
  const recipients = customization.recipients.emails.length;

  let dateRangeText = customization.dateRange.predefined || 'custom';
  if (customization.dateRange.type === 'custom') {
    dateRangeText = `${customization.dateRange.customStart?.toLocaleDateString()} to ${customization.dateRange.customEnd?.toLocaleDateString()}`;
  }

  return `
Report: ${customization.name}
Type: ${customization.type}
Date Range: ${dateRangeText}
Metrics: ${metrics.length}
Recipients: ${recipients}
Frequency: ${customization.delivery.frequency}
Format: ${customization.delivery.format}
Status: ${customization.enabled ? 'Enabled' : 'Disabled'}
  `.trim();
}

/**
 * Clone customization
 */
export function cloneCustomization(
  customization: ReportCustomization,
  newName: string
): ReportCustomization {
  return {
    ...customization,
    id: `CUSTOM-${Date.now()}`,
    name: newName,
    createdAt: new Date(),
    updatedAt: new Date(),
  };
}

/**
 * Get customization templates
 */
export const customizationTemplates = {
  paymentDaily: {
    name: 'Daily Payment Summary',
    type: 'payment' as const,
    dateRange: { type: 'predefined' as const, predefined: '1d' as const },
    delivery: { frequency: 'daily' as const, time: '09:00', format: 'html' as const },
  },
  reconciliationWeekly: {
    name: 'Weekly Reconciliation Report',
    type: 'reconciliation' as const,
    dateRange: { type: 'predefined' as const, predefined: '7d' as const },
    delivery: { frequency: 'weekly' as const, time: '09:00', format: 'pdf' as const },
  },
  fraudMonthly: {
    name: 'Monthly Fraud Analysis',
    type: 'fraud' as const,
    dateRange: { type: 'predefined' as const, predefined: '30d' as const },
    delivery: { frequency: 'monthly' as const, time: '09:00', format: 'pdf' as const },
  },
  withdrawalWeekly: {
    name: 'Weekly Withdrawal Summary',
    type: 'withdrawal' as const,
    dateRange: { type: 'predefined' as const, predefined: '7d' as const },
    delivery: { frequency: 'weekly' as const, time: '09:00', format: 'html' as const },
  },
};

/**
 * Create customization from template
 */
export function createFromTemplate(
  templateKey: keyof typeof customizationTemplates,
  reportId: string
): ReportCustomization {
  const template = customizationTemplates[templateKey];
  const customization = createReportCustomization(reportId, template.name, template.type);

  return {
    ...customization,
    dateRange: template.dateRange,
    delivery: {
      ...customization.delivery,
      ...template.delivery,
    },
  };
}

/**
 * Get customization statistics
 */
export interface CustomizationStats {
  totalCustomizations: number;
  enabledCount: number;
  disabledCount: number;
  byType: Record<string, number>;
  byFrequency: Record<string, number>;
  averageMetricsPerReport: number;
  averageRecipientsPerReport: number;
}

export function getCustomizationStats(customizations: ReportCustomization[]): CustomizationStats {
  const byType: Record<string, number> = {};
  const byFrequency: Record<string, number> = {};
  let totalMetrics = 0;
  let totalRecipients = 0;

  customizations.forEach(c => {
    byType[c.type] = (byType[c.type] || 0) + 1;
    byFrequency[c.delivery.frequency] = (byFrequency[c.delivery.frequency] || 0) + 1;

    const metricsKey = c.type as keyof typeof c.metrics;
    totalMetrics += (c.metrics[metricsKey] || []).length;
    totalRecipients += c.recipients.emails.length;
  });

  return {
    totalCustomizations: customizations.length,
    enabledCount: customizations.filter(c => c.enabled).length,
    disabledCount: customizations.filter(c => !c.enabled).length,
    byType,
    byFrequency,
    averageMetricsPerReport: customizations.length > 0 ? totalMetrics / customizations.length : 0,
    averageRecipientsPerReport: customizations.length > 0 ? totalRecipients / customizations.length : 0,
  };
}
