"""Table of PyGitWeb projects under PROJECTROOT."""

from __future__ import annotations

from pyratatui import Constraint, Direction, Frame, Layout, List, ListItem, ListState, Paragraph, Rect

from pygittools.tui.git_colors import current_theme, focus_style
from pygittools.tui.keys import KeyLike, is_down, is_enter, is_esc, is_quit, is_up, move_hint
from pygittools.tui.projects import ProjectEntry, list_projects
from pygittools.tui.pygitweb_layout import load_pygitweb_layout
from pygittools.tui.types import PageAction, PageContext, PageResult

_BRANCH_WIDTH = 16


class ProjectsPage:
    title = "projects"

    def __init__(self) -> None:
        self._projects: list[ProjectEntry] = []
        self._projectroot_label = ""
        self._list_state = ListState()
        self._error: str | None = None

    def on_enter(self, ctx: PageContext) -> None:
        del ctx
        layout = load_pygitweb_layout()
        self._projectroot_label = str(layout.projectroot)
        self._projects = list_projects(layout)
        self._list_state.select(0)
        self._error = None

    def status_text(self) -> str:
        if self._error:
            return self._error
        if not self._projects:
            return "No projects found — Esc back"
        return f"Enter open project — {move_hint()} — Esc back"

    def draw(self, frame: Frame, area: Rect) -> None:
        if area.height <= 0:
            return
        theme = current_theme()
        chunks = (
            Layout()
            .direction(Direction.Vertical)
            .constraints([Constraint.length(1), Constraint.length(1), Constraint.fill(1)])
            .split(area)
        )
        title = f"Projects ({self._projectroot_label})"
        frame.render_widget(Paragraph.from_string(title).style(theme.header), chunks[0])
        name_width = max(8, chunks[1].width - _BRANCH_WIDTH - 2)
        header = f"{'Name':<{name_width}}  {'Branch':<{_BRANCH_WIDTH}}"
        frame.render_widget(Paragraph.from_string(header).style(theme.header), chunks[1])

        items: list[ListItem] = []
        selected = self._list_state.selected or 0
        for index, project in enumerate(self._projects):
            name = project.path
            if len(name) > name_width:
                name = name[: max(0, name_width - 1)] + "…"
            branch = project.branch
            if len(branch) > _BRANCH_WIDTH:
                branch = branch[: max(0, _BRANCH_WIDTH - 1)] + "…"
            line = f"{name:<{name_width}}  {branch:<{_BRANCH_WIDTH}}"
            style = focus_style(theme.normal) if index == selected else theme.normal
            items.append(ListItem(line, style))
        if not items:
            items.append(ListItem("No projects", theme.log_date))
        frame.render_stateful_list(
            List(items).highlight_style(theme.focus).highlight_symbol(""),
            chunks[2],
            self._list_state,
        )

    def handle_key(self, key: KeyLike) -> PageResult:
        if is_quit(key) or is_esc(key):
            return PageResult(action=PageAction.POP)
        if self._error is not None:
            self._error = None
        if not self._projects:
            return PageResult()

        if is_up(key):
            selected = self._list_state.selected or 0
            self._list_state.select(max(0, selected - 1))
            return PageResult()
        if is_down(key):
            selected = self._list_state.selected or 0
            self._list_state.select(min(len(self._projects) - 1, selected + 1))
            return PageResult()
        if is_enter(key):
            project = self._projects[self._list_state.selected or 0]
            return PageResult(action=PageAction.POP, switch_repo=project.worktree)
        return PageResult()


def projects_page() -> ProjectsPage:
    return ProjectsPage()