from pathlib import Path
import shutil
import time

# Import logging from the same modules directory
from util.setup_logger import log_error, log_info, log_success, log_warning, log_progress
from util.command_utils import run_command
from util.platform_utils import is_darwin, is_ci, is_linux, resolve_repo_root


ORBSTACK_PATH = "/Applications/OrbStack.app"
DOCKER_PATH = "/Applications/Docker.app"


def check_docker_desktop_installed() -> bool:
    """Check if Docker Desktop is installed."""
    return Path(DOCKER_PATH).exists()


def check_orbstack_installed() -> bool:
    """Check if OrbStack is installed."""
    return Path(ORBSTACK_PATH).exists()


def check_orbstack_installed_via_brew() -> bool:
    """Check if OrbStack is installed via Homebrew."""
    if not is_darwin():
        return False

    # Check if brew is available
    brew_path = shutil.which("brew")
    if not brew_path:
        # Try common installation paths
        possible_paths = ["/opt/homebrew/bin/brew", "/usr/local/bin/brew"]
        for path in possible_paths:
            if Path(path).exists():
                brew_path = path
                break

    if not brew_path:
        return False

    # Check if orbstack cask is listed in brew
    result = run_command([brew_path, "list", "--cask", "orbstack"], check=False)
    return result.returncode == 0


def docker_info() -> bool:
    """Check if Docker is running and accessible."""
    result = run_command(["docker", "info"], check=False)
    return result.returncode == 0


def handle_docker_migration():
    """Handle Docker Desktop to OrbStack migration on macOS."""
    if not is_darwin() or is_ci():
        return

    docker_desktop_installed = check_docker_desktop_installed()
    orbstack_installed = check_orbstack_installed()
    orbstack_installed_via_brew = check_orbstack_installed_via_brew()

    # Edge case: OrbStack exists but wasn't installed via Homebrew
    # Note: This should be rare now since we check before brew bundle runs in install_homebrew_deps()
    # But we keep this check as a safety net
    if orbstack_installed and not orbstack_installed_via_brew:
        handle_non_brew_orbstack_migration()
        return

    if not docker_desktop_installed and orbstack_installed:
        log_success("OrbStack is already installed and ready to go!")
    elif not docker_desktop_installed and not orbstack_installed:
        log_error("No container runtime detected. OrbStack should've been installed via brew bundle!!")
        log_error("Please report this error in #devex, it shouldn't happen!  Paste in your markdown log file.")
        return
    elif docker_desktop_installed and not orbstack_installed:
        log_error("Docker desktop installed, but OrbStack is not!? OrbStack should've been installed via brew bundle!!")
        log_error("Please report this error in #devex, it shouldn't happen!  Paste in your markdown log file.")
        return
    elif docker_desktop_installed and orbstack_installed:
        initial_docker_orbstack_migrate()


