import type { CardColor, CardValue, Hand, StashData } from '../types';

export function computePlayable(hand: Hand, ledColor: CardColor | null): Set<string> {
  const keys = Object.keys(hand);
  if (!ledColor) return new Set(keys);

  const ledKeys = keys.filter((k) => hand[k].color === ledColor);
  if (ledKeys.length > 0) return new Set(ledKeys);

  const heartKeys = keys.filter((k) => hand[k].color === 'HEARTS');
  if (heartKeys.length > 0) return new Set(heartKeys);

  return new Set(keys);
}

const VALUE_ORDER: CardValue[] = ['C7', 'C8', 'C9', 'C10', 'LOWER', 'UPPER', 'KING', 'ACE'];

/** Seat that wins a completed 4-card trick — mirrors Stash.get_winner in the
 *  engine: HEARTS (červeň) is the permanent trump, otherwise the highest card
 *  of the led colour wins. Safe to call on a partial stash (returns the current
 *  leader among the cards played so far). */
export function stashWinner(stash: StashData): number {
  const led = stash.cards[String(stash.first_player)];
  if (!led) return stash.first_player;
  let winner = stash.first_player;
  let best = led;
  for (let i = 0; i < 4; i++) {
    const c = stash.cards[String(i)];
    if (!c) continue;
    if (c.color === led.color || c.color === 'HEARTS') {
      if (c.color === best.color) {
        if (VALUE_ORDER.indexOf(c.value) >= VALUE_ORDER.indexOf(best.value)) {
          best = c;
          winner = i;
        }
      } else if (c.color === 'HEARTS') {
        best = c;
        winner = i;
      }
    }
  }
  return winner;
}

/** The bid the last guesser may not make: the four bids must not sum to the
 *  number of tricks in the round (mirrors Round.add_player_guess in the engine).
 *  Returns null while earlier players are still guessing. */
export function forbiddenGuess(cardsInRound: number, guesses: Record<string, number>): number | null {
  if (Object.keys(guesses).length !== 3) return null;
  const alreadySum = Object.values(guesses).reduce((a, b) => a + b, 0);
  return cardsInRound - alreadySum;
}
