/**
 * Prints concrete settlement / parlay / cashback amounts used in smoke & unit tests.
 * Run: pnpm --filter @thebet365/api audit:settlement
 */
import { Decimal } from '@prisma/client/runtime/library';
import {
  calculateParlayPayout,
  calculatePayout,
} from '../../domains/settlement/domain/settlement-calculator';
import { resolveCashbackRateForBet } from '../../domains/operations/cashback/cashback-rate.resolver';

type Row = { scenario: string; stake: number; detail: string; payout: string; netProfit: string };

function fmt(n: number | string | Decimal) {
  return new Decimal(n).toFixed(2);
}

function single(
  scenario: string,
  stake: number,
  odds: number,
  result: Parameters<typeof calculatePayout>[2],
): Row {
  const payout = calculatePayout(stake, odds, result);
  return {
    scenario,
    stake,
    detail: `odds ${odds}, ${result}`,
    payout: fmt(payout),
    netProfit: fmt(payout.sub(stake)),
  };
}

function parlay(
  scenario: string,
  stake: number,
  legs: Array<{ odds: number; result: Parameters<typeof calculatePayout>[2] }>,
): Row {
  const { betResult, payout, effectiveOdds } = calculateParlayPayout(stake, legs);
  const legDesc = legs.map((l) => `${l.odds}@${l.result}`).join(' × ');
  return {
    scenario,
    stake,
    detail: `${betResult} | ${legDesc} | effOdds ${effectiveOdds.toFixed(4)}`,
    payout: fmt(payout),
    netProfit: fmt(payout.sub(stake)),
  };
}

function cashbackExample(stake: number, rate: string, label: string): Row {
  const r = new Decimal(rate);
  const amount = new Decimal(stake).mul(r);
  return {
    scenario: label,
    stake,
    detail: `rate ${rate} → stake × rate`,
    payout: fmt(amount),
    netProfit: fmt(amount),
  };
}

const rows: Row[] = [
  single('单关 1X2 全赢 (BF001)', 100, 2.0, 'WIN'),
  single('单关 1X2 全输 (BF002)', 100, 2.0, 'LOSE'),
  single('让球 -1 全赢 (S009)', 100, 1.85, 'WIN'),
  single('让球 -1 走水 (S010)', 100, 1.85, 'PUSH'),
  single('让球 -0.25 半输 (S011)', 100, 1.85, 'HALF_LOSE'),
  single('半赢派彩 (S011B)', 100, 1.85, 'HALF_WIN'),
  single('让球 -0.5 全输 (S012)', 100, 1.85, 'LOSE'),
  single('大小 小球赢 (S015)', 100, 1.95, 'WIN'),
  parlay('串关全中 (S016)', 100, [
    { odds: 1.8, result: 'WIN' },
    { odds: 2.0, result: 'WIN' },
  ]),
  parlay('串关一关输 (S017)', 100, [
    { odds: 1.8, result: 'WIN' },
    { odds: 2.0, result: 'LOSE' },
  ]),
  parlay('串关一关走水 (S018)', 100, [
    { odds: 1.8, result: 'WIN' },
    { odds: 2.0, result: 'PUSH' },
    { odds: 1.9, result: 'WIN' },
  ]),
  parlay('串关全走水/作废 (S019)', 100, [
    { odds: 1.8, result: 'PUSH' },
    { odds: 2.0, result: 'VOID' },
  ]),
];

const cbRates = [
  {
    label: '返水 玩家专属 (CB001)',
    rate: resolveCashbackRateForBet({
      userId: BigInt(100),
      agentId: BigInt(200),
      marketTypes: ['FT_1X2'],
      agentDefaultRate: new Decimal('0.01'),
      rules: [{ targetType: 'USER', targetId: BigInt(100), rate: new Decimal('0.03'), marketType: null }],
    }).toString(),
  },
  {
    label: '返水 玩法专属 (CB002)',
    rate: resolveCashbackRateForBet({
      userId: BigInt(100),
      agentId: BigInt(200),
      marketTypes: ['FT_HANDICAP'],
      agentDefaultRate: new Decimal('0.01'),
      rules: [
        { targetType: 'GLOBAL', targetId: null, rate: new Decimal('0.005'), marketType: 'FT_HANDICAP' },
      ],
    }).toString(),
  },
  {
    label: '返水 代理默认 (CB003)',
    rate: resolveCashbackRateForBet({
      userId: BigInt(100),
      agentId: BigInt(200),
      marketTypes: ['FT_1X2'],
      agentDefaultRate: new Decimal('0.02'),
      rules: [],
    }).toString(),
  },
];

console.log('\n=== 结算派彩金额（stake=100  unless noted）===\n');
console.table(rows);

console.log('\n=== 返水比例 → 到账金额（已结算注单，公式：stake × rate）===\n');
for (const { label, rate } of cbRates) {
  console.log(`${label}: rate=${rate}`);
  console.table([
    cashbackExample(100, rate, 'stake 100'),
    cashbackExample(500, rate, 'stake 500'),
    cashbackExample(1000, rate, 'stake 1000'),
  ]);
}

console.log('\n=== 端到端钱包（BF001–BF005，smoke bet-flow）===\n');
console.table([
  { case: 'BF001', flow: '单关赢 100@2.0, 2-1', wallet: '1000 → 900 avail + 100 frozen → 1100 avail', actualReturn: '200' },
  { case: 'BF002', flow: '单关输 和局+2-1', wallet: '1000 → 900 avail', actualReturn: '0' },
  { case: 'BF003', flow: '幂等 50 注', wallet: '500 → 450 avail + 50 frozen', actualReturn: '—' },
  { case: 'BF004', flow: '余额不足', wallet: '50 不变', actualReturn: '—' },
  { case: 'BF005', flow: '代理额度 玩家输100', wallet: '玩家 900', agentUsedCredit: '1000 → 900' },
]);

console.log('\n注：dev seed 下 agent1 cashbackRate 默认为 0；需后台配置规则或代理默认比例后才会产生返水批次。\n');
