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

from __future__ import annotations

from pygittools.tui.ucurses import (  # type: ignore[import-untyped]
	A_BOLD,
	A_REVERSE,
	KEY_DOWN,
	KEY_ENTER,
	KEY_RESIZE,
	KEY_UP,
)

from pygittools.tui.draw import draw_line
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
_TABLE_TOP = 2


class ProjectsPage:
	title = "projects"

	def __init__(self) -> None:
		self._projects: list[ProjectEntry] = []
		self._projectroot_label = ""
		self._cursor = 0
		self._scroll_offset = 0
		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._cursor = 0
		self._scroll_offset = 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 "Enter open project — j/k move — Esc back"

	def draw(self, stdscr: int, height: int, width: int) -> None:
		del stdscr
		if height <= 0:
			return
		title = f"Projects ({self._projectroot_label})"
		draw_line(0, 0, title[:width], width, A_BOLD)
		name_width = max(8, width - _BRANCH_WIDTH - 2)
		header = f"{'Name':<{name_width}}  {'Branch':<{_BRANCH_WIDTH}}"
		draw_line(1, 0, header[:width], width, A_BOLD)

		list_height = height - _TABLE_TOP
		if list_height <= 0:
			return
		self._ensure_cursor_visible(list_height)
		for view_row in range(list_height):
			index = self._scroll_offset + view_row
			if index >= len(self._projects):
				break
			project = self._projects[index]
			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}}"
			attr = A_REVERSE if index == self._cursor else 0
			draw_line(_TABLE_TOP + view_row, 0, line[:width], width, attr)

	def handle_key(self, key: int) -> PageResult:
		if key in (ord("q"), ord("Q"), 27):
			return PageResult(action=PageAction.POP)
		if key == KEY_RESIZE:
			return PageResult()
		if self._error is not None:
			self._error = None
		if not self._projects:
			return PageResult()

		if key in (KEY_UP, ord("k"), ord("K")):
			self._cursor = max(0, self._cursor - 1)
			return PageResult()
		if key in (KEY_DOWN, ord("j"), ord("J")):
			self._cursor = min(len(self._projects) - 1, self._cursor + 1)
			return PageResult()
		if key in (KEY_ENTER, 10, 13):
			project = self._projects[self._cursor]
			return PageResult(action=PageAction.POP, switch_repo=project.worktree)
		return PageResult()

	def _ensure_cursor_visible(self, list_height: int) -> None:
		if self._cursor < self._scroll_offset:
			self._scroll_offset = self._cursor
		elif self._cursor >= self._scroll_offset + list_height:
			self._scroll_offset = self._cursor - list_height + 1


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