def remove_non_brew_orbstack() -> bool:
    """Remove non-brew OrbStack installation before brew bundle runs.

    Returns True if OrbStack was successfully removed, False if migration was cancelled.
    This should be called BEFORE running brew bundle to avoid conflicts.
    """
    log_warning("OrbStack is installed but not via Homebrew.")
    log_info("We need to remove the existing OrbStack installation before running brew bundle.")
    log_info("This ensures proper dependency management and consistency.")
    log_info("")
    log_info("IMPORTANT: Your OrbStack configuration and data will be preserved!")
    log_info(" - Your containers and images will be preserved")
    log_info(" - Your OrbStack settings will be retained")
    log_info(" - Database data in volumes is safe")
    log_info("")

    # Find brew command
    brew_path = shutil.which("brew")
    if not brew_path:
        possible_paths = ["/opt/homebrew/bin/brew", "/usr/local/bin/brew"]
        for path in possible_paths:
            if Path(path).exists():
                brew_path = path
                break

    if not brew_path:
        log_error("Homebrew not found. Cannot proceed with migration.")
        return False

    # Install AppCleaner
    log_info("Installing AppCleaner to help with OrbStack removal...")
    appcleaner_result = run_command([brew_path, "install", "--cask", "appcleaner"], check=False)
    if appcleaner_result.returncode != 0:
        log_warning("Failed to install AppCleaner. You may need to manually remove OrbStack.")
        log_info("You can install AppCleaner manually with: brew install --cask appcleaner")
    else:
        log_success("AppCleaner installed successfully")

    log_progress("")
    log_progress("=" * 79)
    log_progress("MANUAL REMOVAL REQUIRED")
    log_progress("=" * 79)
    log_progress("")
    log_progress("Please remove OrbStack using AppCleaner:")
    log_progress("")
    log_progress("1. Open AppCleaner.app (should be in your Applications folder)")
    log_progress("2. Drag OrbStack.app from /Applications into AppCleaner")
    log_progress("3. Review the files AppCleaner found (your config/data should be preserved)")
    log_progress("4. Click 'Remove' to uninstall OrbStack")
    log_progress("5. Empty your trash")
    log_progress("")
    log_progress("Note: This will still preserve your OrbStack configuration and data.")
    log_progress("This removal is necessary to reinstall OrbStack via Homebrew.")
    log_progress("")
    log_progress("=" * 79)
    log_progress("")

    # Wait for user confirmation that OrbStack has been removed
    while True:
        response = input("Have you removed OrbStack using AppCleaner? (y/n): ").strip().lower()
        if response in ("y", "yes"):
            # Verify OrbStack has been removed
            if check_orbstack_installed():
                log_warning("OrbStack still appears to be installed. Please make sure you've removed it.")
                retry = input("Try again? (y/n): ").strip().lower()
                if retry not in ("y", "yes"):
                    log_info("Migration cancelled. Please run this script again when ready.")
                    return False
            else:
                log_success("OrbStack has been removed. Proceeding with Homebrew installation...")
                return True
        elif response in ("n", "no"):
            log_info("Migration cancelled. Please run this script again when ready.")
            return False
        else:
            log_info("Please enter 'y' for yes or 'n' for no.")


def handle_non_brew_orbstack_migration():
    """Handle migration from non-brew OrbStack to brew-installed OrbStack.

    This includes removal AND installation via brew bundle.
    Used when detected during docker migration (should be rare now).
    """
    if not remove_non_brew_orbstack():
        return

    # Install OrbStack via brew bundle
    log_info("Installing OrbStack via Homebrew...")
    repo_root = resolve_repo_root()
    if not repo_root:
        log_error("Could not determine repository root. Cannot install OrbStack.")
        return

    brewfile_path = repo_root / "Brewfile"
    if not brewfile_path.exists():
        log_error(f"Brewfile not found at {brewfile_path}. Cannot install OrbStack.")
        return

    # Find brew command
    brew_path = shutil.which("brew")
    if not brew_path:
        possible_paths = ["/opt/homebrew/bin/brew", "/usr/local/bin/brew"]
        for path in possible_paths:
            if Path(path).exists():
                brew_path = path
                break

    if not brew_path:
        log_error("Homebrew not found. Cannot install OrbStack.")
        return

    str_path = str(brewfile_path.absolute())
    log_progress(f"Running brew bundle to install OrbStack from: {str_path}")
    bundle_result = run_command([brew_path, "bundle", "--file", str_path], check=False)

    if bundle_result.returncode == 0:
        log_success("OrbStack installed successfully via Homebrew!")
    else:
        log_warning("brew bundle may have encountered issues. Please check the output above.")
        log_info("OrbStack should still be installed. Continuing...")


