import { formatAgorotShekels } from '@/lib/money.js';
import { getNegativeAffiliateWallets } from '@/server/admin/resources/affiliates/negative-wallets.js';
import { redactError } from '../redact.js';
import type { CheckAdapter, CheckContext, CheckResult } from '../types.js';
import type { AlertSeverity } from '@/server/cron/settlement-monitor.js';

export interface NegativeWalletAlertConfig {
  countThreshold: number;
  debtThresholdAgorot: number;
}

export function evaluateNegativeWallets(
  wallets: Awaited<ReturnType<typeof getNegativeAffiliateWallets>>,
  config: NegativeWalletAlertConfig,
): { severity: AlertSeverity; detail: string; metrics: Record<string, number> } {
  const totalDebtAgorot = wallets.reduce((sum, wallet) => sum + wallet.debtAgorot, 0);
  const oldestDebtAgeDays = wallets.reduce(
    (oldest, wallet) => Math.max(oldest, wallet.debtAgeDays ?? 0),
    0,
  );
  const thresholdMet =
    wallets.length >= config.countThreshold ||
    (config.debtThresholdAgorot > 0 && totalDebtAgorot >= config.debtThresholdAgorot);

  return {
    severity: thresholdMet ? 'page' : 'info',
    detail: thresholdMet
      ? `negative affiliate wallets=${wallets.length}, total debt ${formatAgorotShekels(totalDebtAgorot)}, oldest debt ${oldestDebtAgeDays}d`
      : `negative affiliate wallets=${wallets.length}, total debt ${formatAgorotShekels(totalDebtAgorot)}`,
    metrics: {
      negativeWalletCount: wallets.length,
      totalDebtAgorot,
      oldestDebtAgeDays,
    },
  };
}

export const affiliateNegativeWallets: CheckAdapter = {
  key: 'affiliate_negative_wallets',
  title: 'Negative affiliate wallets',
  defaultConfig: { countThreshold: 1, debtThresholdAgorot: 0 },
  defaultIntervalHours: 6,
  async run(ctx: CheckContext): Promise<CheckResult> {
    try {
      const countThreshold = Number.isFinite(Number(ctx.config.countThreshold))
        ? Math.max(1, Math.floor(Number(ctx.config.countThreshold)))
        : 1;
      const debtThresholdAgorot = Number.isFinite(Number(ctx.config.debtThresholdAgorot))
        ? Math.max(0, Math.floor(Number(ctx.config.debtThresholdAgorot)))
        : 0;
      const wallets = await getNegativeAffiliateWallets(ctx.db, ctx.now);
      const evaluated = evaluateNegativeWallets(wallets, {
        countThreshold,
        debtThresholdAgorot,
      });

      return {
        key: this.key,
        title: this.title,
        ...evaluated,
      };
    } catch (err) {
      return {
        key: this.key,
        severity: 'warn',
        degraded: true,
        title: this.title,
        detail: redactError(err, 'check threw'),
      };
    }
  },
};
