# ╔══════════════════════════════════════════════════════════════════╗
# ║                                                                  ║
# ║   ░█▀▀░█▀█░█▀▄░█▀▀░█░█   ░█▀▄░█▀▀░█░█░█▀▀                     ║
# ║   ░█░░░█░█░█░█░█▀▀░▄▀▄   ░█░█░█▀▀░▀▄▀░▀▀█                     ║
# ║   ░▀▀▀░▀▀▀░▀▀░░▀▀▀░▀░▀   ░▀▀░░▀▀▀░░▀░░▀▀▀                     ║
# ║                                                                  ║
# ║            © 2026 CodeX Devs — All Rights Reserved              ║
# ║                                                                  ║
# ║   discord  ──  https://discord.gg/codexdev                      ║
# ║   youtube  ──  https://youtube.com/@CodeXDevs                   ║
# ║   github   ──  https://github.com/RayExo                        ║
# ║                                                                  ║
# ╚══════════════════════════════════════════════════════════════════╝

from __future__ import annotations

from typing import ClassVar, Optional

import discord
from discord.ext import commands

from ..tictactoe import Tictactoe
from ..utils import *


class TTTButton(discord.ui.Button["TTTView"]):
    def __init__(self, label: str, style: discord.ButtonStyle, *, row: int, col: int):
        super().__init__(
            label=label,
            style=style,
            row=row,
        )

        self.col = col

    async def callback(self, interaction: discord.Interaction) -> None:
        user = interaction.user
        game = self.view.game

        if user not in (game.cross, game.circle):
            return await interaction.response.send_message(
                "You are not part of this game!", ephemeral=True
            )

        if user != game.turn:
            return await interaction.response.send_message(
                "it is not your turn!", ephemeral=True
            )

        self.label = game.player_to_emoji[user]
        self.disabled = True

        game.board[self.row][self.col] = self.label
        game.turn = game.circle if user == game.cross else game.cross

        tie = all(button.disabled for button in self.view.children)

        if game_over := game.is_game_over(tie=tie):
            if game.winning_indexes:
                self.view.disable_all()
                game.create_streak()
            self.view.stop()

        embed = game.make_embed(game_over=game_over or tie)
        await interaction.response.edit_message(embed=embed, view=self.view)


class TTTView(BaseView):
    def __init__(self, game: BetaTictactoe, *, timeout: float) -> None:
        super().__init__(timeout=timeout)

        self.game = game

        for x, row in enumerate(game.board):
            for y, square in enumerate(row):
                button = TTTButton(
                    label=square,
                    style=self.game.button_style,
                    row=x,
                    col=y,
                )
                self.add_item(button)


class BetaTictactoe(Tictactoe):
    """
    Tictactoe(buttons) game
    """

    BLANK: ClassVar[str] = "\u200b"
    CIRCLE: ClassVar[str] = "O"
    CROSS: ClassVar[str] = "X"

    def create_streak(self) -> None:
        chunked = chunk(self.view.children, count=3)
        for row, col in self.winning_indexes:
            button: TTTButton = chunked[row][col]
            button.style = self.win_button_style

    async def start(
        self,
        ctx: commands.Context[commands.Bot],
        button_style: discord.ButtonStyle = discord.ButtonStyle.green,
        *,
        embed_color: DiscordColor = DEFAULT_COLOR,
        win_button_style: discord.ButtonStyle = discord.ButtonStyle.red,
        timeout: Optional[float] = None,
    ) -> discord.Message:
        """
        starts the tictactoe(buttons) game

        Parameters
        ----------
        ctx : commands.Context
            the context of the invokation command
        button_style : discord.ButtonStyle, optional
            the primary button style to use, by default discord.ButtonStyle.green
        embed_color : DiscordColor, optional
            the color of the game embed, by default DEFAULT_COLOR
        win_button_style : discord.ButtonStyle, optional
            the button style to use to show the winning line, by default discord.ButtonStyle.red
        timeout : Optional[float], optional
            the timeout for the view, by default None

        Returns
        -------
        discord.Message
            returns the game message
        """
        self.embed_color = discord.Color.random()
        self.button_style = button_style
        self.win_button_style = win_button_style

        self.view = TTTView(self, timeout=timeout)
        self.message = await ctx.send(embed=self.make_embed(), view=self.view)

        await double_wait(
            wait_for_delete(ctx, self.message, user=(self.cross, self.circle)),
            self.view.wait(),
        )

        return self.message
