from textual import on
from textual.app import ComposeResult
from textual.widgets import Markdown, TextArea
from textual.containers import Vertical, VerticalScroll
from textual.reactive import var

from analyst_klondike.features.current.selectors import select_current_task
from analyst_klondike.features.teacher.edit_task import ToggleTaskEditMode, UpdateCurrentTaskText
from analyst_klondike.state.app_dispatch import app_dispatch
from analyst_klondike.state.app_state import INITIAL_STATE, AppState, select
from analyst_klondike.features.current.actions import MakeTaskCurrentAction
from analyst_klondike.features.helpers import for_actions


class CurrentTaskInfo(Vertical):

    DEFAULT_CSS = """
        CurrentTaskInfo {
            border: solid $primary;
            background: $background;
            height: 1fr;
            padding: 0;
        }

        #task_editor {
            background: $background;
        }

        .hidden {
            display: none;
        }
    """

    state = var(INITIAL_STATE, init=False)

    def on_mount(self) -> None:
        self.border_title = "Задача"

    def compose(self) -> ComposeResult:
        with VerticalScroll():
            yield Markdown(id="task_viewer")
            yield TextArea(id="task_editor", classes="hidden", text="edit")

    @for_actions(MakeTaskCurrentAction, ToggleTaskEditMode)
    def watch_state(self, _: AppState) -> None:
        curr_task = select(select_current_task)
        if curr_task is None:
            return
        viewer = self.query_one("#task_viewer", Markdown)
        editor = self.query_one("#task_editor", TextArea)

        if curr_task.is_edited:
            viewer.add_class('hidden')
            editor.remove_class('hidden')
        else:
            viewer.remove_class('hidden')
            editor.add_class('hidden')

        if curr_task.is_edited:
            with editor.prevent(TextArea.Changed):
                editor.text = curr_task.description
        else:
            viewer.update(curr_task.description)

    @on(TextArea.Changed)
    def on_textarea_changed(self, event: TextArea.Changed) -> None:
        new_text = event.text_area.text
        app_dispatch(UpdateCurrentTaskText(new_text))
