from pathlib import Path
from typing import Iterator

from textual.binding import Binding
from textual.containers import Grid
from textual.screen import ModalScreen
from textual.widget import Widget
from textual.widgets import Button, Label

from azure_explorer.config import Config
from azure_explorer.managers import ContainerManager
from azure_explorer.widgets.components.windows import Browser

READ_FILE_CODE_SNIPPET = """
import azure_explorer as ax

data = ax.read_file(
    storage_account_name="{self.container_manager.storage_account_name}",
    container_name="{self.container_manager.container_name}",
    path="{path}",
)
"""


class DeleteConfirmScreen(ModalScreen[bool]):
    """Screen with a dialog to quit."""

    CSS = """
    DeleteConfirmScreen {
        align: center middle;
    }

    #dialog {
        grid-size: 2;
        grid-gutter: 1 2;
        grid-rows: 1fr 3;
        padding: 0 1;
        width: 60;
        height: 11;
        border: thick $background 80%;
        background: $surface;
    }

    #question {
        column-span: 2;
        height: 1fr;
        width: 1fr;
        content-align: center middle;
    }

    Button {
        width: 100%;
    }
    """

    def __init__(self, path: str):
        super().__init__()
        self.path = path

    def compose(self):
        yield Grid(
            Label(f"Are you sure you want to delete '{self.path}'?", id="question"),
            Button("Yes", variant="error", id="yes"),
            Button("No", variant="primary", id="no"),
            id="dialog",
        )

    def on_button_pressed(self, event: Button.Pressed) -> None:
        if event.button.id == "yes":
            self.dismiss(True)
        else:
            self.dismiss(False)


class BlobFolderBrowser(Browser):
    COLUMN_NAMES = ["Name", "Size (MB)", "Last Modified", "Created Time"]
    LABEL_COLUMN = "Name"

    BINDINGS = [
        Binding("ctrl+s", "download", "Download", show=True, priority=True),
        Binding("ctrl+c", "copy_code", "Copy code", show=True, priority=True),
        Binding("ctrl+d", "delete", "Delete", show=True, priority=True),
    ]

    def __init__(self, container_manager: ContainerManager, folder: str = ""):
        self.container_manager = container_manager
        self.folder = folder
        super().__init__()

    def check_action(self, action: str, parameters: tuple[object, ...]) -> bool | None:
        """Check if an action may run."""
        id_ = self.get_highlighted_id()

        path = f"{self.folder}/{id_}" if self.folder else id_

        if action == "copy_code":
            if not self.container_manager.is_file(path):
                return None

        if action in ["download", "delete"]:
            if not (
                self.container_manager.is_dir(path)
                or self.container_manager.is_file(path)
            ):
                return None
        return super().check_action(action, parameters)

    def action_download(self):
        id_ = self.get_highlighted_id()

        path = f"{self.folder}/{id_}" if self.folder else id_

        download_folder = Path.cwd() / ".downloads" / path

        if self.container_manager.is_dir(path):
            self.container_manager.download_dir(path, download_folder)
        else:
            self.container_manager.download_file(path, download_folder)

    def action_copy_code(self):
        id_ = self.get_highlighted_id()

        path = f"{self.folder}/{id_}" if self.folder else id_

        code_snippet = READ_FILE_CODE_SNIPPET.format(
            self=self,
            path=path,
        )
        self.app.copy_to_clipboard(code_snippet)
        self.notify("Code snippet copied to clipboard!", severity="info", timeout=3)

    def action_delete(self):

        id_ = self.get_highlighted_id()

        path = f"{self.folder}/{id_}" if self.folder else id_

        def on_confirm(confirm: bool):
            if not confirm:
                return

            if self.container_manager.is_dir(path):
                self.container_manager.delete_dir(path)
            else:
                self.container_manager.delete_file(path)

            self.action_refresh()

        self.app.push_screen(screen=DeleteConfirmScreen(path), callback=on_confirm)

    def iter_rows(self) -> Iterator[tuple[str, tuple]]:
        if not self.container_manager.is_dir(self.folder):
            # the folder might be changed during navigation, so we need to
            # check if it exists before iterating
            self.notify(f"Folder '{self.folder}' not found", severity="error")
            return

        for subitem in self.container_manager.iter_dir(self.folder):
            if self.container_manager.is_dir(subitem.path):
                icon = "📁"
            else:
                icon = "📄"

            if subitem.path.endswith("/"):
                base_name = subitem.path
            else:
                base_name = subitem.path.split("/")[-1]

            if subitem.last_modified_time:
                last_modified_time_local = subitem.last_modified_time.astimezone(
                    Config.time_zone
                )
            else:
                last_modified_time_local = "-"

            if subitem.created_time:
                created_time_local = subitem.created_time.astimezone(Config.time_zone)
            else:
                created_time_local = "-"

            if subitem.size:
                size_MB = round(subitem.size / (1024 * 1024), 2)
            else:
                size_MB = "-"

            yield base_name, (
                f"{icon} {base_name}",
                size_MB,
                last_modified_time_local,
                created_time_local,
            )

    def get_widget(self, id_: str) -> Widget:
        path = f"{self.folder.rstrip('/')}/{id_}" if self.folder else id_

        if not self.container_manager.is_dir(path):
            return

        return BlobFolderBrowser(
            self.container_manager,
            path,
        )
