# Copyright 2022 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Example Plugin that displays some dynamic content: a game of 2048."""

from random import choice
from typing import Iterable, List, Tuple, TYPE_CHECKING
import time

from prompt_toolkit.filters import has_focus
from prompt_toolkit.formatted_text import StyleAndTextTuples
from prompt_toolkit.key_binding import KeyBindings, KeyPressEvent
from prompt_toolkit.layout import (
    AnyContainer,
    Dimension,
    FormattedTextControl,
    HSplit,
    Window,
    WindowAlign,
    VSplit,
)
from prompt_toolkit.mouse_events import MouseEvent, MouseEventType
from prompt_toolkit.widgets import MenuItem

import pw_console.widgets.border
from pw_console.widgets import (
    FloatingWindowPane,
    ToolbarButton,
    WindowPaneToolbar,
)
from pw_console.plugin_mixin import PluginMixin
from pw_console.get_pw_console_app import get_pw_console_app

if TYPE_CHECKING:
    from pw_console.console_app import ConsoleApp

Twenty48Cell = Tuple[int, int, int]


class Twenty48Game:
    """2048 Game."""
    def __init__(self) -> None:
        self.colors = {
            2: 'bg:#dd6',
            4: 'bg:#da6',
            8: 'bg:#d86',
            16: 'bg:#d66',
            32: 'bg:#d6a',
            64: 'bg:#a6d',
            128: 'bg:#66d',
            256: 'bg:#68a',
            512: 'bg:#6a8',
            1024: 'bg:#6d6',
            2048: 'bg:#0f8',
            4096: 'bg:#0ff',
        }
        self.board: List[List[int]]
        self.last_board: List[Twenty48Cell]
        self.move_count: int
        self.width: int = 4
        self.height: int = 4
        self.max_value: int = 0
        self.start_time: float
        self.reset_game()

    def reset_game(self) -> None:
        self.start_time = time.time()
        self.max_value = 2
        self.move_count = 0
        self.board = []
        for _i in range(self.height):
            self.board.append([0] * self.width)
        self.last_board = list(self.all_cells())
        self.add_random_tiles(2)

    def stats(self) -> StyleAndTextTuples:
        """Returns stats on the game in progress."""
        elapsed_time = int(time.time() - self.start_time)
        minutes = int(elapsed_time / 60.0)
        seconds = elapsed_time % 60
        fragments: StyleAndTextTuples = []
        fragments.append(('', '\n'))
        fragments.append(('', f'Moves: {self.move_count}'))
        fragments.append(('', '\n'))
        fragments.append(('', 'Time:  {:0>2}:{:0>2}'.format(minutes, seconds)))
        fragments.append(('', '\n'))
        fragments.append(('', f'Max: {self.max_value}'))
        fragments.append(('', '\n\n'))
        fragments.append(('', 'Press R to restart\n'))
        fragments.append(('', '\n'))
        fragments.append(('', 'Arrow keys to move'))
        return fragments

    def __pt_formatted_text__(self) -> StyleAndTextTuples:
        """Returns the game board formatted in a grid with colors."""
        fragments: StyleAndTextTuples = []

        def print_row(row: List[int], include_number: bool = False) -> None:
            fragments.append(('', '  '))
            for col in row:
                style = 'class:theme-fg-default '
                if col > 0:
                    style = '#000 '
                style += self.colors.get(col, '')
                text = ' ' * 6
                if include_number:
                    text = '{:^6}'.format(col)
                fragments.append((style, text))
            fragments.append(('', '\n'))

        fragments.append(('', '\n'))
        for row in self.board:
            print_row(row)
            print_row(row, include_number=True)
            print_row(row)

        return fragments

    def __repr__(self) -> str:
        board = ''
        for row_cells in self.board:
            for column in row_cells:
                board += '{:^6}'.format(column)
            board += '\n'
        return board

    def all_cells(self) -> Iterable[Twenty48Cell]:
        for row, row_cells in enumerate(self.board):
            for col, cell_value in enumerate(row_cells):
                yield (row, col, cell_value)

    def update_max_value(self) -> None:
        for _row, _col, value in self.all_cells():
            if value > self.max_value:
                self.max_value = value

    def empty_cells(self) -> Iterable[Twenty48Cell]:
        for row, row_cells in enumerate(self.board):
            for col, cell_value in enumerate(row_cells):
                if cell_value != 0:
                    continue
                yield (row, col, cell_value)

    def _board_changed(self) -> bool:
        return self.last_board != list(self.all_cells())

    def complete_move(self) -> None:
        if not self._board_changed():
            # Move did nothing, ignore.
            return

        self.update_max_value()
        self.move_count += 1
        self.add_random_tiles()
        self.last_board = list(self.all_cells())

    def add_random_tiles(self, count: int = 1) -> None:
        for _i in range(count):
            empty_cells = list(self.empty_cells())
            if not empty_cells:
                return
            row, col, _value = choice(empty_cells)
            self.board[row][col] = 2

    def row(self, row_index: int) -> Iterable[Twenty48Cell]:
        for col, cell_value in enumerate(self.board[row_index]):
            yield (row_index, col, cell_value)

    def col(self, col_index: int) -> Iterable[Twenty48Cell]:
        for row, row_cells in enumerate(self.board):
            for col, cell_value in enumerate(row_cells):
                if col == col_index:
                    yield (row, col, cell_value)

    def non_zero_row_values(self, index: int) -> Tuple[List, List]:
        non_zero_values = [
            value for row, col, value in self.row(index) if value != 0
        ]
        padding = [0] * (self.width - len(non_zero_values))
        return (non_zero_values, padding)

    def move_right(self) -> None:
        for i in range(self.height):
            non_zero_values, padding = self.non_zero_row_values(i)
            self.board[i] = padding + non_zero_values

    def move_left(self) -> None:
        for i in range(self.height):
            non_zero_values, padding = self.non_zero_row_values(i)
            self.board[i] = non_zero_values + padding

    def add_horizontal(self, reverse=False) -> None:
        for i in range(self.width):
            this_row = list(self.row(i))
            if reverse:
                this_row = list(reversed(this_row))
            for row, col, this_cell in this_row:
                if this_cell == 0 or col >= self.width - 1:
                    continue
                next_cell = self.board[row][col + 1]
                if this_cell == next_cell:
                    self.board[row][col] = 0
                    self.board[row][col + 1] = this_cell * 2
                    break

    def non_zero_col_values(self, index: int) -> Tuple[List, List]:
        non_zero_values = [
            value for row, col, value in self.col(index) if value != 0
        ]
        padding = [0] * (self.height - len(non_zero_values))
        return (non_zero_values, padding)

    def _set_column(self, col_index: int, values: List[int]) -> None:
        for row, value in enumerate(values):
            self.board[row][col_index] = value

    def add_vertical(self, reverse=False) -> None:
        for i in range(self.height):
            this_column = list(self.col(i))
            if reverse:
                this_column = list(reversed(this_column))
            for row, col, this_cell in this_column:
                if this_cell == 0 or row >= self.height - 1:
                    continue
                next_cell = self.board[row + 1][col]
                if this_cell == next_cell:
                    self.board[row][col] = 0
                    self.board[row + 1][col] = this_cell * 2
                    break

    def move_down(self) -> None:
        for col_index in range(self.width):
            non_zero_values, padding = self.non_zero_col_values(col_index)
            self._set_column(col_index, padding + non_zero_values)

    def move_up(self) -> None:
        for col_index in range(self.width):
            non_zero_values, padding = self.non_zero_col_values(col_index)
            self._set_column(col_index, non_zero_values + padding)

    def press_down(self) -> None:
        self.move_down()
        self.add_vertical(reverse=True)
        self.move_down()
        self.complete_move()

    def press_up(self) -> None:
        self.move_up()
        self.add_vertical()
        self.move_up()
        self.complete_move()

    def press_right(self) -> None:
        self.move_right()
        self.add_horizontal(reverse=True)
        self.move_right()
        self.complete_move()

    def press_left(self) -> None:
        self.move_left()
        self.add_horizontal()
        self.move_left()
        self.complete_move()


