from typing import Callable
from textual import on
from textual.app import ComposeResult
from textual.screen import ModalScreen
from textual.widgets import Footer, Button, Input, Static
from textual.containers import Container, Vertical, Horizontal
from textual.validation import Function


class CreateEditScreen(ModalScreen[str | None]):

    CSS_PATH = "screen_styles.tcss"

    BINDINGS = [
        ("escape", "dismiss")
    ]

    def __init__(self, check_title: Callable[[str], bool], screen_title: str) -> None:
        super().__init__()
        self.check_title = check_title
        self.screen_title = screen_title

    def compose(self) -> ComposeResult:
        yield Footer()
        with Vertical(id="dialog") as dialog_container:
            with Vertical():
                yield Input(
                    id="quiz_title",
                    placeholder="Название",
                    compact=True,
                    validators=[Function(
                        self.check_title, "Тест уже существует"
                    ),
                        Function(
                        self._check_empty, "Длина должна быть более 5 символов"
                    )]
                )
                yield Static(id="validation_result")
            with Horizontal(id="button-container"):
                yield Button("Создать", id="create_button", variant='success', compact=True)
                yield Container(classes="separator")
                yield Button("Отмена", id="close_button", variant="primary", compact=True)

        dialog_container.border_title = self.screen_title

    @on(Button.Pressed, "#create_button")
    def create_button_click(self):
        text_field = self.query_one("#quiz_title", Input)
        self.dismiss(text_field.value)

    @on(Button.Pressed, "#close_button")
    def close_button_click(self):
        self.dismiss(None)

    @on(Input.Changed)
    def show_validation_message(self, event: Input.Changed):
        assert event.validation_result is not None
        if not event.validation_result.is_valid:
            failure_descr = next(
                iter(event.validation_result.failure_descriptions), ""
            )
            self.query_one(Static).update(failure_descr)
            self.query_one("#create_button").disabled = True
        else:
            self.query_one(Static).update("")
            self.query_one("#create_button").disabled = False

    def _check_empty(self, value: str) -> bool:
        return len(value) > 5


def push_create_edit_screen(
        dismiss_callback: Callable[[str | None], None],
        screen_title: str,
        check_title: Callable[[str], bool],
) -> None:
    # pylint: disable=import-outside-toplevel
    from analyst_klondike.ui.runner_app import get_app
    app = get_app()
    app.push_screen(
        CreateEditScreen(
            check_title,
            screen_title
        ), dismiss_callback
    )
