import type { Card, Rank, Suit } from './types';

const SUIT_SYMBOL: Record<Suit, string> = {
  heart: '♥',
  diamond: '♦',
  spade: '♠',
  club: '♣',
  joker: '★',
};

const RANK_LABEL: Record<Rank, string> = {
  '2': '2',
  '3': '3',
  '4': '4',
  '5': '5',
  '6': '6',
  '7': '7',
  '8': '8',
  '9': '9',
  '10': '10',
  J: 'J',
  Q: 'Q',
  K: 'K',
  JOKER: '鬼',
};

export type CardColor = 'red' | 'black';

export function isRed(suit: Suit): boolean {
  return suit === 'heart' || suit === 'diamond';
}

/** 牌色：红=红桃/方片，黑=黑桃/梅花，joker 无色 */
export function cardColor(card: Card): CardColor | null {
  if (card.suit === 'joker') return null;
  return isRed(card.suit) ? 'red' : 'black';
}

export function isJoker(card: Card): boolean {
  return card.suit === 'joker';
}

/** 丁丁：红桃3（全副仅一张） */
export function isHeart3(card: Card): boolean {
  return card.suit === 'heart' && card.rank === '3';
}

export function cardLabel(card: Card): string {
  if (card.suit === 'joker') return '大王';
  return RANK_LABEL[card.rank];
}

export function cardSymbol(card: Card): string {
  return SUIT_SYMBOL[card.suit];
}

let counter = 0;
export function makeCard(suit: Suit, rank: Rank, faceUp: boolean): Card {
  counter += 1;
  return { id: `c${counter}`, suit, rank, faceUp };
}

/**
 * 构造官方 32 张扯旋牌库：
 * 红桃3 ×1、大王 ×1、红Q ×2、红2 ×2、黑5 ×2、黑9 ×2、黑J ×2、
 * 4 / 6 / 7 / 8 / 10 各四张（共 20 张）。合计 32 张。
 */
export function buildDeck(faceUp = false): Card[] {
  const deck: Card[] = [];
  // 单张：红桃3、大王
  deck.push(makeCard('heart', '3', faceUp));
  deck.push(makeCard('joker', 'JOKER', faceUp));
  // 红Q / 红2（红桃 + 方片）
  for (const s of ['heart', 'diamond'] as Suit[]) {
    deck.push(makeCard(s, 'Q', faceUp));
    deck.push(makeCard(s, '2', faceUp));
  }
  // 黑5 / 黑9 / 黑J（黑桃 + 梅花）
  for (const s of ['spade', 'club'] as Suit[]) {
    deck.push(makeCard(s, '5', faceUp));
    deck.push(makeCard(s, '9', faceUp));
    deck.push(makeCard(s, 'J', faceUp));
  }
  // 4 / 6 / 7 / 8 / 10 各四张
  for (const r of ['4', '6', '7', '8', '10'] as Rank[]) {
    for (const s of ['heart', 'diamond', 'spade', 'club'] as Suit[]) {
      deck.push(makeCard(s, r, faceUp));
    }
  }
  return deck;
}

/** Fisher–Yates 洗牌（返回新数组，不改原数组） */
export function shuffle<T>(arr: T[]): T[] {
  const a = arr.slice();
  for (let i = a.length - 1; i > 0; i--) {
    const j = Math.floor(Math.random() * (i + 1));
    [a[i], a[j]] = [a[j], a[i]];
  }
  return a;
}

/**
 * 单张大小（数值越大越强，1..7）：
 * 红Q(7) > 红2(6) > 红8(5) > 红4(4) > (黑10=黑4=黑6)(3) >
 * (黑J=红10=红6=红7)(2) > (黑5=黑7=黑8=黑9=红桃3=大王)(1)
 */
export function singleValue(card: Card): number {
  if (isJoker(card) || isHeart3(card)) return 1; // 下四烂
  const color = cardColor(card);
  const r = card.rank;
  if (color === 'red') {
    if (r === 'Q') return 7;
    if (r === '2') return 6;
    if (r === '8') return 5;
    if (r === '4') return 4;
    if (r === '10' || r === '6' || r === '7') return 2; // 苕十/猫猫/膏药（下腰）
    return 1;
  }
  // black
  if (r === '10' || r === '4' || r === '6') return 3; // 梅十/板凳/长三（中三）
  if (r === 'J') return 2; // 虎头/斧头（下腰）
  return 1; // 黑5/黑7/黑8/黑9（下四烂）
}

/** 散牌点数：红Q=2,黑J=1,大王=6,红桃3=3，其余按牌面 */
export function cardPoint(card: Card): number {
  if (isJoker(card)) return 6;
  if (card.rank === 'Q') return 2;
  if (card.rank === 'J') return 1;
  return Number(card.rank);
}

/**
 * 一对（同色同点）的官方牌型名：
 * 红Q→天牌 红2→地牌 红8→人牌 红4→和牌
 * 黑10→梅十 黑4→板凳 黑6→长三
 * 黑J→虎头 红10→苕十 红6→猫猫 红7→膏药
 * 黑5/黑7/黑8/黑9→对子
 */
export function pairName(card: Card): string {
  const color = cardColor(card);
  const r = card.rank;
  if (color === 'red') {
    if (r === 'Q') return '天牌';
    if (r === '2') return '地牌';
    if (r === '8') return '人牌';
    if (r === '4') return '和牌';
    if (r === '10') return '苕十';
    if (r === '6') return '猫猫';
    if (r === '7') return '膏药';
  } else {
    if (r === '10') return '梅十';
    if (r === '4') return '板凳';
    if (r === '6') return '长三';
    if (r === 'J') return '虎头';
  }
  return '对子'; // 黑5 / 黑7 / 黑8 / 黑9
}

/** 单张中文名（用于牌型标签） */
export function singleName(card: Card): string {
  if (isJoker(card)) return '大王';
  if (isHeart3(card)) return '丁丁';
  const color = cardColor(card);
  const r = card.rank;
  if (color === 'red') {
    if (r === 'Q') return '天';
    if (r === '2') return '地';
    if (r === '8') return '人';
    if (r === '4') return '和';
    if (r === '10') return '苕十';
    if (r === '6') return '猫猫';
    if (r === '7') return '膏药';
  } else {
    if (r === '10') return '梅十';
    if (r === '4') return '板凳';
    if (r === '6') return '长三';
    if (r === 'J') return '斧头';
  }
  return `黑${r}`;
}
