from itertools import product
from random import shuffle


class GoFish:
    """Represents a game of Go Fish.

    Instance variables:
        deck (list): The deck of cards
        players (list): The list of players

    Public methods:
        make_deck()
        make_players()
        deal()
    """

    def __init__(self):
        self.deck = []
        self.players = []

    def make_deck(self):
        """Append 52 Card objects to the game's deck."""
        suits = ['Hearts', 'Diamonds', 'Clubs', 'Spades']
        values = ['Ace', 'King', 'Queen', 'Jack', 'Ten', 'Nine', 'Eight',
                 'Seven', 'Six', 'Five', 'Four', 'Three', 'Two']

        for set in product(suits, values):
            self.deck.append(Card(set))

        shuffle(self.deck)

    def make_players(self, count):
        """Append the specified number of Player objects to the player list.

        Arguments:
            count (int): The number of players to be added.

        Raises:
            PlayerCountError: When the count is
                less than 2, or greater than 6.
        """
        names = ['Jack', 'Bob', 'Sally', 'Jim', 'Jill', 'Timmy',
                 'Sarah', 'Ben', 'Kate', 'Jessica', 'Will', 'Sam']
        shuffle(names)

        if count > 6 or count < 2:
            raise PlayerCountError("Must choose between 2 and 6 players")

        for __ in range(0, count):
            player = Player(names.pop())
            self.players.append(player)

    def deal(self):
        """Pop cards from deck and append to each player's `hand` property"""
        count = 5

        if len(self.players) == 2:
            count = 7

        for __ in range(0, count):
            for player in self.players:
                card = self.deck.pop()
                player.hand.append(card)


class Player:
    """Represents a single card player."""

    def __init__(self, name):
        self.name = name
        self.hand = []
        # self.memory = []
        # self.matches = 0


class Card:
    """Represents a card in the deck."""

    def __init__(self, card):
        self.suit = card[0]
        self.value = card[1]


class PlayerCountError(Exception):
    """An error that is raised when an invalid number of users is chosen.
    Must be between 2 and 6."""

    def __init__(self, message):
        pass
