"""Diagnose screen for the ALiCE TUI — runs checks and shows pass/fail."""

from __future__ import annotations

from typing import TYPE_CHECKING

from textual.containers import Horizontal, Vertical
from textual.widgets import Button, Footer, Input, Label
from textual.worker import Worker, WorkerState

from alice_cli.config import resolve_config
from alice_cli.models import CLIConfig, DoctorCheck
from alice_cli.tui.screens.base import AliceScreen
from alice_cli.tui.widgets.breadcrumb import BreadcrumbBar
from alice_cli.tui.widgets.header_bar import AliceHeaderBar
from alice_cli.tui.widgets.output import OutputPanel

if TYPE_CHECKING:
    from textual.app import ComposeResult


def _run_checks(config: CLIConfig) -> list[DoctorCheck]:
    from alice_cli.commands.diagnose import (
        _check_aws_cli,
        _check_bedrock_endpoint,
        _check_boto3,
        _check_locker_prefix,
        _check_python_version,
        _check_s3_bucket,
        _check_sso_session,
        _check_stored_credentials,
        _resolve_username,
    )

    checks = [
        _check_python_version(),
        _check_boto3(),
        _check_aws_cli(),
        _check_stored_credentials(),
        _check_sso_session(config),
        _check_bedrock_endpoint(config.region),
        _check_s3_bucket(config),
    ]
    username = _resolve_username(config)
    if username:
        checks.append(_check_locker_prefix(config, username))
    else:
        checks.append(
            DoctorCheck(
                name="Locker prefix access",
                passed=False,
                detail="Could not determine JHED",
                hint="Run 'alice auth' first.",
            )
        )
    return checks


class DiagnoseScreen(AliceScreen):
    """Runs diagnostics and displays a pass/fail checklist."""

    DEFAULT_CSS = """
    DiagnoseScreen {
        align: center middle;
    }

    DiagnoseScreen #profile-row {
        height: 3;
        width: 100%;
        margin-bottom: 1;
    }

    DiagnoseScreen #profile-label {
        width: 10;
        height: 3;
        content-align: left middle;
        background: transparent;
    }

    DiagnoseScreen #profile-input {
        width: 1fr;
    }

    DiagnoseScreen #btn-run {
        width: 100%;
        margin-top: 1;
    }
    """

    def compose(self) -> ComposeResult:
        yield AliceHeaderBar()
        yield BreadcrumbBar(id="breadcrumb")
        with Vertical(id="diagnose-box", classes="alice-panel"):
            yield Label("ALiCE Diagnostics", id="diagnose-title", classes="alice-panel-title")
            with Horizontal(id="profile-row"):
                yield Label("Profile:", id="profile-label")
                yield Input(
                    placeholder="e.g. drcc-ai",
                    value=self.config.profile or "",
                    id="profile-input",
                )
            yield OutputPanel(id="output-panel", wrap=True, wordstar=self._wordstar)
            yield Button("Run Diagnostics", id="btn-run", variant="primary")
        yield Footer()

    def on_mount(self) -> None:
        if self.config.profile:
            self._run()
        else:
            output = self.query_one("#output-panel", OutputPanel)
            output.write("  Enter an SSO profile above and press Run Diagnostics.")

    def on_button_pressed(self, event: Button.Pressed) -> None:
        if event.button.id == "btn-run":
            self._run()

    def on_input_submitted(self, event: Input.Submitted) -> None:
        if event.input.id == "profile-input":
            self._run()

    def _build_config(self) -> CLIConfig:
        """Build a config using the profile input value, with full credential resolution."""
        config = self.config
        profile = self.query_one("#profile-input", Input).value.strip() or config.profile
        return resolve_config(
            profile=profile,
            region=config.region,
            namespace=config.namespace,
            environment=config.environment,
            quiet=config.quiet,
            debug=config.debug,
        )

    def _run(self) -> None:
        output = self.query_one("#output-panel", OutputPanel)
        output.clear()
        output.write("  Running diagnostics…")
        run_config = self._build_config()
        self.run_worker(lambda: _run_checks(run_config), name="diagnose", thread=True)

    def on_worker_state_changed(self, event: Worker.StateChanged) -> None:
        if event.worker.name != "diagnose":
            return
        if event.state == WorkerState.SUCCESS:
            checks: list[DoctorCheck] = event.worker.result  # type: ignore[assignment]
            self._display(checks)
        elif event.state == WorkerState.ERROR:
            output = self.query_one("#output-panel", OutputPanel)
            output.clear()
            exc = event.worker.error
            if exc is not None:
                self._handle_error(exc, output)
            else:
                output.write("[#FF6600]Unexpected error during diagnostics[/]")

    def _display(self, checks: list[DoctorCheck]) -> None:
        output = self.query_one("#output-panel", OutputPanel)
        output.clear()
        for check in checks:
            detail = check.detail
            # Shorten ARNs: show just the role/session portion
            if "arn:aws:" in detail:
                detail = detail.replace("arn:aws:sts::", "…").replace(":assumed-role/", " → ")
            if check.passed:
                output.write(f"  [green]✓[/green] {check.name}")
                output.write(f"    {detail}")
            else:
                output.write(f"  [red]✗[/red] {check.name}")
                output.write(f"    {detail}")
                if check.hint:
                    output.write(f"    [yellow]↳ {check.hint}[/yellow]")
        passed = sum(1 for c in checks if c.passed)
        total = len(checks)
        style = "green" if passed == total else "yellow" if passed else "red"
        output.write("")
        output.write(f"  [{style}]{passed}/{total} checks passed[/{style}]")