def initial_docker_orbstack_migrate():
    log_info("Both Docker Desktop and OrbStack are installed.")
    log_info("We recommend removing Docker Desktop and keeping OrbStack for better performance and a native macOS UX.")
    log_info(
        "We have a company site licence, so please use it, we don't want to support Docker Desktop on macOS anymore!"
    )
    log_warning(
        "Important: This will stop any running Docker containers, but your data will be preserved and be managed by orbstack."
    )
    log_warning("Please STOP any running backend processes first.")
    log_info(" - Docker images and volumes will be preserved")
    log_info(" - Database data in volumes is safe")
    log_info(" - You'll need to restart your compose services after migration")
    log_info(" - You will need to do some one time manual steps.")

    response = input("Remove Docker Desktop and keep OrbStack? (Y/n): ").strip().lower()
    if response in ("y", "yes", ""):
        migrate_to_orbstack()


def check_orbstack_running() -> bool:
    """Check if OrbStack is running and docker is accessible."""
    # Check if OrbStack process is running
    check_process = run_command(["pgrep", "-f", "OrbStack"], check=False)
    if check_process.returncode != 0:
        return False

    # Check if docker command works (which means OrbStack's docker is available)
    return docker_info()


def wait_for_orbstack(max_wait: int = 30) -> bool:
    """Wait for OrbStack to be ready and docker to be accessible."""
    log_info("Waiting for OrbStack to be ready...")
    for i in range(max_wait):
        if check_orbstack_running() and docker_info():
            log_success("OrbStack is ready and Docker is accessible!")
            return True
        time.sleep(1)
        if i % 5 == 0:
            log_progress(f"Still waiting for OrbStack... ({i}/{max_wait} seconds)")
    return False


def check_orbstack_logged_in() -> bool:
    """Check if user is logged into OrbStack."""
    if not is_darwin():
        return True  # Login check only relevant on macOS

    if not check_orbstack_installed():
        return False

    # Check login status by running orbctl login (without --force)
    # If already logged in, it will output "Already logged in." and exit with code 0
    # If not logged in, it would prompt for login or show different output
    try:
        result = run_command(["orbctl", "login"], check=False)
        # Check if output contains "Already logged in" (case-insensitive)
        output = result.stdout.lower() if result.stdout else ""
        if result.returncode == 0 and "already logged in" in output:
            return True
        return False
    except Exception:
        # If orbctl command fails, assume not logged in
        return False


def log_orbstack_login_instructions(step_num: str = "2"):
    log_progress("")
    log_progress(f"STEP {step_num}: Sign in to OrbStack")
    log_progress("-" * 79)
    log_progress("1. We will open a browser to login to OrbStack")
    log_progress("2. Choose 'Sign in with Google' (don't type email directly)")
    log_progress("3. In the browser page that opens:")
    log_progress("   - Sign in with your corporate Anysphere/Cursor Google account")
    log_progress("   - Select or join the 'Anysphere' organization")
    log_progress("   - Complete the sign-in process")
    log_progress("")


