"""Shell config step - configures shell with tribunal alias."""

from __future__ import annotations

from pathlib import Path

from installer.context import InstallContext
from installer.platform_utils import get_shell_config_files
from installer.steps.base import BaseStep

ALIAS_MARKER = "# Tribunal"
SF_BIN = "$HOME/.tribunal/bin/tribunal"
BUN_BIN_PATH = "$HOME/.bun/bin"


def get_alias_lines(shell_type: str) -> str:
    """Get tribunal and sfc alias lines for the given shell type."""
    if shell_type == "fish":
        path_line = f'set -gx PATH "{BUN_BIN_PATH}" $PATH'
    else:
        path_line = f'export PATH="{BUN_BIN_PATH}:$PATH"'
    return f'{ALIAS_MARKER}\n{path_line}\nalias tribunal="{SF_BIN}"\nalias sfc="{SF_BIN}"'


def alias_exists_in_file(config_file: Path) -> bool:
    """Check if tribunal alias already exists in config file."""
    if not config_file.exists():
        return False
    content = config_file.read_text()
    return ALIAS_MARKER in content or "alias tribunal" in content or "alias sfc" in content


def remove_old_alias(config_file: Path) -> bool:
    """Remove existing tribunal alias from config file to allow clean update."""
    if not config_file.exists():
        return False

    content = config_file.read_text()
    has_old = (
        ALIAS_MARKER in content
        or "alias tribunal" in content
        or "alias sfc" in content
        or "tribunal()" in content
        or "sfc()" in content
        or "function tribunal" in content
        or "function sfc" in content
        or 'PATH="$HOME/.bun/bin' in content
    )
    if not has_old:
        return False

    lines = content.split("\n")
    new_lines = []
    inside_function = False
    brace_count = 0

    for line in lines:
        stripped = line.strip()

        if ALIAS_MARKER in line:
            continue

        if (
            stripped.startswith("alias tribunal=")
            or stripped.startswith("alias sfc=")
            or stripped.startswith("alias tribunal ")
            or stripped.startswith("alias sfc ")
        ):
            continue

        if stripped == 'export PATH="$HOME/.bun/bin:$PATH"' or stripped == 'set -gx PATH "$HOME/.bun/bin" $PATH':
            continue

        if stripped.startswith("tribunal()") or stripped == "tribunal () {":
            inside_function = True
            brace_count = 0
        elif stripped.startswith("sfc()") or stripped == "sfc () {":
            inside_function = True
            brace_count = 0

        if inside_function:
            brace_count += line.count("{") - line.count("}")
            if brace_count <= 0:
                inside_function = False
            continue

        if stripped.startswith("function tribunal") or stripped.startswith("function sfc"):
            inside_function = True
            continue

        if inside_function and stripped == "end":
            inside_function = False
            continue

        if not inside_function:
            new_lines.append(line)

    final_lines = []
    prev_blank = False
    for line in new_lines:
        is_blank = line.strip() == ""
        if is_blank and prev_blank:
            continue
        final_lines.append(line)
        prev_blank = is_blank

    config_file.write_text("\n".join(final_lines))
    return True


class ShellConfigStep(BaseStep):
    """Step that configures shell with tribunal alias."""

    name = "shell_config"

    def check(self, ctx: InstallContext) -> bool:
        """Always return False to ensure alias is updated on every install."""
        _ = ctx
        return False

    def run(self, ctx: InstallContext) -> None:
        """Configure shell with tribunal alias."""
        ui = ctx.ui
        config_files = get_shell_config_files()
        modified_files: list[str] = []
        needs_reload = False

        if ui:
            ui.status("Configuring shell alias...")

        for config_file in config_files:
            if not config_file.exists():
                continue

            alias_existed = alias_exists_in_file(config_file)
            if alias_existed:
                remove_old_alias(config_file)

            shell_type = "fish" if "fish" in config_file.name else "bash"
            alias_lines = get_alias_lines(shell_type)

            try:
                with open(config_file, "a") as f:
                    f.write(f"\n{alias_lines}\n")
                modified_files.append(str(config_file))
                if ui:
                    if alias_existed:
                        ui.success(f"Updated alias in {config_file.name}")
                    else:
                        ui.success(f"Added alias to {config_file.name}")
                        needs_reload = True
            except (OSError, IOError) as e:
                if ui:
                    ui.warning(f"Could not modify {config_file.name}: {e}")

        ctx.config["modified_shell_configs"] = modified_files
        ctx.config["shell_needs_reload"] = needs_reload
