import discord
from random import shuffle, choice
from discord.ext import commands
import utils.sql_commands as mydb


lottery_list = ["🎁", "🎮", "🎷", "🔫", "📸", "🎃", "🏅"]

lottery_win = {
    "🎁": 2,
    "🎁🎁": 5,
    "🎁🎁🎁": 500,
    "🔫🔫🔫": 25,
    "📸📸📸": 50,
    "🎃🎃🎃": 75,
    "🏅🏅🏅": 100,
    "🎮🎮🎮": 250,
    "🎷🎷🎷": 1000,
}

bj_values = {
    "2♦️": 2,
    "2♥️": 2,
    "2♣️": 2,
    "2♠️": 2,
    "3♦️": 3,
    "3♥️": 3,
    "3♣️": 3,
    "3♠️": 3,
    "4♦️": 4,
    "4♥️": 4,
    "4♣️": 4,
    "4♠️": 4,
    "5♦️": 5,
    "5♥️": 5,
    "5♣️": 5,
    "5♠️": 5,
    "6♦️": 6,
    "6♥️": 6,
    "6♣️": 6,
    "6♠️": 6,
    "7♦️": 7,
    "7♥️": 7,
    "7♣️": 7,
    "7♠️": 7,
    "8♦️": 8,
    "8♥️": 8,
    "8♣️": 8,
    "8♠️": 8,
    "9♦️": 9,
    "9♥️": 9,
    "9♣️": 9,
    "9♠️": 9,
    "10♦️": 10,
    "10♥️": 10,
    "10♣️": 10,
    "10♠️": 10,
    "J♦️": 10,
    "J♥️": 10,
    "J♣️": 10,
    "J♠️": 10,
    "Q♦️": 10,
    "Q♥️": 10,
    "Q♣️": 10,
    "Q♠️": 10,
    "K♦️": 10,
    "K♥️": 10,
    "K♣️": 10,
    "K♠️": 10,
    "A♦️": 11,
    "A♥️": 11,
    "A♣️": 11,
    "A♠️": 11,
}


class Deck:
    def __init__(self):
        self.deck = list(bj_values.keys())
        shuffle(self.deck)

    async def deal(self):
        return self.deck.pop()


class Hand:
    def __init__(self, name, bet):
        self.cards = []
        self.value = 0
        self.aces = 0
        self.bust = False
        self.name = name
        self.bet = bet

    async def win_bet(self):
        pass

    async def lose_bet(self):
        pass

    async def add_card(self, card):
        self.cards.append(card)
        self.aces = ("".join(self.cards)).count("A")
        value = 0
        for card in self.cards:
            value += bj_values[card]
        self.value = value
        while self.value > 21 and self.aces:
            self.value -= 10
            self.aces -= 1


async def hit(deck, hand):
    await hand.add_card(await deck.deal())


async def double(deck, hand):
    pass


async def split(deck, hands):
    pass


async def payout(ctx, play, amount, multiplier):
    await ctx.reply(
        f"{play}\nBet: {amount:,}\nYou won {amount * multiplier:,} Flooneys"
    )


async def check_winner(msg: discord.Interaction, player_hand, dealer_hand):
    p_value, d_value = player_hand.value, dealer_hand.value
    embed = discord.Embed(description="Blackjack")
    embed.add_field(name="Bet: ", value="amount", inline=True)
    embed.add_field(
        name=player_hand.name,
        value=f"{', '.join(player_hand.cards)}: {player_hand.value}",
        inline=False,
    )
    embed.add_field(
        name=dealer_hand.name,
        value=f"{', '.join(dealer_hand.cards)}: {dealer_hand.value}",
        inline=False,
    )

    if (p_value > d_value and not player_hand.bust) or dealer_hand.bust:
        embed.add_field(name="Winner:", value=f"{player_hand.name}", inline=False)
        player_balance = int(mydb.select("WALLET", "economy", True, "ID", player_hand.name.id).get("WALLET", None))
        mydb.add("economy", "ID", "WALLET", player_hand.name.id, player_balance + player_hand.bet*2, True)
    elif p_value < d_value and dealer_hand.bust:
        embed.add_field(name="Winner:", value=f"{dealer_hand.name}", inline=False)
    else:
        embed.add_field(name="Winner:", value=f"Draw", inline=False)
    await msg.edit_original_response(embed=embed)


async def dealer(msg: discord.Interaction, player_hand, dealer_hand, cards):
    while dealer_hand.value < 17 and not player_hand.bust and not dealer_hand.bust:
        await hit(cards, dealer_hand)
        if dealer_hand.value > 21:
            dealer_hand.bust = True
    embed = discord.Embed(description="Blackjack")
    embed.add_field(name="Bet: ", value="amount", inline=True)
    embed.add_field(
        name=player_hand.name,
        value=f"{', '.join(player_hand.cards)}: {player_hand.value}",
        inline=False,
    )
    embed.add_field(
        name=dealer_hand.name,
        value=f"{', '.join(dealer_hand.cards)}: {dealer_hand.value}",
        inline=False,
    )
    await msg.edit_original_response(embed=embed)
    await check_winner(msg, player_hand, dealer_hand)


