import type { TFunction } from "i18next";

import type { SettlementBillRow } from "@/api/admin-agent-settlement";

function billDisplayLabel(
  t: TFunction<["agents", "settlementCenter"]>,
  key: string,
  defaultValue: string,
  vars: Record<string, string> = {},
): string {
  const rendered = t(`settlementCenter:billDisplay.${key}`, { defaultValue, ...vars });
  if (!/\{\{\w+\}\}/.test(rendered)) {
    return rendered;
  }

  return defaultValue.replace(/\{\{(\w+)\}\}/g, (_, name: string) => vars[name] ?? "");
}

export type BillPartyRole = "owner" | "counterparty";

export type BillPaymentDirection = {
  payer: string;
  payee: string;
  ownerOwes: boolean;
  amount: number;
};

export function billLayerLabel(
  bill: SettlementBillRow,
  t: TFunction<["agents", "settlementCenter"]>,
): string {
  if (bill.bill_type === "player") {
    return t("settlementCenter:billsPanel.layer.player", {
      defaultValue: "玩家与直属代理结算",
    });
  }
  if (bill.bill_type === "agent") {
    return t("settlementCenter:billsPanel.layer.agent", {
      defaultValue: "代理与上级 / 平台结算",
    });
  }
  if (bill.bill_type === "adjustment") {
    return t("settlementCenter:billsPanel.layer.adjustment", {
      defaultValue: "结算差异调账",
    });
  }
  if (bill.bill_type === "bad_debt") {
    return t("settlementCenter:billsPanel.layer.badDebt", {
      defaultValue: "坏账核销归档",
    });
  }
  if (bill.bill_type === "reversal") {
    return t("settlementCenter:billsPanel.layer.reversal", {
      defaultValue: "历史账单冲正",
    });
  }

  return t("settlementCenter:billsPanel.layer.generic", {
    defaultValue: "结算辅助单据",
  });
}

export function billDirectionHint(
  bill: SettlementBillRow,
  t: TFunction<["agents", "settlementCenter"]>,
): string {
  if (bill.bill_type === "player") {
    return bill.net_amount > 0
      ? t("settlementCenter:billDisplay.flowHint.playerPayAgent", {
          defaultValue: "玩家应向直属代理结算",
        })
      : t("settlementCenter:billDisplay.flowHint.agentPayPlayer", {
          defaultValue: "直属代理应向玩家结算",
        });
  }

  if (bill.bill_type === "agent") {
    return bill.net_amount > 0
      ? t("settlementCenter:billDisplay.flowHint.agentPayUpstream", {
          defaultValue: "本级代理应向上级 / 平台结算",
        })
      : t("settlementCenter:billDisplay.flowHint.upstreamPayAgent", {
          defaultValue: "上级 / 平台应向本级代理结算",
        });
  }

  if (bill.bill_type === "adjustment") {
    return t("settlementCenter:billDisplay.flowHint.adjustment", {
      defaultValue: "补差单独结转，不改变原账单主体关系",
    });
  }

  if (bill.bill_type === "bad_debt") {
    return t("settlementCenter:billDisplay.flowHint.badDebt", {
      defaultValue: "核销未结金额，并生成坏账归档记录",
    });
  }

  if (bill.bill_type === "reversal") {
    return t("settlementCenter:billDisplay.flowHint.reversal", {
      defaultValue: "冲正原账单影响，按冲正规则回退",
    });
  }

  return t("settlementCenter:billDisplay.flowHint.generic", {
    defaultValue: "按账单结算关系执行收付或调账",
  });
}

export type DownlineShareItem = {
  owner_id: number;
  owner_label: string;
  share_profit: number;
};

export type DownlineShareBreakdown = {
  total: number;
  items: DownlineShareItem[];
};

export type BillBreakdownLine = {
  key: string;
  label: string;
  amount: number;
  signedAmount: number;
  kind: "add" | "subtract" | "subtotal" | "total";
  hint?: string;
  children?: BillBreakdownLine[];
};