class Twenty48Control(FormattedTextControl):
    """Example prompt_toolkit UIControl for displaying formatted text.

    This is the prompt_toolkit class that is responsible for drawing the 2048,
    handling keybindings if in focus, and mouse input.
    """
    def __init__(self, twenty48_pane: 'Twenty48Pane', *args, **kwargs) -> None:
        self.twenty48_pane = twenty48_pane
        self.game = self.twenty48_pane.game

        # Set some custom key bindings to toggle the view mode and wrap lines.
        key_bindings = KeyBindings()

        @key_bindings.add('R')
        def _restart(_event: KeyPressEvent) -> None:
            """Restart the game."""
            self.game.reset_game()

        @key_bindings.add('q')
        def _quit(_event: KeyPressEvent) -> None:
            """Quit the game."""
            self.twenty48_pane.close_dialog()

        @key_bindings.add('j')
        @key_bindings.add('down')
        def _move_down(_event: KeyPressEvent) -> None:
            """Move down"""
            self.game.press_down()

        @key_bindings.add('k')
        @key_bindings.add('up')
        def _move_up(_event: KeyPressEvent) -> None:
            """Move up."""
            self.game.press_up()

        @key_bindings.add('h')
        @key_bindings.add('left')
        def _move_left(_event: KeyPressEvent) -> None:
            """Move left."""
            self.game.press_left()

        @key_bindings.add('l')
        @key_bindings.add('right')
        def _move_right(_event: KeyPressEvent) -> None:
            """Move right."""
            self.game.press_right()

        # Include the key_bindings keyword arg when passing to the parent class
        # __init__ function.
        kwargs['key_bindings'] = key_bindings
        # Call the parent FormattedTextControl.__init__
        super().__init__(*args, **kwargs)

    def mouse_handler(self, mouse_event: MouseEvent):
        """Mouse handler for this control."""
        # If the user clicks anywhere this function is run.

        # Mouse positions relative to this control. x is the column starting
        # from the left size as zero. y is the row starting with the top as
        # zero.
        _click_x = mouse_event.position.x
        _click_y = mouse_event.position.y

        # Mouse click behavior usually depends on if this window pane is in
        # focus. If not in focus, then focus on it when left clicking. If
        # already in focus then perform the action specific to this window.

        # If not in focus, change focus to this 2048 pane and do nothing else.
        if not has_focus(self.twenty48_pane)():
            if mouse_event.event_type == MouseEventType.MOUSE_UP:
                get_pw_console_app().focus_on_container(self.twenty48_pane)
                # Mouse event handled, return None.
                return None

        # If code reaches this point, this window is already in focus.
        # if mouse_event.event_type == MouseEventType.MOUSE_UP:
        #     # Toggle the view mode.
        #     self.twenty48_pane.toggle_view_mode()
        #     # Mouse event handled, return None.
        #     return None

        # Mouse event not handled, return NotImplemented.
        return NotImplemented


