import type { OfficeBuyoutListItem } from "@/types/office-buyout";

type DecimalLike = { toNumber(): number };

type SerializableOfficeBuyout = {
  id: bigint;
  purchaseNo: string;
  purchaseDate: Date;
  status: string;
  buyoutSourceAgent: { id: bigint; name: string } | null;
  lines: Array<{
    id: bigint;
    qtyOrdered: DecimalLike;
    unitPrice: DecimalLike;
    buyoutMalUnitPriceSnapshot: DecimalLike | null;
    buyoutAgentSharePercent: DecimalLike | null;
    buyoutProfitAmount: DecimalLike | null;
    buyoutAgentCommission: DecimalLike | null;
    unit: { code: string };
    sourceLot: {
      id: bigint;
      lotCode: string;
      grade: { name: string } | null;
    } | null;
  }>;
  lots: Array<{
    lotCode: string;
    purchaseLineId: bigint | null;
  }>;
};

export function serializeOfficeBuyoutListItem(
  purchase: SerializableOfficeBuyout
): OfficeBuyoutListItem {
  const resultLotCodeMap = new Map(
    purchase.lots
      .filter((lot) => lot.purchaseLineId !== null)
      .map((lot) => [lot.purchaseLineId!.toString(), lot.lotCode])
  );

  return {
    id: purchase.id.toString(),
    purchase_no: purchase.purchaseNo,
    purchase_date: purchase.purchaseDate.toISOString().slice(0, 10),
    status: purchase.status,
    source_agent: purchase.buyoutSourceAgent
      ? {
          id: purchase.buyoutSourceAgent.id.toString(),
          name: purchase.buyoutSourceAgent.name
        }
      : null,
    line_count: purchase.lines.length,
    total_qty: purchase.lines.reduce((sum, line) => sum + line.qtyOrdered.toNumber(), 0),
    total_buyout_amount: purchase.lines.reduce(
      (sum, line) => sum + line.qtyOrdered.toNumber() * line.unitPrice.toNumber(),
      0
    ),
    total_agent_commission: purchase.lines.reduce(
      (sum, line) => sum + (line.buyoutAgentCommission?.toNumber() ?? 0),
      0
    ),
    lines: purchase.lines.map((line) => ({
      id: line.id.toString(),
      source_lot_id: line.sourceLot?.id.toString() ?? "",
      source_lot_code: line.sourceLot?.lotCode ?? "-",
      result_lot_code: resultLotCodeMap.get(line.id.toString()) ?? "-",
      grade: line.sourceLot?.grade?.name ?? "-",
      qty_buyout: line.qtyOrdered.toNumber(),
      unit_code: line.unit.code,
      buyout_unit_price: line.unitPrice.toNumber(),
      mal_unit_price_snapshot: line.buyoutMalUnitPriceSnapshot?.toNumber() ?? 0,
      agent_share_percent: line.buyoutAgentSharePercent?.toNumber() ?? 0,
      profit_amount: line.buyoutProfitAmount?.toNumber() ?? 0,
      agent_commission: line.buyoutAgentCommission?.toNumber() ?? 0
    }))
  };
}