export function parseBillMeta(metaJson: SettlementBillRow["meta_json"]): {
  share_profit?: number;
  platform_share_profit?: number;
} {
  if (metaJson == null || metaJson === "") {
    return {};
  }
  try {
    const parsed =
      typeof metaJson === "string" ? (JSON.parse(metaJson) as Record<string, unknown>) : metaJson;
    return {
      share_profit: parsed.share_profit != null ? Number(parsed.share_profit) : undefined,
      platform_share_profit:
        parsed.platform_share_profit != null ? Number(parsed.platform_share_profit) : undefined,
    };
  } catch {
    return {};
  }
}

export function resolveBillPartyName(
  bill: SettlementBillRow,
  role: BillPartyRole,
  t: TFunction<["agents", "settlementCenter"]>,
): string {
  const platformLabel = t("agents:settlementBills.platform", { defaultValue: "平台" });
  const fallbackPartyName = (type: string, id: number): string =>
    type === "platform" ? platformLabel : `${type}#${id}`;

  if (role === "owner") {
    if (bill.owner_type === "platform") {
      return platformLabel;
    }
    if (bill.bill_type === "player") {
      return bill.player_username ?? bill.owner_label ?? fallbackPartyName(bill.owner_type, bill.owner_id);
    }
    return bill.owner_party_label ?? bill.owner_label ?? fallbackPartyName(bill.owner_type, bill.owner_id);
  }

  if (
    bill.counterparty_type === "platform" ||
    bill.counterparty_label === "platform" ||
    bill.superior_agent_label === "platform"
  ) {
    return platformLabel;
  }
  if (bill.bill_type === "player") {
    return (
      bill.direct_agent_label ??
      bill.counterparty_label ??
      fallbackPartyName(bill.counterparty_type, bill.counterparty_id)
    );
  }
  return (
    bill.superior_agent_label ??
    bill.counterparty_label ??
    fallbackPartyName(bill.counterparty_type, bill.counterparty_id)
  );
}

export function describeBillPaymentDirection(
  bill: SettlementBillRow,
  t: TFunction<["agents", "settlementCenter"]>,
): BillPaymentDirection {
  const owner = resolveBillPartyName(bill, "owner", t);
  const counterparty = resolveBillPartyName(bill, "counterparty", t);
  const ownerOwes = bill.net_amount > 0;
  const amount = Math.abs(bill.net_amount);

  return {
    payer: ownerOwes ? owner : counterparty,
    payee: ownerOwes ? counterparty : owner,
    ownerOwes,
    amount,
  };
}

