package pokercore

import (
	"errors"
)

var ErrDuplicateCard = errors.New("cannot score a poker hand out of a set of cards with duplicates")

// this method makes a n new hands where n is the number of cards in the hand
// each of the new hands has one card removed from the original hand
// then it calls the identifyBestFiveCardPokerHand method on each of the new hands
// and returns the best hand by score.  this is recursion and is exponential in time complexity
func (hand Cards) IdentifyBestFiveCardPokerHand() (Cards, error) {

	//fmt.Println("hand: ", hand)
	if hand.containsDuplicates() {
		return nil, ErrDuplicateCard
	}

	if len(hand) == 5 {
		return hand, nil
	}

	if len(hand) < 5 {
		return nil, errors.New("hand must have at least 5 cards to identify the best 5 card poker hand")
	}

	newHands := make([]Cards, len(hand))
	for i := 0; i < len(hand); i++ {
		newHand := make(Cards, len(hand)-1)
		copy(newHand, hand[:i])
		copy(newHand[i:], hand[i+1:])
		//fmt.Printf("generating new subset of hand: %+v\n", newHand)
		//fmt.Printf("this subset drops the card at index %d: %s\n", i, hand[i].String())
		newHands[i] = newHand
	}
	//fmt.Printf("newHands: %+v\n", newHands)
	var bestHand Cards
	var bestScore HandScore

	for _, h := range newHands {
		if len(h) == 5 {
			score, _ := h.PokerHandScore()
			if score > bestScore {
				bestScore = score
				bestHand = h
			}
		} else {
			rh, _ := h.IdentifyBestFiveCardPokerHand()
			score, _ := rh.PokerHandScore()
			if score > bestScore {
				bestScore = score
				bestHand = rh
			}
		}
	}
	return bestHand, nil
}