def migrate_to_orbstack():
    """Migrate from Docker Desktop to OrbStack."""
    log_info("Stopping Docker Desktop containers first...")

    # Stop running containers gracefully before removing Docker Desktop
    if docker_info():
        compose_file = Path("backend/server/docker-compose.yml")
        if compose_file.exists():
            # Use docker-compose on macOS (OrbStack), docker compose on Linux
            if is_darwin():
                run_command(["docker-compose", "-f", str(compose_file), "down"], check=False)
            else:
                run_command(["docker", "compose", "-f", str(compose_file), "down"], check=False)
            log_info("Stopped backend/server compose services")
        else:
            # Try to stop any running containers
            try:
                # Get list of running container IDs
                ps_result = run_command(["docker", "ps", "-q"], check=False)
                if ps_result.returncode == 0 and ps_result.stdout.strip():
                    container_ids = ps_result.stdout.strip().split("\n")
                    for container_id in container_ids:
                        if container_id.strip():
                            run_command(["docker", "stop", container_id.strip()], check=False)
                    log_info("Attempted to stop any running containers")
            except Exception:
                log_info("Could not enumerate containers to stop")

    # Launch OrbStack
    if not launch_orbstack():
        log_warning(
            f"We couldn't launch {ORBSTACK_PATH} for some reason, for this migration to work, you need to launch the OrbStack app, please do so."
        )
        log_info("Please manually launch OrbStack and then press Enter to continue...")
        input()

    # Wait a bit for OrbStack to start up
    log_info("Waiting for OrbStack to initialize...")
    time.sleep(3)

    # Check if OrbStack is ready (docker accessible)
    orbstack_ready = wait_for_orbstack(max_wait=10)

    if orbstack_ready:
        log_success("OrbStack appears to be ready! Checking if migration is needed...")
        # If docker is already working, migration might already be done
        log_info("Docker is accessible via OrbStack. Migration may have already completed.")
    else:
        log_warning("OrbStack may not be fully ready yet, but continuing with migration steps...")

    log_progress("")
    log_progress("STEP 1: Migrate from Docker Desktop")
    log_progress("-" * 79)
    log_progress("1. In the OrbStack window, click through the initial wizard")
    log_progress("   - Choose 'Docker' when prompted (or any option, it doesn't matter)")
    log_progress(f"   - If you can't see it, launch OrbStack at {ORBSTACK_PATH}")
    log_progress("")
    log_progress("2. Look for the MIGRATE button:")
    log_progress("   - Make sure 'Containers' is selected in the left sidebar")
    log_progress("   - Look for a purple 'MIGRATE' button/box in the UI")
    log_progress("   - Click it to start the migration from Docker Desktop")
    log_progress("")
    log_progress("3. Follow the migration wizard:")
    log_progress("   - Docker Desktop may launch automatically (this is normal)")
    log_progress("   - Click through any prompts to allow the migration")
    log_progress("   - Wait for migration to complete")
    log_progress("   - You should see your docker compose stack appear in OrbStack")
    log_progress("")
    log_progress("=" * 79)
    log_progress("")

    # Step 1: Confirm migration is complete
    while True:
        response = input("Have you completed STEP 1 (migration from Docker Desktop)? (y/n): ").strip().lower()
        if response in ("y", "yes"):
            break
        elif response in ("n", "no"):
            log_warning("Please complete STEP 1 before proceeding.")
            log_info("You can continue when ready, or cancel and run this again later.")
            retry = input("Try again? (y/n): ").strip().lower()
            if retry not in ("y", "yes"):
                log_info("Migration cancelled. Docker Desktop will not be removed.")
                return
        else:
            log_info("Please enter 'y' for yes or 'n' for no.")

    # Step 2: Handle OrbStack login
    log_progress("")
    log_progress("=" * 79)
    log_progress("STEP 2: Sign in to OrbStack")
    log_progress("-" * 79)

    # Always show login instructions first
    log_orbstack_login_instructions(step_num="2")

    # Ask if ready to login, then run orbctl login which will open browser
    while True:
        response = input("Ready to sign in to OrbStack? This will open your browser. (y/n): ").strip().lower()
        if response in ("y", "yes"):
            log_info("Opening OrbStack login in your browser...")
            log_info("Please complete the login process in the browser that opens.")
            # Run orbctl login - this will open browser if not logged in, or confirm if already logged in
            run_command(["orbctl", "login"], check=False)

            # Wait a moment for browser to open and user to potentially complete login
            time.sleep(2)

            # Check if login was successful
            if check_orbstack_logged_in():
                log_success("✓ Successfully logged into OrbStack!")
            else:
                log_warning("Login check shows you may not be logged in yet.")
                log_info("If you just completed login, it may take a moment to register.")
                retry = input("Try checking login status again? (y/n): ").strip().lower()
                if retry in ("y", "yes"):
                    time.sleep(2)
                    if check_orbstack_logged_in():
                        log_success("✓ Successfully logged into OrbStack!")
                    else:
                        log_warning("Still not logged in. You may need to complete the login manually.")
                else:
                    log_info("Continuing... Please ensure you're logged in before proceeding.")
            break
        elif response in ("n", "no"):
            log_warning("You need to sign in to OrbStack to continue.")
            log_info("You can run this script again later to complete the login step.")
            retry = input("Cancel migration? (y/n): ").strip().lower()
            if retry in ("y", "yes"):
                log_info("Migration cancelled. Docker Desktop will not be removed.")
                return
        else:
            log_info("Please enter 'y' for yes or 'n' for no.")

    # Final confirmation before removing Docker Desktop
    log_progress("")
    log_progress("=" * 79)
    log_progress("")

    while True:
        response = input("Have you completed all steps? Ready to remove Docker Desktop? (y/n): ").strip().lower()
        if response in ("y", "yes"):
            # Verify docker is accessible one more time
            if docker_info():
                log_success("Docker is accessible! Migration appears successful.")
            else:
                log_warning("Docker is not yet accessible. You may need to complete the migration steps first.")
                retry = input("Continue with Docker Desktop removal anyway? (y/n): ").strip().lower()
                if retry not in ("y", "yes"):
                    log_info("Skipping Docker Desktop removal. You can run this again later.")
                    return
            break
        elif response in ("n", "no"):
            log_warning("Migration cancelled. Docker Desktop will not be removed.")
            log_info("You can run the migration again later when ready.")
            return
        else:
            log_info("Please enter 'y' for yes or 'n' for no.")

    remove_docker_desktop()


