from os import stat, chmod, path, unlink
from stat import S_IEXEC
from typing import Callable
from .core import CLI
from .decorators import opt
from subprocess import run, CalledProcessError
from tempfile import NamedTemporaryFile


def install_setup(cli: CLI, script_path: str) -> Callable:
    """
    Install a setup command for a Zenif CLI applet.

    This function creates a new command that generates a shell script to install
    the CLI applet as a Zsh command.

    Args:
        cli (CLI): The Zenif CLI instance to add the command to.
        script_path (str): The file to run.

    Returns:
        Callable: The setup function that was added to the CLI.
    """

    @cli.command
    @opt("--alias", default=cli.name, help="Alias for the command")
    def setup(alias: str):
        """Install this script as a Zsh command"""
        install_script_content = f"""#!/bin/zsh
if [[ -f ~/.zshrc ]]; then
    if ! grep -q "{alias}()" ~/.zshrc; then
        echo '\n# Auto-generated by Zenif CLI' >> ~/.zshrc
        echo '{alias}() {{' >> ~/.zshrc
        echo '    python {script_path} "$@"' >> ~/.zshrc
        echo '}}' >> ~/.zshrc
        echo "Command \x1b[44m\x1b[30m {alias} \x1b[0m has been added to your .zshrc file.\n"
        echo "Run the following to finish the installation:"
        echo "\nsource ~/.zshrc   \x1b[90mupdate your configuration\x1b[0m"
        echo   "{alias} -h{(13-len(alias))*" "}  \x1b[90mdisplay help information\x1b[0m"
    else
        echo "The command \x1b[44m\x1b[30m {alias} \x1b[0m is already in your .zshrc file."
    fi
else
    echo "Error: ~/.zshrc file not found."
fi

# Delete this script
rm -f "$0"
"""

        with NamedTemporaryFile(mode="w", suffix=".sh", delete=False) as temp_script:
            temp_script.write(install_script_content)
            temp_script_path = temp_script.name

        # Make the script executable
        st = stat(temp_script_path)
        chmod(temp_script_path, st.st_mode | S_IEXEC)

        print(f"Executing installation script for '{alias}' command...")

        try:
            # Execute the script
            result = run(
                ["zsh", temp_script_path], check=True, text=True, capture_output=True
            )
            print(f"\n{result.stdout}")
            if result.stderr:
                print(f"\n{result.stderr}")
        except CalledProcessError as e:
            print(f"Installation failed with error: {e}")
            print(e.stderr)
        finally:
            try:
                if "temp_script_path" in locals() and path.exists(temp_script_path):
                    unlink(temp_script_path)
                    print("Installation script has been cleaned up.")
                else:
                    print("No temporary script to clean up; already cleaned up.")
            except Exception as e:
                print(f"Failed to delete temporary script: {e}")

    return setup
