from __future__ import annotations

import platform
import tkinter as tk
import typing

from biscuit.common import Menu
from biscuit.common.ui import Frame, IconButton

from .item import MenubarItem
from .searchbar import SearchBar

if typing.TYPE_CHECKING:
    ...


class Menubar(Frame):
    """Menubar of the application

    - Contains the MenubarItems
    - Manages the MenubarItems
    """

    def __init__(self, master: Frame, *args, **kwargs) -> None:
        super().__init__(master, *args, **kwargs)
        self.menus: list[MenubarItem] = []
        self.events = self.base.commands

        # structure of the menubar

        # |---left container---|---searchbar---|---right container---|

        self.container = Frame(self, **self.base.theme.layout.menubar)
        self.container.pack(side=tk.LEFT, fill=tk.BOTH)

        self.searchbar = SearchBar(self)
        self.searchbar.place(relx=0.5, rely=0.5, anchor=tk.CENTER)

        self.container_right = Frame(self, **self.base.theme.layout.menubar)
        self.container_right.pack(side=tk.RIGHT, fill=tk.BOTH)

        # make this custom titlebar for windows
        if platform.system() == "Windows":
            close = IconButton(
                self.container_right,
                icon="chrome-close",
                iconsize=12,
                padx=15,
                pady=8,
                event=self.events.quit_biscuit,
            )
            close.config(activebackground="#e81123", activeforeground="white")
            close.pack(side=tk.RIGHT, fill=tk.Y, padx=0)

            IconButton(
                self.container_right,
                icon="chrome-maximize",
                iconsize=12,
                icon2="chrome-restore",
                padx=15,
                pady=8,
                event=self.events.maximize_biscuit,
            ).pack(side=tk.RIGHT, fill=tk.Y, padx=0)
            IconButton(
                self.container_right,
                icon="chrome-minimize",
                iconsize=12,
                padx=15,
                pady=8,
                event=self.events.minimize_biscuit,
            ).pack(side=tk.RIGHT, fill=tk.Y, padx=0)
            self.config_bindings()

        self.update_idletasks()

        self.config(**self.base.theme.layout.menubar)
        self.add_menus()

    def change_title(self, title: str) -> None:
        """Change the title of the searchbar

        Args:
            title (str): Title of the searchbar"""

        self.searchbar.label.change_text(title)

    def config_bindings(self) -> None:
        self.bind("<Map>", self.events.window_mapped)
        self.bind("<Button-1>", self.start_move)
        self.bind("<ButtonRelease-1>", self.stop_move)
        self.bind("<B1-Motion>", self.moving)

    def start_move(self, event) -> None:
        self.x = event.x
        self.y = event.y

    def stop_move(self, _) -> None:
        self.x = None
        self.y = None

    def moving(self, event: tk.Event) -> None:
        x = event.x_root - self.x
        y = event.y_root - self.y
        self.base.geometry(f"+{x}+{y}")

    def add_menu(self, text: str) -> Menu:
        """Add a new menu to the menubar

        Args:
            text (str): Text of the menu"""

        new_menu = MenubarItem(self, text)
        new_menu.pack(side=tk.LEFT, fill=tk.BOTH, in_=self.container)
        self.menus.append(new_menu)

        return new_menu.menu

    def add_menus(self) -> None:
        self.add_file_menu()
        self.add_edit_menu()
        self.add_selection_menu()
        self.add_view_menu()
        self.add_go_menu()
        self.add_help_menu()

    def add_file_menu(self) -> None:
        events = self.events

        self.file_menu = self.add_menu("File")
        self.file_menu.add_command("New File", events.new_file)
        self.file_menu.add_command("New Window", events.new_window)
        self.file_menu.add_separator()
        self.file_menu.add_command("Open File", events.open_file)
        self.file_menu.add_command("Open Folder", events.open_directory)
        self.file_menu.add_command("Open Recent File...", events.open_recent_file)
        self.file_menu.add_command("Open Recent Folder...", events.open_recent_dir)
        self.file_menu.add_separator()
        self.file_menu.add_command("Save", events.save_file)
        self.file_menu.add_command("Save As...", events.save_file_as)
        self.file_menu.add_command("Save All", events.save_all)
        self.file_menu.add_separator()
        self.file_menu.add_command("Preferences", events.open_settings)
        self.file_menu.add_separator()
        self.file_menu.add_command("Close Editor", events.close_editor)
        self.file_menu.add_command("Close Folder", events.close_folder)
        self.file_menu.add_command("Close Window", events.quit_biscuit)
        self.file_menu.add_separator()
        self.file_menu.add_command("Exit", events.quit_biscuit)

    def add_edit_menu(self) -> None:
        events = self.events

        self.edit_menu = self.add_menu("Edit")
        self.edit_menu.add_command("Undo", events.undo)
        self.edit_menu.add_command("Redo", events.redo)
        self.edit_menu.add_separator()
        self.edit_menu.add_command("Cut", events.cut)
        self.edit_menu.add_command("Copy", events.copy)
        self.edit_menu.add_command("Paste", events.paste)
        self.edit_menu.add_separator()
        self.edit_menu.add_command("Find", events.find_symbol)
        self.edit_menu.add_command("Replace", events.replace_symbol)
        self.edit_menu.add_command("Find in Files", events.search_files)
        self.edit_menu.add_command("Change Language Mode", events.change_language_mode)
        self.edit_menu.add_separator()
        self.edit_menu.add_checkable("Word Wrap", events.toggle_wordwrap)
        self.edit_menu.add_checkable("Block Cursor", events.toggle_block_cursor)

    def add_selection_menu(self) -> None:
        events = self.events

        self.selection_menu = self.add_menu("Selection")
        self.selection_menu.add_command("Select All", events.select_all)
        self.selection_menu.add_command("Select Line", events.select_line)
        self.selection_menu.add_command("Delete Line", events.delete_line)
        self.selection_menu.add_separator()
        self.selection_menu.add_command("Copy Line Up", events.copy_line_up)
        self.selection_menu.add_command("Copy Line Down", events.copy_line_down)
        self.selection_menu.add_command("Move Line Up", events.move_line_up)
        self.selection_menu.add_command("Move Line Down", events.move_line_down)
        self.selection_menu.add_command(
            "Duplicate Selection", events.duplicate_selection
        )

    def add_view_menu(self) -> None:
        events = self.events

        self.view_menu = self.add_menu("View")
        self.view_menu.add_command("Command Palette...", events.show_command_palette)
        self.view_menu.add_command("Explorer", events.show_explorer)
        self.view_menu.add_command("Outline", events.show_outline)
        self.view_menu.add_command("Search", events.show_search)
        self.view_menu.add_command("Source Control", events.show_source_control)
        self.view_menu.add_command("Extensions", events.show_extensions)
        self.view_menu.add_separator()
        self.view_menu.add_command("Terminal", events.show_terminal)
        self.view_menu.add_command("Log", events.show_logs)

    def add_go_menu(self) -> None:
        events = self.events

        self.view_menu = self.add_menu("Go")
        self.view_menu.add_command("Go to File...", events.search_files)
        self.view_menu.add_separator()
        self.view_menu.add_command("Go to Symbol in Editor", events.show_symbol_palette)
        self.view_menu.add_command("Go to Definition", events.go_to_symbol_definition)
        self.view_menu.add_command("Go to References", events.find_symbol_references)
        self.view_menu.add_separator()
        self.view_menu.add_command("Go to Line/Column...", events.goto_line_column)

    def add_help_menu(self) -> None:
        events = self.events

        self.help_menu = self.add_menu("Help")
        self.help_menu.add_command("Welcome", events.show_welcome)
        self.help_menu.add_command("Show All Commands", events.show_command_palette)
        self.help_menu.add_command("Documentation", events.open_biscuit_documentation)
        self.help_menu.add_command(
            "Show Release Notes", events.open_biscuit_release_notes
        )
        self.help_menu.add_separator()
        self.help_menu.add_command("Report Bug", events.report_bug)
        self.help_menu.add_command("Request Feature", events.request_feature)
        self.help_menu.add_separator()
        self.help_menu.add_command("View License", events.view_biscuit_licenses)
        self.help_menu.add_command(
            "Code of Conduct", events.open_biscuit_code_of_conduct
        )
        self.help_menu.add_separator()
        self.help_menu.add_command("About", events.show_about)

    def close_all_menus(self, *_) -> None:
        for btn in self.menus:
            btn.menu.hide()

    def switch_menu(self, item: MenubarItem) -> None:
        active = False
        for i in self.menus:
            if i.menu.active:
                active = True
            if i.menu != item.menu:
                i.menu.hide()
                i.deselect()

        if active:
            item.select()
            item.menu.show()

    def pack(self):
        super().pack(fill=tk.BOTH)