def check_docker_desktop_running() -> bool:
    """Check if Docker Desktop is currently running."""
    check_result = run_command(["pgrep", "-f", "Docker Desktop"], check=False)
    return check_result.returncode == 0


def quit_docker_desktop() -> bool:
    """Quit Docker Desktop gracefully using AppleScript, then kill if needed."""
    if not check_docker_desktop_running():
        log_info("Docker Desktop is not running")
        return True

    log_info("Quitting Docker Desktop...")

    # Try graceful quit via AppleScript first
    try:
        # First attempt: Standard quit
        quit_script = """
        tell application "Docker"
            if it is running then
                quit
            end if
        end tell
        """
        run_command(["osascript", "-e", quit_script], check=False)
        time.sleep(3)  # Give it time to quit gracefully

        # Check if it quit successfully
        if not check_docker_desktop_running():
            log_success("Docker Desktop quit successfully")
            return True

        # Second attempt: Force quit via AppleScript if standard quit didn't work
        log_info("Standard quit didn't work, trying force quit...")
        force_quit_script = """
        tell application "System Events"
            tell process "Docker"
                if exists then
                    try
                        click button 1 of window 1
                    end try
                    quit
                end if
            end tell
        end tell
        tell application "Docker"
            if it is running then
                quit saving no
            end if
        end tell
        """
        run_command(["osascript", "-e", force_quit_script], check=False)
        time.sleep(2)
    except Exception as e:
        log_warning(f"AppleScript quit attempt failed: {e}")

    # If still running, kill processes
    if check_docker_desktop_running():
        log_info("Docker Desktop still running, killing processes...")
        return kill_docker_desktop()

    return True


def kill_docker_desktop() -> bool:
    """Forcefully kill Docker Desktop and all related processes."""
    log_info("Forcefully killing Docker Desktop processes...")

    # List of Docker Desktop processes to kill
    processes_to_kill = [
        "com.docker.backend",
        "com.docker.supervisor",
        "com.docker.driver.amd64-linux",
        "com.docker.hyperkit",
        "com.docker.vpnkit",
        "Docker Desktop",
        "Docker",
    ]

    # Try killing via AppleScript first (can handle multiple processes)
    try:
        kill_script = """
        tell application "System Events"
            set docker_processes to every process whose name contains "Docker"
            repeat with proc in docker_processes
                try
                    kill proc
                end try
            end repeat
        end tell
        """
        run_command(["osascript", "-e", kill_script], check=False)
        time.sleep(1)
    except Exception as e:
        log_warning(f"AppleScript kill attempt failed: {e}")

    # Kill processes via pkill as fallback
    for process_name in processes_to_kill:
        try:
            run_command(["pkill", "-9", "-f", process_name], check=False)
        except Exception:
            pass

    # Also try killing by bundle identifier
    bundle_ids = ["com.docker.docker", "com.electron.dockerfrontend"]
    for bundle_id in bundle_ids:
        try:
            run_command(["killall", "-9", bundle_id], check=False)
        except Exception:
            pass

    # Wait for processes to terminate
    time.sleep(2)

    # Verify Docker Desktop is no longer running
    if check_docker_desktop_running():
        log_warning("Some Docker Desktop processes may still be running")
        return False

    log_success("Docker Desktop has been killed")
    return True


