"""TypewriterEditor widget with typewriter constraints."""

from textual.widgets import TextArea
from textual.events import Key
from textual.reactive import reactive

from ..utils.strikethrough import strike_character_at


class TypewriterEditor(TextArea):
    """A text editor with typewriter constraints.

    Features:
    - No backspace/delete (forward-only writing)
    - Overtype mode (typing replaces existing text)
    - Free cursor navigation with arrow keys
    - Strikethrough with Ctrl+X
    """

    has_unsaved_changes = reactive(False)

    def __init__(self, *args, **kwargs):
        """Initialize the typewriter editor."""
        super().__init__(*args, **kwargs)
        self.show_line_numbers = False

    def _on_key(self, event: Key) -> None:
        """Handle key events with typewriter constraints."""
        # Block backspace and delete keys
        if event.key in ("backspace", "delete"):
            event.prevent_default()
            event.stop()
            return

        # Handle printable characters with overtype mode
        if event.character and event.character.isprintable():
            self._handle_character_input(event)
            return

        # All other keys (arrows, home, end, etc.) pass through
        super()._on_key(event)

    def _handle_character_input(self, event: Key) -> None:
        """Handle character input with overtype mode."""
        # Get current cursor position
        cursor = self.cursor_location

        # Get current text
        current_text = self.text

        # Check if we're at the end or in the middle
        # Note: cursor_location is a tuple (row, col)
        row, col = cursor

        lines = current_text.split('\n')

        if row >= len(lines):
            # At end of document, normal insert
            super()._on_key(event)
            self.has_unsaved_changes = True
            return

        current_line = lines[row]

        if col >= len(current_line):
            # At end of line, normal insert
            super()._on_key(event)
            self.has_unsaved_changes = True
            return

        # Overtype mode: replace character at cursor
        # Build new line with character replaced
        new_line = current_line[:col] + event.character + current_line[col + 1:]
        lines[row] = new_line

        # Update text
        new_text = '\n'.join(lines)
        self.text = new_text

        # Move cursor forward
        self.cursor_location = (row, col + 1)

        self.has_unsaved_changes = True
        event.prevent_default()
        event.stop()

    def _apply_strikethrough(self) -> None:
        """Apply strikethrough to character at cursor, then move to next char."""
        cursor = self.cursor_location
        row, col = cursor

        current_text = self.text
        lines = current_text.split('\n')

        if row >= len(lines):
            return

        current_line = lines[row]

        if col >= len(current_line):
            return

        # Strike through character at cursor
        new_line = strike_character_at(current_line, col)
        lines[row] = new_line

        # Update text
        new_text = '\n'.join(lines)
        self.text = new_text

        # Move cursor forward by 2 (character + combining char)
        # This positions us at the next character to strike
        self.cursor_location = (row, col + 2)

        self.has_unsaved_changes = True

    def load_content(self, content: str) -> None:
        """Load content into editor."""
        self.text = content
        self.has_unsaved_changes = False
        # Move cursor to end
        lines = content.split('\n')
        last_row = len(lines) - 1
        last_col = len(lines[last_row]) if lines else 0
        self.cursor_location = (last_row, last_col)
        self.focus()

    def clear_content(self) -> None:
        """Clear editor content."""
        self.text = ""
        self.has_unsaved_changes = False
        self.cursor_location = (0, 0)
