"""ExecutionScreen - Active execution mode screen.

Contract: CNT-TUI-SCR-002
Traceability: UX-001, UI-002
"""

from pathlib import Path
from typing import Any

from textual.app import ComposeResult
from textual.binding import Binding
from textual.containers import Vertical
from textual.screen import Screen
from textual.widgets import Footer, Header, Static

from laida_cli.adapters.claude_code_adapter import ClaudeCodeSubprocessAdapter
from laida_cli.ports.claude_code_port import ClaudeCodeAuthError
from laida_cli.services.execute_phase import ExecutePhaseService
from laida_cli.tui.services.telemetry_service import TelemetryService
from laida_cli.tui.widgets.live_feed import LiveFeedWidget
from laida_cli.tui.widgets.telemetry_bar import TelemetryBar


class ExecutionHeader(Static):
    """Header showing current execution info."""

    DEFAULT_CSS = """
    ExecutionHeader {
        dock: top;
        height: 3;
        background: #1e1b4b;
        padding: 0 2;
        border-bottom: solid #8b5cf6;
    }
    """

    def __init__(self, phase: int, step: int, step_name: str, **kwargs: Any) -> None:
        super().__init__(**kwargs)
        self._phase = phase
        self._step = step
        self._step_name = step_name

    def render(self) -> str:
        return (
            f"[bold #a78bfa]▶ EXECUTING[/]\n"
            f"[#5eead4]Phase {self._phase} Step {self._step}[/] "
            f"[#64748b]({self._step_name})[/]"
        )


class ExecutionScreen(Screen[bool]):
    """Screen displayed during phase/step execution.

    This screen takes over the UI during execution, showing:
    - Execution header with phase/step info
    - Full-screen live feed
    - Telemetry bar

    Returns True on success, False on failure when dismissed.
    """

    DEFAULT_CSS = """
    ExecutionScreen {
        background: #0f0a1a;
    }

    #execution-content {
        height: 1fr;
        padding: 0;
    }

    ExecutionScreen LiveFeedWidget {
        height: 1fr;
        margin: 1;
    }
    """

    BINDINGS = [
        Binding("escape", "cancel", "Cancel", show=True),
        Binding("enter", "dismiss_result", "Continue", show=False),
    ]

    def __init__(
        self,
        project_path: Path,
        phase: int,
        step: int,
        step_name: str,
        telemetry_service: TelemetryService | None = None,
        **kwargs: Any,
    ) -> None:
        """Initialize the execution screen.

        Args:
            project_path: Path to LAIDA project
            phase: Phase number to execute
            step: Step number to execute
            step_name: Human-readable step name
            telemetry_service: Shared telemetry service
            **kwargs: Additional screen arguments
        """
        super().__init__(**kwargs)
        self._project_path = project_path
        self._phase = phase
        self._step = step
        self._step_name = step_name
        self._telemetry_service = telemetry_service or TelemetryService()
        self._success: bool = False
        self._is_running: bool = False
        self._live_feed: LiveFeedWidget | None = None

    def compose(self) -> ComposeResult:
        """Compose the execution screen layout."""
        yield Header()
        yield ExecutionHeader(self._phase, self._step, self._step_name)

        with Vertical(id="execution-content"):
            self._live_feed = LiveFeedWidget()
            yield self._live_feed

        yield TelemetryBar(telemetry_service=self._telemetry_service)
        yield Footer()

    def on_mount(self) -> None:
        """Start execution when screen mounts."""
        self.run_worker(self._execute(), exclusive=True)

    async def _execute(self) -> None:
        """Execute the phase/step asynchronously."""
        self._is_running = True
        self._telemetry_service.start_task()

        if self._live_feed:
            self._live_feed.start_execution(self._phase, self._step)

        try:
            # Create adapter and service
            adapter = ClaudeCodeSubprocessAdapter()
            service = ExecutePhaseService(adapter)

            # Execute with streaming
            result = service.execute_streaming(
                phase=self._phase,
                step=self._step,
                project_path=str(self._project_path),
                on_output=self._handle_output,
            )

            self._success = result.success
            self._telemetry_service.end_task(
                success=result.success,
                phase=self._phase,
                step=self._step,
            )

            if self._live_feed:
                self._live_feed.end_execution(result.success)

            # Update border color based on result
            if result.success:
                self.styles.border = ("solid", "#10b981")  # Green
            else:
                self.styles.border = ("solid", "#f87171")  # Red

        except ClaudeCodeAuthError:
            self._success = False
            self._telemetry_service.reset_task()
            if self._live_feed:
                self._live_feed.write(
                    "\n[bold #f87171]Authentication Error[/]\n"
                    "[#64748b]Run 'laida login' to authenticate[/]"
                )

        except Exception as e:
            self._success = False
            self._telemetry_service.reset_task()
            if self._live_feed:
                self._live_feed.write(f"\n[bold #f87171]Error: {e}[/]")

        finally:
            self._is_running = False
            # Enable the dismiss binding
            self.set_focus(None)
            self.notify(
                "Press Enter to continue" if self._success else "Press Enter to return",
                timeout=5,
            )

    def _handle_output(self, line: str) -> None:
        """Handle streaming output from execution.

        Args:
            line: Output line from Claude Code
        """
        if self._live_feed:
            self._live_feed.append_line(line)

    def action_cancel(self) -> None:
        """Cancel execution (if possible) and return."""
        if not self._is_running:
            self.dismiss(self._success)
        else:
            self.notify("Execution in progress, please wait...", timeout=2)

    def action_dismiss_result(self) -> None:
        """Dismiss screen with result."""
        if not self._is_running:
            self.dismiss(self._success)

    @property
    def is_running(self) -> bool:
        """Check if execution is in progress."""
        return self._is_running

    @property
    def success(self) -> bool:
        """Check if execution was successful."""
        return self._success