export function buildBillAmountBreakdown(
  bill: SettlementBillRow,
  t: TFunction<["agents", "settlementCenter"]>,
  downlineShares?: DownlineShareBreakdown | null,
): BillBreakdownLine[] {
  const meta = parseBillMeta(bill.meta_json);
  const gross = bill.gross_win_loss ?? 0;
  const rebate = bill.rebate_amount ?? 0;
  const shareProfit = meta.share_profit ?? 0;
  const rounding = bill.platform_rounding_adjustment ?? 0;
  const teamNet = gross - rebate;

  if (bill.bill_type === "player") {
    const lines: BillBreakdownLine[] = [];
    if (bill.gross_win_loss != null) {
      lines.push({
        key: "gross",
        label: t("settlementCenter:billDisplay.playerGross", { defaultValue: "游戏输赢" }),
        amount: Math.abs(gross),
        signedAmount: gross,
        kind: "add",
        hint:
          gross > 0
            ? t("settlementCenter:billDisplay.playerLostHint", { defaultValue: "玩家输了，应付代理" })
            : gross < 0
              ? t("settlementCenter:billDisplay.playerWonHint", { defaultValue: "玩家赢了，代理应付玩家" })
              : undefined,
      });
    }
    if (bill.rebate_amount != null && rebate !== 0) {
      lines.push({
        key: "rebate",
        label: t("settlementCenter:billDisplay.rebate", { defaultValue: "回水" }),
        amount: Math.abs(rebate),
        signedAmount: -Math.abs(rebate),
        kind: "subtract",
      });
    }
    if (rounding !== 0) {
      lines.push({
        key: "rounding",
        label: t("agents:settlementBills.platformRounding", { defaultValue: "平台尾差" }),
        amount: Math.abs(rounding),
        signedAmount: rounding > 0 ? -Math.abs(rounding) : Math.abs(rounding),
        kind: rounding > 0 ? "subtract" : "add",
      });
    }
    lines.push({
      key: "net",
      label:
        bill.net_amount > 0
          ? t("settlementCenter:billDisplay.playerNet", { defaultValue: "玩家应付净额" })
          : t("settlementCenter:billDisplay.playerNetReceive", { defaultValue: "代理应付玩家" }),
      amount: Math.abs(bill.net_amount),
      signedAmount: bill.net_amount,
      kind: "total",
    });
    return lines;
  }

  if (bill.bill_type === "agent") {
    const counterparty = resolveBillPartyName(bill, "counterparty", t);
    const lines: BillBreakdownLine[] = [];
    if (bill.gross_win_loss != null) {
      lines.push({
        key: "gross",
        label: t("settlementCenter:billDisplay.teamGross", { defaultValue: "本期团队赢亏" }),
        amount: Math.abs(gross),
        signedAmount: gross,
        kind: "add",
        hint: t("settlementCenter:billDisplay.teamGrossHint", {
          defaultValue: "本级及下级玩家本期合计",
        }),
      });
    }
    if (bill.rebate_amount != null && rebate !== 0) {
      lines.push({
        key: "rebate",
        label: t("settlementCenter:billDisplay.teamRebate", { defaultValue: "扣玩家回水" }),
        amount: Math.abs(rebate),
        signedAmount: -Math.abs(rebate),
        kind: "subtract",
      });
    }
    if (bill.gross_win_loss != null || bill.rebate_amount != null) {
      lines.push({
        key: "team-net",
        label: t("settlementCenter:billDisplay.teamNet", { defaultValue: "可分配利润" }),
        amount: Math.abs(teamNet),
        signedAmount: teamNet,
        kind: "subtotal",
      });
    }
    if (downlineShares && downlineShares.total > 0) {
      lines.push({
        key: "downline-share",
        label: billDisplayLabel(t, "agentDownlineShare", "下级代理保留"),
        amount: Math.abs(downlineShares.total),
        signedAmount: -Math.abs(downlineShares.total),
        kind: "subtract",
        hint: billDisplayLabel(
          t,
          "agentDownlineShareHint",
          "下级代理按约定比例先保留的金额（明细见下行）",
        ),
        children: downlineShares.items.map((item) => ({
          key: `downline-share-${item.owner_id}`,
          label: billDisplayLabel(t, "agentDownlineShareItem", "{{agent}} 保留", {
            agent: item.owner_label,
          }),
          amount: Math.abs(item.share_profit),
          signedAmount: -Math.abs(item.share_profit),
          kind: "subtract" as const,
        })),
      });
    }
    if (meta.share_profit != null) {
      lines.push({
        key: "share",
        label: billDisplayLabel(t, "agentShareKeep", "本级保留"),
        amount: Math.abs(shareProfit),
        signedAmount: -Math.abs(shareProfit),
        kind: "subtract",
        hint: billDisplayLabel(t, "agentShareKeepHint", "本级按约定比例保留的金额"),
      });
    }
    if (rounding !== 0) {
      lines.push({
        key: "rounding",
        label: t("agents:settlementBills.platformRounding", { defaultValue: "平台尾差" }),
        amount: Math.abs(rounding),
        signedAmount: rounding > 0 ? -Math.abs(rounding) : Math.abs(rounding),
        kind: rounding > 0 ? "subtract" : "add",
      });
    }
    lines.push({
      key: "net",
      label:
        bill.net_amount > 0
          ? billDisplayLabel(t, "agentNet", "应上缴 {{counterparty}}", { counterparty })
          : billDisplayLabel(t, "agentNetReceive", "{{counterparty}} 应补给本级", { counterparty }),
      amount: Math.abs(bill.net_amount),
      signedAmount: bill.net_amount,
      kind: "total",
    });
    return lines;
  }

  return [];
}

export function billGrossColumnHint(
  bill: SettlementBillRow,
  t: TFunction<["agents", "settlementCenter"]>,
): string | undefined {
  if (bill.bill_type === "player") {
    return t("settlementCenter:billDisplay.playerGrossShort", { defaultValue: "玩家" });
  }
  if (bill.bill_type === "agent") {
    return t("settlementCenter:billDisplay.teamGrossShort", { defaultValue: "团队" });
  }
  return undefined;
}
