type JsonRecord = Record<string, unknown>;

export function renderProfitScenarioLines(scenario: JsonRecord): string[] {
  if (Object.keys(scenario).length === 0) return [];
  const theoretical = record(scenario.theoretical);
  const redistributed = record(scenario.redistributed);
  const costs = record(redistributed.costsCny);
  const profit = record(redistributed.profitCny);
  const daily = record(scenario.dailyAverage);
  const dailyCosts = record(daily.costsCny);
  const dailyProfit = record(daily.profitCny);
  const lines = [
    "",
    `SCENARIO status=${text(scenario.status)} method=${text(scenario.method)} sale-rate=${text(scenario.saleRateCnyPerApiUsd)}CNY/API_USD scale=${text(scenario.scale)} removed-period-cost=${cny(scenario.removedPeriodCostCny)}`,
    table(
      ["SCOPE", "REVENUE_CNY", "TRAFFIC_COST_CNY", "SELF_USE_COST_CNY", "PERIOD_COST_CNY", "THEORETICAL_CEILING_CNY", "REDISTRIBUTED_PROFIT_CNY", "DAILY_PROFIT_CNY"],
      [
        ["不扣自用", cny(redistributed.revenueCny), cny(costs.profitPool), "-", cny(costs.period), cny(theoretical.withoutSelfUseProfitCny), cny(profit.withoutSelfUse), cny(dailyProfit.withoutSelfUse)],
        ["扣除自用", cny(redistributed.revenueCny), cny(costs.profitPool), cny(costs.selfUse), cny(costs.period), cny(theoretical.withSelfUseProfitCny), cny(profit.withSelfUse), cny(dailyProfit.withSelfUse)],
      ],
    ),
    `DAILY days=${text(daily.days)} revenue=${cny(daily.revenueCny)} traffic-cost=${cny(dailyCosts.profitPool)} self-use-cost=${cny(dailyCosts.selfUse)} period-cost=${cny(dailyCosts.period)}`,
    "SCENARIO ACCOUNTS",
  ];
  const selected = records(scenario.selectedAccounts);
  if (selected.length === 0) lines.push("- none; candidate sale-rate only");
  for (const row of selected) {
    lines.push(`- account=${text(row.accountName)} id=${text(row.accountId)} classes=${arrayText(row.classes)}`);
  }
  lines.push("REDISTRIBUTION");
  for (const row of records(scenario.redistribution)) {
    lines.push(`- class=${text(row.class)} selected-share=${percent(row.selectedSharePct)} remaining-rate=${text(row.remainingWeightedCostRateCnyPerApiUsd)} replacement-cost=${cny(row.replacementCostCny)} remaining-load-increase=${percent(row.remainingLoadIncreasePct)}`);
  }
  const warnings = Array.isArray(scenario.warnings) ? scenario.warnings : [];
  for (const warning of warnings) lines.push(`WARNING ${text(warning)}`);
  return lines;
}

function record(value: unknown): JsonRecord {
  return typeof value === "object" && value !== null && !Array.isArray(value) ? value as JsonRecord : {};
}

function records(value: unknown): JsonRecord[] {
  return Array.isArray(value) ? value.filter((item): item is JsonRecord => typeof item === "object" && item !== null && !Array.isArray(item)) : [];
}

function text(value: unknown): string {
  if (value === null || value === undefined || value === "") return "-";
  return String(value).replace(/[\r\n\t]+/gu, " ");
}

function cny(value: unknown): string {
  const numeric = Number(value);
  return Number.isFinite(numeric) ? `¥${numeric.toFixed(6)}` : text(value);
}

function percent(value: unknown): string {
  const numeric = Number(value);
  return Number.isFinite(numeric) ? `${numeric.toFixed(2)}%` : text(value);
}

function arrayText(value: unknown): string {
  return Array.isArray(value) ? value.map(text).join(",") : text(value);
}

function table(headers: string[], rows: string[][]): string {
  const widths = headers.map((header, index) => Math.max(header.length, ...rows.map((row) => (row[index] ?? "").length)));
  return [headers, ...rows].map((row) => row.map((cell, index) => cell.padEnd(widths[index]!)).join("  ").trimEnd()).join("\n");
}
