import random
import rich
import sys
import os

game = {"draw_pile": [],
        "play_pile": [],
        "hand0": [],
        "hand1": [],
        "hand2": [],
        "hand3": [],
        "name0": "Brianna",
        "name1": "Jakayla",
        "name2": "Mariam",
        "name3": "Thao",
        "current_player": 0,
        "direction": "clockwise",
        "wild_color": None}

# a color is either
# "red", "blue", "green", or "yellow"

# a card will be either
# - a pair like ("green", 8)
# - "wild", or
# - "draw4"

# Let's build a deck of numbered cards.

def advance_player():
    if game["direction"]=="clockwise":
        if game["current_player"]==0:
            game["current_player"]=1
        elif game["current_player"]==1:
            game["current_player"]=2
        elif game["current_player"]==2:
            game["current_player"]=3
        elif game["current_player"]==3:
            game["current_player"]=0
    else:
        if game["current_player"]==0:
            game["current_player"]=3
        elif game["current_player"]==3:
            game["current_player"]=2
        elif game["current_player"]==2:
            game["current_player"]=1
        elif game["current_player"]==1:
            game["current_player"]=0

def new_deck():
    deck = []
    for color in ["red","green","blue","yellow"]:
        for i in range(10):
            if i==0:
                deck.append((color,i))
            else:
                deck.append((color, i))
                deck.append((color, i))
        deck.append((color,"reverse"))
        deck.append((color,"reverse"))
        deck.append((color,"skip"))
        deck.append((color,"skip"))
        deck.append((color,"+2"))
        deck.append((color,"+2"))
    return deck

def print_card(card):
    (color, rank) = card
    rich.print("["+color+"]("+str(rank)+")[/]",end="")

def deal():
    for i in range(7):
        game["hand0"].append(game["draw_pile"].pop())
        game["hand1"].append(game["draw_pile"].pop())
        game["hand2"].append(game["draw_pile"].pop())
        game["hand3"].append(game["draw_pile"].pop())

def can_play_card(top_card, card):
    (top_color, top_rank) = top_card
    (card_color, card_rank) = card
    if top_color==card_color:
        return True
    elif top_rank==card_rank:
        return True
    else:
        return False

# build list of cards that can be played on top card
def playable(top_card, hand):
    result = []
    for card in hand:
        if can_play_card(top_card, card):
            result.append(card)
    return result

def show_table():
    os.system("clear")
    print("top card", end=" ")
    top_card = game["play_pile"][-1] # bottom card of play pile
    print_card(top_card)
    print()
    for i in [0,1,2,3]:
        if i==game["current_player"]:
            rich.print(">>> " + game["name"+str(i)], end=" ")
        else:
            print("... " + game["name" + str(i)], end=" ")
        hand = game["hand"+str(i)]
        if i==0:
            for card in hand:
                print_card(card)
        else:
            print(len(hand),"cards", end=" ")
        print()
    #print("current player", game["current_player"])
    print("direction:", game["direction"])
    #print("wild color", game["wild_color"])

def change_direction():
    if game["direction"]=="clockwise":
        game["direction"]="counterclockwise"
    else:
        game["direction"]="clockwise"

def player_turn():
    # print("top card", end=" ")
    top_card = game["play_pile"][-1]
    # print_card(top_card)
    # print()
    i = 0
    hand = game["hand0"]
    for card in hand:
        print(i,end=" ")
        print_card(card)
        print()
        i += 1
    print("What would you like to do?")
    print("Type a number to play a card.")
    print("(d) Draw.")
    print("(q) Quit.")
    choice = input(">> ")
    if choice=="q":
        print("Bye!")
        sys.exit()
    elif choice=="d":
        print("You chose to draw a card.")
        game["hand0"].append(game["draw_pile"].pop())
    else:
        chosen_card = int(choice)
        card = hand[chosen_card]
        print("You chose to play", end=" ")
        print_card(card)
        print()
        if can_play_card(top_card, card):
            # print("Good choice!")
            if card[1]=="reverse":
                change_direction()
                print("The direction has been reversed!")
            elif card[1]=="skip":
                advance_player()
                cp = game["current_player"]
                print(game["name"+str(cp)],"has been skipped!")
            elif card[1]=="+2":
                advance_player()
                cp = game["current_player"]
                print(game["name"+str(cp)],"must draw two cards!")
                game["hand"+str(cp)].append(game["draw_pile"].pop())
                game["hand"+str(cp)].append(game["draw_pile"].pop())
            game["hand0"].remove(card)
            game["play_pile"].append(card)
            if len(game["hand0"])==1:
                os.system("UNO!")
        else:
            print("You can't play that card.")
            player_turn()
            return
    advance_player()
    x = input("Press enter.")
    #else:
    #    print("I didn't understand your choice.")
    #    player_turn()

def computer_turn():
    cp = game["current_player"]
    name = game["name"+str(cp)]
    hand = game["hand"+str(cp)]
    x = input("It's " + name + "'s turn. Press enter.")
    top_card = game["play_pile"][-1]
    choices = playable(top_card,hand)
    if len(choices)==0:
        print(name,"cannot play a card.")
        print(name,"draws a card.")
        game["hand"+str(cp)].append(game["draw_pile"].pop())
    else:
        card = random.choice(choices) # randomly choose a playable card
        print(name,"chose",end=" ")
        game["hand"+str(cp)].remove(card)
        game["play_pile"].append(card)
        print_card(card)
        print()
        if card[1]=="reverse":
            change_direction()
            print("The direction has been reversed!")
        elif card[1]=="skip":
            advance_player()
            cp = game["current_player"]
            print(game["name"+str(cp)],"has been skipped!")
        elif card[1] == "+2":
            advance_player()
            cp = game["current_player"]
            print(game["name" + str(cp)], "must draw two cards!")
            game["hand" + str(cp)].append(game["draw_pile"].pop())
            game["hand" + str(cp)].append(game["draw_pile"].pop())
    advance_player()
    x = input("Press enter.")

def winner():
    if len(game["hand0"])==0:
        return game["name0"]
    elif len(game["hand1"])==0:
        return game["name1"]
    elif len(game["hand2"])==0:
        return game["name2"]
    elif len(game["hand3"])==0:
        return game["name3"]
    else:
        return None

def play_game():
    deck = new_deck()
    print("shuffling...")
    random.shuffle(deck)
    game["draw_pile"] = deck
    deal()
    game["play_pile"].append(game["draw_pile"].pop())
    w = winner()
    while w is None:
        print()
        show_table()
        if game["current_player"]==0:
            player_turn()
        else:
            computer_turn()
        w = winner()
    print("Game over!")
    print(w,"won the game!")

play_game()
