"""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()