import type { TicketItemListRow } from "@/types/api/ticket-items";

export type TicketItemGroup = {
  key: string;
  order_no: string | null;
  order_status: string | null;
  draw_no: string | null;
  placed_at: string | null;
  currency_code: string | null;
  status: string;
  items: TicketItemListRow[];
  total_bet_amount: number;
  actual_deduct_amount: number;
  win_amount: number;
  jackpot_win_amount: number;
};

/** 分组键：有 order_no 则按订单；否则 draw_no + placed_at + currency + status 兜底 */
export function getTicketItemGroupKey(row: TicketItemListRow): string {
  const orderNo = (row.order_no ?? "").trim();
  if (orderNo) {
    return `order:${orderNo}`;
  }
  const drawNo = row.draw_no ?? "";
  const placedAt = row.placed_at ?? "";
  const currency = row.currency_code ?? "";
  const status = row.status ?? "";
  return `fallback:${drawNo}|${placedAt}|${currency}|${status}`;
}

function resolveGroupStatus(items: TicketItemListRow[]): string {
  const orderStatus = items.map((row) => row.order_status).find((s) => s != null && s !== "");
  if (orderStatus === "partial_failed" || orderStatus === "partial_pending_confirm") {
    return orderStatus;
  }

  const hasStatus = (status: string): boolean => items.some((row) => row.status === status);
  const hasAny = (statuses: string[]): boolean => statuses.some((status) => hasStatus(status));
  const allMatch = (statuses: string[]): boolean =>
    items.length > 0 && items.every((row) => statuses.includes(row.status));
  const hasWinningItem = items.some(
    (row) => row.status === "settled_win" && row.win_amount + row.jackpot_win_amount > 0,
  );

  if (hasStatus("failed") && hasAny(["pending_draw", "placed", "pending_confirm"])) {
    return "partial_failed";
  }

  if (hasAny(["pending_confirm", "partial_pending_confirm"])) {
    return hasAny(["failed", "pending_draw", "placed", "pending_payout", "settled_win", "settled_lose"])
      ? "partial_pending_confirm"
      : "pending_confirm";
  }

  if (hasAny(["pending_draw", "placed"])) {
    return "pending_draw";
  }

  if (hasStatus("pending_payout")) {
    return "pending_payout";
  }

  if (hasWinningItem) {
    return "settled_win";
  }

  if (allMatch(["failed"])) {
    return "failed";
  }

  if (allMatch(["refunded"])) {
    return "refunded";
  }

  if (allMatch(["settled_lose", "settled_win"])) {
    return "settled_lose";
  }

  return items[0]?.status ?? "unknown";
}

export function sortTicketGroupItems(items: TicketItemListRow[]): TicketItemListRow[] {
  return [...items].sort((a, b) => {
    const byPlay = a.play_code.localeCompare(b.play_code);
    if (byPlay !== 0) return byPlay;
    return (a.original_number ?? "").localeCompare(b.original_number ?? "");
  });
}

/** 保持 API 返回顺序下，按分组键首次出现顺序输出合并组 */
export function groupTicketItems(items: TicketItemListRow[]): TicketItemGroup[] {
  const map = new Map<string, TicketItemGroup>();
  const order: string[] = [];

  for (const row of items) {
    const key = getTicketItemGroupKey(row);
    let group = map.get(key);
    if (!group) {
      const orderNo = (row.order_no ?? "").trim();
      group = {
        key,
        order_no: orderNo || null,
        order_status: row.order_status ?? null,
        draw_no: row.draw_no ?? null,
        placed_at: row.placed_at ?? null,
        currency_code: row.currency_code ?? null,
        status: row.status,
        items: [],
        total_bet_amount: 0,
        actual_deduct_amount: 0,
        win_amount: 0,
        jackpot_win_amount: 0,
      };
      map.set(key, group);
      order.push(key);
    }
    group.items.push(row);
    group.total_bet_amount += row.total_bet_amount;
    group.actual_deduct_amount += row.actual_deduct_amount;
    group.win_amount += row.win_amount;
    group.jackpot_win_amount += row.jackpot_win_amount;
  }

  return order.map((key) => {
    const group = map.get(key)!;
    const sortedItems = sortTicketGroupItems(group.items);
    return {
      ...group,
      items: sortedItems,
      status: resolveGroupStatus(sortedItems),
      order_status: sortedItems[0]?.order_status ?? group.order_status,
    };
  });
}

export function ticketDetailHref(ticketNo: string): string {
  return `/orders/${encodeURIComponent(ticketNo)}`;
}