"""Form to add a new git worktree."""

from __future__ import annotations

from pathlib import Path
from typing import Literal

from pyratatui import (
	Constraint,
	Direction,
	Frame,
	Layout,
	Paragraph,
	Rect,
	TextPrompt,
	TextState,
)

from pygittools.tui.git_colors import current_theme
from pygittools.tui.git_worktrees import add_worktree
from pygittools.tui.keys import KeyLike, is_down, is_enter, is_esc, is_quit, is_up, move_hint
from pygittools.tui.types import PageAction, PageContext, PageResult

_Field = Literal["path", "branch"]


class WorktreeAddPage:
	title = "worktree-add"

	def __init__(self) -> None:
		self._ctx: PageContext | None = None
		self._path_state = TextState()
		self._branch_state = TextState()
		self._field: _Field = "path"
		self._error: str | None = None

	def on_enter(self, ctx: PageContext) -> None:
		self._ctx = ctx
		self._path_state.set_value("")
		self._branch_state.set_value("")
		self._field = "path"
		self._error = None
		self._path_state.focus()
		self._branch_state.blur()

	def status_text(self) -> str:
		if self._error:
			return self._error
		return f"Enter submit — {move_hint()} switch field — 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.length(1),
				Constraint.fill(1),
			])
			.split(area)
		)
		frame.render_widget(Paragraph.from_string("Add worktree").style(theme.header), chunks[0])
		self._sync_focus()
		frame.render_text_prompt(TextPrompt("Path: "), chunks[1], self._path_state)
		frame.render_text_prompt(
			TextPrompt("Branch (new or existing, empty = detached): "),
			chunks[2],
			self._branch_state,
		)
		hint = "Path is relative to the current worktree unless absolute."
		frame.render_widget(Paragraph.from_string(hint).style(theme.log_date), chunks[3])

	def handle_key(self, key: KeyLike) -> PageResult:
		if is_esc(key) or is_quit(key):
			return PageResult(action=PageAction.POP)
		if self._error is not None:
			self._error = None
		ctx = self._ctx
		if ctx is None:
			return PageResult()
		if is_up(key):
			self._field = "path"
			return PageResult()
		if is_down(key):
			self._field = "branch"
			return PageResult()
		if is_enter(key):
			return self._submit(ctx)
		state = self._path_state if self._field == "path" else self._branch_state
		state.focus()
		state.handle_key(key)
		return PageResult()

	def _sync_focus(self) -> None:
		if self._field == "path":
			self._path_state.focus()
			self._branch_state.blur()
		else:
			self._branch_state.focus()
			self._path_state.blur()

	def _submit(self, ctx: PageContext) -> PageResult:
		raw_path = self._path_state.value().strip()
		if not raw_path:
			self._error = "Path is required"
			return PageResult()
		branch = self._branch_state.value().strip() or None
		ok, error = add_worktree(ctx.repo, Path(raw_path), branch)
		if ok:
			return PageResult(action=PageAction.POP, repo_changed=True)
		self._error = error
		return PageResult()


def worktree_add_page() -> WorktreeAddPage:
	return WorktreeAddPage()