import { type CardMeta, fetchCard } from "@/api";
import { isExtraDeckCard, isToken, tellCardBasicType } from "@/common";
import { type IDeck } from "@/stores";

export type Type = "main" | "extra" | "side";

/** 用在卡组编辑 */
export interface EditingDeck {
  deckName: string;
  main: CardMeta[];
  extra: CardMeta[];
  side: CardMeta[];
}

export const iDeckToEditingDeck = async (
  ideck: IDeck
): Promise<EditingDeck> => ({
  deckName: ideck.deckName,
  main: await Promise.all(ideck.main.map(fetchCard)),
  extra: await Promise.all(ideck.extra.map(fetchCard)),
  side: await Promise.all(ideck.side.map(fetchCard)),
});

export const editingDeckToIDeck = (deck: EditingDeck): IDeck => ({
  deckName: deck.deckName,
  main: deck.main.map((card) => card.id),
  extra: deck.extra.map((card) => card.id),
  side: deck.side.map((card) => card.id),
});

/** 能不能添加到正在编辑的卡组的区域 */
export const canAdd = (
  card: CardMeta,
  type: Type,
  editDeckStore: EditingDeck
): { result: boolean; reason?: string } => {
  let result = true,
    reason;
  const initialCards = editDeckStore[type];
  // 如果是衍生物，则不能添加
  if (isToken(card.data.type ?? 0)) {
    result = false;
    reason = "不能添加衍生物";
  }
  // 超出数量，则不能添加
  const countLimit = type === "main" ? 60 : 15;
  if (initialCards.length >= countLimit) {
    result = false;
    reason = `超过${countLimit}张的上限`;
  }
  // 接着需要检查卡的种类
  if (
    (type === "extra" && !isExtraDeckCard(card.data.type ?? 0)) ||
    (type === "main" && isExtraDeckCard(card.data.type ?? 0))
  ) {
    result = false;
    reason = "卡片种类不符合";
  }
  // 同名卡不超过三张
  const maxSameCard = 3; // TODO: 禁卡表
  const sameCardCount = initialCards.filter((c) => c.id === card.id).length;
  if (sameCardCount >= maxSameCard) {
    result = false;
    reason = `超过同名卡${maxSameCard}张的上限`;
  }
  return { result, reason };
};

/** 卡组内部排序，给array.sort用 */
export const compareCards = (a: CardMeta, b: CardMeta): number => {
  const aType = tellCardBasicType(a.data.type ?? 0);
  const bType = tellCardBasicType(b.data.type ?? 0);
  if (aType !== bType) return aType - bType;
  return a.id - b.id;
};
