"""Execution flows for the CLI."""

from __future__ import annotations

import logging
from pathlib import Path

from rich.console import Console
import typer

from revo_module_installer.cli_support import helpers as cli_helpers
from revo_module_installer.config.load import (
    is_local_registry_environment,
    load_registry_index,
)
from revo_module_installer.config.manifest import ManifestIndex
from revo_module_installer.config.registry import RegistryEntry, RegistryIndex
from revo_module_installer.config.settings import get_default_registry_url

console: Console = Console()
logger: logging.Logger = logging.getLogger(__name__)


def execute_module_install(
    registry_entry: RegistryEntry,
    registry_index: RegistryIndex,
    manifest_index: ManifestIndex,
    manifest_source_url: str,
    *,
    dry_run: bool,
) -> None:
    """Render and execute a module installation.

    Args:
        registry_entry: Registry metadata for the module.
        registry_index: Parsed registry data.
        manifest_index: Parsed manifest data.
        manifest_source_url: URL where the selected manifest was loaded from.
        dry_run: Whether to skip filesystem writes.
    """
    plan: cli_helpers.InstallPlan = cli_helpers.build_install_plan(
        registry_entry,
        manifest_index,
        registry_index.version,
    )
    console.print(
        f"Installing [bold]{registry_entry.name}[/] "
        f"({registry_entry.id})",
    )
    console.print(cli_helpers.render_manifest_table(manifest_index.entries))

    if dry_run:
        console.print("Dry run complete. No files were written.")
        return

    applied_count: int = cli_helpers.apply_manifest_entries(
        manifest_index.entries,
        manifest_source_url,
        Path.cwd(),
    )
    logger.info(
        "Applied %s entries from manifest version %s",
        applied_count,
        plan["manifest_version"],
    )
    console.print(f"Module installation completed. Applied {applied_count} entries.")


def run_default_module_install() -> None:
    """Prompt for a module name and install it."""
    registry_url: str = get_default_registry_url()
    registry_index: RegistryIndex = load_registry_index(
        registry_url,
        allow_local_fallback=is_local_registry_environment(),
        local_registry_path=None,
    )
    console.print(cli_helpers.build_search_table(registry_index.entries))
    search_query: str = cli_helpers.prompt_for_search_query(registry_index.entries)
    matched_entries: list[RegistryEntry] = cli_helpers.filter_registry_entries(
        registry_index.entries,
        search_query,
    )
    if not matched_entries:
        console.print("[red]No modules matched that search.[/]")
        raise typer.Exit(code=1)

    registry_entry: RegistryEntry | None = None
    if len(matched_entries) == 1:
        registry_entry = matched_entries[0]
        if not cli_helpers.confirm_module_installation(registry_entry):
            console.print("Cancelled install.")
            raise typer.Exit(code=0)
    else:
        console.print(cli_helpers.build_search_table(matched_entries))
        module_name: str = cli_helpers.prompt_for_module_name()
        registry_entry = cli_helpers.find_registry_entry_by_name(
            matched_entries,
            module_name,
        )
        if registry_entry is None:
            console.print(f"[red]Module not found:[/] {module_name}")
            raise typer.Exit(code=1)

    selected_variant_id: str | None = cli_helpers.prompt_for_variant_id(registry_entry)
    manifest_source_url: str = cli_helpers.resolve_manifest_source_url(
        registry_entry,
        manifest_url_override=None,
        selected_variant_id=selected_variant_id,
    )
    manifest_index: ManifestIndex = cli_helpers.resolve_manifest_index(
        registry_entry,
        manifest_url_override=None,
        selected_variant_id=selected_variant_id,
    )
    execute_module_install(
        registry_entry,
        registry_index,
        manifest_index,
        manifest_source_url,
        dry_run=False,
    )
