""" Run this to install to your projects
    |  "--dest folder"  |to set destination dir
    |  "--project name" |to set project name
    |  "--verbose" or "-v"|to enable verbose output
    |  "--force" or "-f"|to force overwrite existing files
"""

import os
import sys
import shutil
import argparse
import subprocess
from pathlib import Path

# Try to import our script creation module
try:
    from create_launcher_scripts import ensure_launcher_scripts
except ImportError:
    # If we can't import it, we'll define a simple version here
    def ensure_launcher_scripts(
        script_dir, dest_dir, project_name, verbose=False, force=False
    ):
        """Fallback function if the module can't be imported."""
        print(
            "Warning: create_launcher_scripts module not found. Using fallback."
        )
        return []


def main():
    """Main installation function."""
    parser = argparse.ArgumentParser(
        description="Install the progress tracking system."
    )
    parser.add_argument(
        "--dest", default="scripts", help="Destination directory"
    )
    parser.add_argument("--project", default="Project", help="Project name")
    parser.add_argument(
        "--verbose", "-v", action="store_true", help="Enable verbose output"
    )
    parser.add_argument(
        "--force",
        "-f",
        action="store_true",
        help="Force overwrite existing files",
    )
    args = parser.parse_args()

    verbose = args.verbose
    force = args.force

    if verbose:
        print(
            f"Installing progress tracking system to {args.dest} for project {args.project}"
        )

    # Create destination directories
    os.makedirs(
        os.path.join(args.dest, "track_progress", "templates"), exist_ok=True
    )
    os.makedirs("docs/status", exist_ok=True)

    # Get the directory of this script
    script_dir = os.path.dirname(os.path.abspath(__file__))
    parent_dir = os.path.dirname(script_dir)  # scripts/track_progress

    # Look for compiled executable
    exe_ext = ".exe" if sys.platform == "win32" else ""
    compiled_exe = os.path.join(parent_dir, f"track_progress{exe_ext}")
    dist_exe = os.path.join(parent_dir, "dist", f"track_progress{exe_ext}")

    # Check if we have the executable in either location
    if not os.path.exists(compiled_exe) and not os.path.exists(dist_exe):
        # Try to build it
        if verbose:
            print(f"Compiled executable not found, trying to build it...")

        build_script = os.path.join(script_dir, "build_with_nuitka.py")
        if os.path.exists(build_script):
            build_cmd = [sys.executable, build_script]
            if verbose:
                build_cmd.append("--verbose")

            try:
                subprocess.check_call(build_cmd)
                # The executable should now be in the dist directory

                # Move the executable from dist to parent directory
                if os.path.exists(dist_exe):
                    if os.path.exists(compiled_exe):
                        os.remove(compiled_exe)
                    shutil.move(dist_exe, compiled_exe)
                    if verbose:
                        print(
                            f"Moved executable from {dist_exe} to {compiled_exe}"
                        )
            except subprocess.CalledProcessError:
                print(
                    "Failed to build the executable. Falling back to Python files."
                )
        else:
            print("Build script not found. Falling back to Python files.")

    # Check if we have the executable now
    have_executable = os.path.exists(compiled_exe)

    if have_executable:
        # Copy the compiled executable
        dst_exe = os.path.join(
            args.dest, "track_progress", f"track_progress{exe_ext}"
        )
        if not os.path.exists(dst_exe) or force:
            shutil.copy2(compiled_exe, dst_exe)
            if verbose:
                print(
                    f"Copied compiled executable from {compiled_exe} to {dst_exe}"
                )
        elif verbose:
            print(f"Skipping existing executable: {dst_exe}")
    else:
        # Copy individual Python files
        python_files = [
            "track_progress.py",
            "config.py",
            "git_analyzer.py",
            "code_stats.py",
            "feature_markdown.py",
            "template_engine.py",
            "changelog_generator.py",
            "roadmap_generator.py",
            "__init__.py",  # Add this to make it a proper package
            "README.md",
        ]

        for file in python_files:
            src = os.path.join(parent_dir, file)
            dst = os.path.join(args.dest, "track_progress", file)

            # Skip existing files unless force is specified
            if os.path.exists(dst) and not force:
                if verbose:
                    print(f"Skipping existing file: {dst}")
                continue

            if os.path.exists(src):
                shutil.copy2(src, dst)
                if verbose:
                    print(f"Copied {file} to {dst}")
            elif file == "__init__.py":
                # Create empty __init__.py if it doesn't exist
                with open(dst, "w", encoding="utf-8") as f:
                    f.write(
                        "# This file makes the directory a Python package\n"
                    )
                if verbose:
                    print(f"Created {dst}")

    # Copy templates (always copy templates, they should remain exposed)
    template_files = [
        "status_template.md",
        "feature_template.md",
        "changelog_template.md",
    ]

    for file in template_files:
        src = os.path.join(parent_dir, "templates", file)
        dst = os.path.join(args.dest, "track_progress", "templates", file)

        # Skip existing files unless force is specified
        if os.path.exists(dst) and not force:
            if verbose:
                print(f"Skipping existing template: {dst}")
            continue

        if os.path.exists(src):
            shutil.copy2(src, dst)
            if verbose:
                print(f"Copied template {file} to {dst}")

    # Copy and customize configuration
    config_src = os.path.join(parent_dir, "progress_config.json")
    config_dst = os.path.join(
        args.dest, "track_progress", "progress_config.json"
    )

    # Skip existing config unless force is specified
    if not os.path.exists(config_dst) or force:
        if os.path.exists(config_src):
            # Read the config file
            with open(config_src, "r", encoding="utf-8") as f:
                config_content = f.read()

            # Replace project name
            config_content = config_content.replace(
                '"project_name": "AdvChkSys"',
                f'"project_name": "{args.project}"',
            )

            # Ensure paths are relative to the project root
            config_content = config_content.replace(
                '"features_file": "docs/features.md"',
                '"features_file": "docs/features.md"',
            )
            config_content = config_content.replace(
                '"output_dir": "docs/status"',
                '"output_dir": "docs/status"',
            )
            config_content = config_content.replace(
                '"changelog_file": "CHANGELOG.md"',
                '"changelog_file": "CHANGELOG.md"',
            )

            # Write the customized config
            with open(config_dst, "w", encoding="utf-8") as f:
                f.write(config_content)

            if verbose:
                print(f"Created customized configuration at {config_dst}")
    elif verbose:
        print(f"Skipping existing configuration: {config_dst}")

    # Ensure launcher scripts exist in the scripts directory
    created_scripts = ensure_launcher_scripts(
        script_dir, args.dest, args.project, verbose, force
    )
    if created_scripts and verbose:
        print(
            f"Created {len(created_scripts)} launcher scripts in {script_dir}"
        )

    # Create an empty CHANGELOG.md if it doesn't exist
    if not os.path.exists("CHANGELOG.md"):
        with open("CHANGELOG.md", "w", encoding="utf-8") as f:
            f.write("# Changelog\n\n")
        if verbose:
            print("Created empty CHANGELOG.md")

    # Copy the scripts directory to the destination if it doesn't exist
    scripts_dst = os.path.join(args.dest, "track_progress", "scripts")
    if not os.path.exists(scripts_dst) or force:
        os.makedirs(scripts_dst, exist_ok=True)

        # Copy script files
        script_files = [
            "build_with_nuitka.py",
            "create_launcher_scripts.py",
            "setup_install.py",
        ]

        for file in script_files:
            src = os.path.join(script_dir, file)
            dst = os.path.join(scripts_dst, file)

            if os.path.exists(src) and (not os.path.exists(dst) or force):
                shutil.copy2(src, dst)
                if verbose:
                    print(f"Copied script {file} to {dst}")

    print("\nInstallation complete!")
    if have_executable:
        print(
            f"Compiled tracker installed to: {os.path.join(args.dest, 'track_progress')}"
        )
    else:
        print(
            f"Python tracker installed to: {os.path.join(args.dest, 'track_progress')}"
        )

    # Check which launcher scripts exist
    py_launcher = os.path.join(script_dir, "run_progress_tracker.py")
    sh_launcher = os.path.join(script_dir, "run_progress_tracker.sh")
    bat_launcher = os.path.join(script_dir, "run_progress_tracker.bat")

    print("\nTo run the tracker, use one of these commands:")
    if os.path.exists(py_launcher):
        print(f"- Python: python {py_launcher}")
    if os.path.exists(sh_launcher) and sys.platform != "win32":
        print(f"- Shell: {sh_launcher}")
    if os.path.exists(bat_launcher) and sys.platform == "win32":
        print(f"- Batch: {bat_launcher}")


if __name__ == "__main__":
    main()