class Twenty48Pane(FloatingWindowPane, PluginMixin):
    """Example Pigweed Console plugin to play 2048.

    The Twenty48Pane is a WindowPane based plugin that displays an interactive
    game of 2048. It inherits from both WindowPane and PluginMixin. It can be
    added on console startup by calling: ::

        my_console.add_window_plugin(Twenty48Pane())

    For an example see:
    https://pigweed.dev/pw_console/embedding.html#adding-plugins
    """
    def __init__(self, include_resize_handle: bool = True, **kwargs):

        super().__init__(pane_title='2048',
                         height=Dimension(preferred=17),
                         width=Dimension(preferred=50),
                         **kwargs)
        self.game = Twenty48Game()

        # Hide by default.
        self.show_pane = False

        # Create a toolbar for display at the bottom of the 2048 window. It
        # will show the window title and buttons.
        self.bottom_toolbar = WindowPaneToolbar(
            self, include_resize_handle=include_resize_handle)

        # Add a button to restart the game.
        self.bottom_toolbar.add_button(
            ToolbarButton(
                key='R',  # Key binding help text for this function
                description='Restart',  # Button name
                # Function to run when clicked.
                mouse_handler=self.game.reset_game,
            ))
        # Add a button to restart the game.
        self.bottom_toolbar.add_button(
            ToolbarButton(
                key='q',  # Key binding help text for this function
                description='Quit',  # Button name
                # Function to run when clicked.
                mouse_handler=self.close_dialog,
            ))

        # Every FormattedTextControl object (Twenty48Control) needs to live
        # inside a prompt_toolkit Window() instance. Here is where you specify
        # alignment, style, and dimensions. See the prompt_toolkit docs for all
        # opitons:
        # https://python-prompt-toolkit.readthedocs.io/en/latest/pages/reference.html#prompt_toolkit.layout.Window
        self.twenty48_game_window = Window(
            # Set the content to a Twenty48Control instance.
            content=Twenty48Control(
                self,  # This Twenty48Pane class
                self.game,  # Content from Twenty48Game.__pt_formatted_text__()
                show_cursor=False,
                focusable=True,
            ),
            # Make content left aligned
            align=WindowAlign.LEFT,
            # These two set to false make this window fill all available space.
            dont_extend_width=True,
            dont_extend_height=False,
            wrap_lines=False,
            width=Dimension(preferred=28),
            height=Dimension(preferred=15),
        )

        self.twenty48_stats_window = Window(
            content=Twenty48Control(
                self,  # This Twenty48Pane class
                self.game.stats,  # Content from Twenty48Game.stats()
                show_cursor=False,
                focusable=True,
            ),
            # Make content left aligned
            align=WindowAlign.LEFT,
            # These two set to false make this window fill all available space.
            width=Dimension(preferred=20),
            dont_extend_width=False,
            dont_extend_height=False,
            wrap_lines=False,
        )

        # self.container is the root container that contains objects to be
        # rendered in the UI, one on top of the other.
        self.container = self._create_pane_container(
            pw_console.widgets.border.create_border(
                HSplit([
                    # Vertical split content
                    VSplit([
                        # Left side will show the game board.
                        self.twenty48_game_window,
                        # Stats will be shown on the right.
                        self.twenty48_stats_window,
                    ]),
                    # The bottom_toolbar is shown below the VSplit.
                    self.bottom_toolbar,
                ]),
                title='2048',
                border_style='class:command-runner-border',
                # left_margin_columns=1,
                # right_margin_columns=1,
            ))

        self.dialog_content: List[AnyContainer] = [
            # Vertical split content
            VSplit([
                # Left side will show the game board.
                self.twenty48_game_window,
                # Stats will be shown on the right.
                self.twenty48_stats_window,
            ]),
            # The bottom_toolbar is shown below the VSplit.
            self.bottom_toolbar,
        ]
        # Wrap the dialog content in a border
        self.bordered_dialog_content = pw_console.widgets.border.create_border(
            HSplit(self.dialog_content),
            title='2048',
            border_style='class:command-runner-border',
        )
        # self.container is the root container that contains objects to be
        # rendered in the UI, one on top of the other.
        if include_resize_handle:
            self.container = self._create_pane_container(*self.dialog_content)
        else:
            self.container = self._create_pane_container(
                self.bordered_dialog_content)

        # This plugin needs to run a task in the background periodically and
        # uses self.plugin_init() to set which function to run, and how often.
        # This is provided by PluginMixin. See the docs for more info:
        # https://pigweed.dev/pw_console/plugins.html#background-tasks
        self.plugin_init(
            plugin_callback=self._background_task,
            # Run self._background_task once per second.
            plugin_callback_frequency=1.0,
            plugin_logger_name='pw_console_example_2048_plugin',
        )

    def get_top_level_menus(self) -> List[MenuItem]:
        def _toggle_dialog() -> None:
            self.toggle_dialog()

        return [
            MenuItem(
                '[2048]',
                children=[
                    MenuItem('Example Top Level Menu',
                             handler=None,
                             disabled=True),
                    # Menu separator
                    MenuItem('-', None),
                    MenuItem('Show/Hide 2048 Game', handler=_toggle_dialog),
                    MenuItem('Restart', handler=self.game.reset_game),
                ],
            ),
        ]

    def pw_console_init(self, app: 'ConsoleApp') -> None:
        """Set the Pigweed Console application instance.

        This function is called after the Pigweed Console starts up and allows
        access to the user preferences. Prefs is required for creating new
        user-remappable keybinds."""
        self.application = app

    def _background_task(self) -> bool:
        """Function run in the background for the ClockPane plugin."""
        # Optional: make a log message for debugging purposes. For more info
        # see:
        # https://pigweed.dev/pw_console/plugins.html#debugging-plugin-behavior
        # self.plugin_logger.debug('background_task_update_count: %s',
        #                          self.background_task_update_count)

        # Returning True in the background task will force the user interface to
        # re-draw.
        # Returning False means no updates required.

        if self.show_pane:
            # Return true so the game clock is updated.
            return True

        # Game window is hidden, don't redraw.
        return False