def remove_docker_desktop_files() -> None:
    """Remove Docker Desktop files and directories."""
    docker_paths_to_remove = [
        Path(DOCKER_PATH),
        Path.home() / "Library/Group Containers/group.com.docker",
        Path.home() / "Library/Containers/com.docker.docker",
        Path.home() / "Library/Application Support/Docker Desktop",
        Path.home() / "Library/Preferences/com.docker.docker.plist",
        Path.home() / "Library/Preferences/com.electron.dockerfrontend.plist",
        Path.home() / "Library/Saved Application State/com.electron.dockerfrontend.savedState",
        Path.home() / "Library/Caches/com.docker.docker",
        Path.home() / ".docker",
    ]

    for path in docker_paths_to_remove:
        if path.exists():
            try:
                if path.is_dir():
                    shutil.rmtree(path)
                    log_info(f"Removed directory: {path}")
                else:
                    path.unlink()
                    log_info(f"Removed file: {path}")
            except PermissionError:
                log_warning(f"Permission denied removing {path}, may need manual cleanup")
            except Exception as e:
                log_warning(f"Could not remove {path}: {e}")


def remove_docker_desktop():
    """Comprehensive Docker Desktop removal with multiple fallback strategies."""
    log_info("Removing Docker Desktop...")

    # Step 1: Quit Docker Desktop completely
    if not quit_docker_desktop():
        log_warning("Docker Desktop may still be running. Proceeding anyway...")

    # Step 2: Try official uninstall script first (most reliable)
    uninstall_script = Path("/Applications/Docker.app/Contents/MacOS/uninstall")
    if uninstall_script.exists():
        log_info("Running Docker Desktop official uninstall script...")
        log_info("You will be prompted for your password to remove Docker Desktop system files.")
        result = run_command(["sudo", str(uninstall_script)], check=False)
        if result.returncode == 0:
            log_success("Official uninstall script completed successfully")
        else:
            log_warning(f"Uninstall script exited with code {result.returncode}")
            log_info("Trying alternative removal methods...")

    # Step 3: Try Homebrew uninstall (if installed via Homebrew)
    log_info("Attempting Homebrew uninstall...")
    brew_result = run_command(["brew", "uninstall", "--cask", "docker"], check=False)
    if brew_result.returncode == 0:
        log_success("Homebrew uninstall completed")
    else:
        log_info("Docker may not have been installed via Homebrew, or already removed")

    # Step 4: Manual file cleanup for stubborn files
    log_info("Cleaning up remaining Docker Desktop files...")
    remove_docker_desktop_files()

    # Step 5: Verify removal
    if check_docker_desktop_installed():
        log_warning("Docker Desktop removal appears to have failed. Docker Desktop.app still exists.")
        log_progress("Installing AppCleaner as a last resort...")
        run_command(["brew", "install", "--cask", "appcleaner"], check=False)
        log_info("")
        log_info("=" * 79)
        log_info("MANUAL REMOVAL REQUIRED")
        log_info("=" * 79)
        log_info("Docker Desktop could not be automatically removed. Please try one of:")
        log_info("")
        log_info("Option 1: Use AppCleaner (recommended)")
        log_info("  1. Open AppCleaner.app")
        log_info("  2. Drag Docker.app from /Applications into AppCleaner")
        log_info("  3. Review and confirm removal")
        log_info("")
        log_info("Option 2: Use Docker Desktop's built-in uninstaller")
        log_info("  1. Open Docker Desktop application")
        log_info("  2. Go to Docker Desktop menu > Settings > Resources > Uninstall")
        log_info("")
        log_info("Option 3: Manual removal (advanced)")
        log_info("  1. Remove /Applications/Docker.app")
        log_info("  2. Remove ~/Library/Containers/com.docker.docker")
        log_info("  3. Remove ~/Library/Group Containers/group.com.docker")
        log_info("  4. Remove ~/Library/Application Support/Docker Desktop")
        log_info("=" * 79)
    else:
        log_success("Docker Desktop removal complete")
        log_success("Congrats, you're now on OrbStack!")