class MyView(discord.ui.View):
    def __init__(self, player_hand, dealer_hand, cards):
        super().__init__()
        self.player_hand = player_hand
        self.dealer_hand = dealer_hand
        self.cards = cards

    @discord.ui.button(label="Hit", style=discord.ButtonStyle.primary, emoji="✅")
    async def hit(self, interaction: discord.Interaction, button: discord.ui.Button):
        await hit(self.cards, self.player_hand)
        embed = discord.Embed(description="Blackjack")
        embed.add_field(name="Bet: ", value="amount", inline=True)
        embed.add_field(
            name=self.player_hand.name,
            value=f"{', '.join(self.player_hand.cards)}: {self.player_hand.value}",
            inline=False,
        )
        embed.add_field(
            name=self.dealer_hand.name,
            value=f"{(self.dealer_hand.cards)[0]}",
            inline=False,
        )
        msg = interaction
        if self.player_hand.value < 21:
            await msg.response.edit_message(embed=embed)
        else:
            await msg.response.edit_message(embed=embed, view=None)
            if self.player_hand.value > 21:
                self.player_hand.bust = True
            await dealer(msg, self.player_hand, self.dealer_hand, self.cards)

    @discord.ui.button(label="Stand", style=discord.ButtonStyle.secondary, emoji="🛑")
    async def stand(self, interaction: discord.Interaction, button: discord.ui.Button):
        embed = discord.Embed(description="Blackjack")
        embed.add_field(name="Bet: ", value=self.player_hand.bet, inline=True)
        embed.add_field(
            name=self.player_hand.name,
            value=f"{', '.join(self.player_hand.cards)}: {self.player_hand.value}",
            inline=False,
        )
        embed.add_field(
            name=self.dealer_hand.name,
            value=f"{(self.dealer_hand.cards)[0]}",
            inline=False,
        )
        msg = interaction
        await msg.response.edit_message(embed=embed, view=None)
        await dealer(msg, self.player_hand, self.dealer_hand, self.cards)


class Gamble(commands.Cog):
    def __init__(self, client):
        self.client = client

    @commands.command()
    async def blackjack(self, ctx, bet):
        amount = int(bet)

        cards = Deck()
        player_balance = int(mydb.select("WALLET", "economy", True, "ID", ctx.author.id).get(
                "WALLET", None
            )
        )
        if player_balance < bet or bet < 0:
            await ctx.reply("You have insufficient funds.")
            return
        mydb.add("economy", "ID", "WALLET", ctx.author.id, player_balance - bet, True)
        player_hand, dealer_hand = Hand(ctx.author, amount), Hand("Dealer", None)

        # setup
        for _ in range(2):
            await player_hand.add_card(await cards.deal())
            await dealer_hand.add_card(await cards.deal())

        embed = discord.Embed(description="Blackjack")
        embed.add_field(name="Bet: ", value=amount, inline=True)
        embed.add_field(
            name=ctx.author,
            value=f"{', '.join(player_hand.cards)}: {player_hand.value}",
            inline=False,
        )
        embed.add_field(name="Dealer", value=f"{(dealer_hand.cards)[0]}", inline=False)

        view = MyView(player_hand, dealer_hand, cards)
        await ctx.send(embed=embed, view=view)

    @commands.command()
    async def show_buttons(self, ctx):
        await ctx.reply(
            "This is a button!", view=MyView(None, None, None)
        )  # Send a message with our View class that contains the button


    @commands.cooldown(1, 1, commands.BucketType.user)
    @commands.command(name="lottery", aliases=["slots"])
    async def lottery(self, ctx, bet: int):
        player_balance = int(
            mydb.select("WALLET", "economy", True, "ID", ctx.author.id).get(
                "WALLET", None
            )
        )
        if player_balance < bet or bet < 0:
            await ctx.reply("You have insufficient funds.")
            return
        play = "".join([choice(lottery_list) for _ in range(3)])

        if play in lottery_win:
            mult = lottery_win[play]
            await payout(ctx, play, bet, mult)

        elif play.count("🎁") == 2:
            mult = lottery_win["🎁🎁"]
            await payout(ctx, play, bet, mult)

        elif play.count("🎁") == 1:
            mult = lottery_win["🎁"]
            await payout(ctx, play, bet, mult)

        else:
            mydb.add("economy", "ID", "WALLET", ctx.author.id, player_balance - bet, True)
            await ctx.reply(f"{play}\nYou lost {int(bet):,} Flooneys")


async def setup(client):
    await client.add_cog(Gamble(client))