def launch_orbstack():
    """Launch OrbStack application."""
    orbstack_path = Path(ORBSTACK_PATH)
    if orbstack_path.exists():
        log_info("Launching OrbStack...")
        run_command(["open", ORBSTACK_PATH], check=False)
        log_success("OrbStack launched successfully")
        log_info("Please complete the OrbStack setup in the opened window")
        return True
    return False


def start_docker():
    """Start Docker if not running."""
    if docker_info():
        return

    started_orbstack = False

    if is_linux():
        log_info("You will be prompted for your password to start the Docker service.")
        run_command(["sudo", "service", "docker", "start"], check=False)
        # Wait a moment for docker to start
        time.sleep(2)
        # Check if user needs to be added to docker group or if socket permissions need fixing
        if not docker_info():
            # Check if socket exists and has correct permissions
            socket_check = run_command(["test", "-S", "/var/run/docker.sock"], check=False)
            if socket_check.returncode == 0:
                # Try to fix socket permissions (typically root:docker 0660)
                log_info("You will be prompted for your password to fix Docker socket permissions.")
                run_command(["sudo", "chmod", "666", "/var/run/docker.sock"], check=False)
                # Re-check after fixing permissions
                if docker_info():
                    log_success("Docker is now accessible after fixing socket permissions")
                else:
                    log_warning("Docker started but user may need to be added to docker group")
                    log_info("Run: sudo usermod -aG docker $USER && newgrp docker")
    elif is_darwin():
        if Path(ORBSTACK_PATH).exists():
            launch_orbstack()
            started_orbstack = True
        elif Path(DOCKER_PATH).exists():
            run_command(["open", DOCKER_PATH], check=False)
        else:
            log_warning("Neither OrbStack nor Docker Desktop is installed. It should be installed by brew bundle.")

    if started_orbstack:
        log_info("Started OrbStack")
    else:
        log_info("Started Docker")


def check_docker_in_path() -> None:
    """Check if docker command is in PATH when Docker or OrbStack is installed."""
    docker_installed = check_docker_desktop_installed()
    orbstack_installed = check_orbstack_installed()

    # Only check if at least one is installed
    if not docker_installed and not orbstack_installed:
        return

    # Check if docker command is in PATH
    docker_path = shutil.which("docker")
    if docker_path is None:
        log_warning("Docker or OrbStack is installed, but the 'docker' command is not found in your PATH.")
        log_warning("This usually means PATH hasn't been updated yet.")
        log_info("Please restart your terminal and make sure you've manually run the OrbStack / Docker Desktop UX.")


def check_docker_in_usr_local_bin() -> None:
    """Check if docker exists in /usr/local/bin/docker (macOS only)."""
    if not is_darwin() or is_ci():
        return

    docker_bin_path = Path("/usr/local/bin/docker")
    if docker_bin_path.exists():
        log_success(f"Docker CLI found at {docker_bin_path}")
    else:
        log_warning(f"Docker CLI not found at {docker_bin_path}")
        log_info("This may be normal if OrbStack hasn't fully initialized yet.")
        log_info("Please restart your terminal after OrbStack setup completes.")


def setup_docker():
    handle_docker_migration()
    check_docker_in_path()
    start_docker()
    check_docker_in_usr_local_bin()
