"""Functions for rclone and local filesystem interaction."""

import os
import subprocess
from typing import List, Optional, Tuple

def run_command(command: List[str], timeout: int = 10) -> Tuple[int, str]:
    """Execute a command and return (returncode, output)."""
    try:
        result = subprocess.run(
            command,
            capture_output=True,
            text=True,
            timeout=timeout,
            check=False,
        )
        return result.returncode, result.stdout + result.stderr
    except subprocess.TimeoutExpired:
        return 1, "Command timed out"
    except Exception as e:
        return 1, str(e)

def list_remotes() -> List[str]:
    """Get list of rclone remotes."""
    rc, output = run_command(["rclone", "listremotes"])
    if rc != 0:
        return []
    return [line.strip() for line in output.splitlines() if line.strip()]

def list_remote_dir(remote: str, path: str = "") -> List[str]:
    """List directories and files in a remote path."""
    # The user specifically mentioned lsd, so let's ensure we get directories
    full_remote_path = f"{remote}{path}"
    
    # Try using lsf as primary because it's much easier to parse and handles both
    # But we'll fallback to lsd for directories as suggested if lsf seems empty/failed
    rc, output = run_command(["rclone", "lsf", "--dir-slash", "--format", "p", full_remote_path])
    
    if rc == 0 and output.strip():
        items = [line.strip() for line in output.splitlines() if line.strip()]
        dirs = sorted([i for i in items if i.endswith("/")])
        files = sorted([i for i in items if not i.endswith("/")])
        return dirs + files
    
    # Fallback/Supplemental: Use lsd as specifically suggested
    rc_lsd, output_lsd = run_command(["rclone", "lsd", full_remote_path])
    if rc_lsd == 0:
        dirs = []
        for line in output_lsd.splitlines():
            if line.strip():
                # lsd output looks like: "          -1 2023-10-10 10:10:10         -1 My Directory"
                # We need to correctly capture the name after the first 4 columns
                parts = line.split(None, 4)
                if len(parts) >= 5:
                    dirs.append(parts[4].strip() + "/")
        return sorted(dirs)
        
    return []

def list_local_dir(path: str) -> List[str]:
    """List directories and files in a local path."""
    try:
        items = os.listdir(path)
        # Add trailing slash to directories
        formatted_items = []
        for item in items:
            if os.path.isdir(os.path.join(path, item)):
                formatted_items.append(item + "/")
            else:
                formatted_items.append(item)
        
        # Sort: directories first, then files
        dirs = sorted([i for i in formatted_items if i.endswith("/")])
        files = sorted([i for i in formatted_items if not i.endswith("/")])
        return dirs + files
    except Exception:
        return []

def run_rclone_copy(mode: int, src: str, dst: str, dry_run: bool = False):
    """Run rclone copy command based on mode.

    Modes:
    1: Single file (copyto)
    2: Directory traversed (copy)
    3: Directory no-traverse (copy --no-traverse)
    """
    import sys
    import subprocess
    import os

    # Common exclude patterns - use /** for directories to exclude their contents
    exclude_patterns = [
        "--exclude", ".git/**",
        "--exclude", ".venv/**",
        "--exclude", "venv/**",
        "--exclude", "env/**",
        "--exclude", ".opencode/**",
        "--exclude", ".openai_*",
        "--exclude", ".*~",
        "--exclude", ".python-version",
        "--exclude", ".python-cache/**",
        "--exclude", ".pytest_cache/**",
    ]

    if mode == 1:
        # Single file copy - exclude patterns not supported
        cmd = ["rclone", "copyto", src, dst, "--progress"]
    elif mode == 2:
        cmd = ["rclone", "copy", src, dst, "--progress"] + exclude_patterns
    elif mode == 3:
        cmd = ["rclone", "copy", src, dst, "--progress", "--no-traverse"] + exclude_patterns
    else:
        return

    if dry_run:
        cmd.append("--dry-run")

    # Clear screen for a clean output and ensure sane terminal state
    os.system('stty sane && clear')
    print(f"Executing: {' '.join(cmd)}\n")
    if dry_run:
        print("!!! DRY RUN MODE - No files will be copied !!!\n")
    print("-" * 60)

    try:
        # Run and allow user to see output
        result = subprocess.run(cmd, check=False)

        # Call stty sane again after rclone completes
        os.system('stty sane')

        print("-" * 60)
        if result.returncode == 0:
            print("\n\033[92mOperation finished successfully.\033[0m Press Enter to return to mcrc...")
        else:
            print(f"\n\033[91mOperation failed (exit code {result.returncode}).\033[0m Press Enter to return to mcrc...")

        # Use a more robust input waiting mechanism
        try:
            sys.stdin.read(1)
        except:
            pass

    except KeyboardInterrupt:
        os.system('stty sane')
        print("\n\n\033[91mOperation cancelled by user.\033[0m")
        print("Press Enter to return to mcrc...")
        try:
            sys.stdin.read(1)
        except:
            pass
    except Exception as e:
        os.system('stty sane')
        print(f"\n\n\033[91mError in rclone execution: {e}\033[0m")
        print("Press Enter to return to mcrc...")
        try:
            sys.stdin.read(1)
        except:
            pass

def run_rclone_deletefile(remote_path: str):
    """Run rclone deletefile command.
    
    Args:
        remote_path: The remote path to the file (remote:path/to/file)
    """
    import sys
    import subprocess
    import os

    cmd = ["rclone", "deletefile", remote_path, "--progress"]

    # Clear screen for a clean output and ensure sane terminal state
    os.system('stty sane && clear')
    print(f"Executing: {' '.join(cmd)}\n")
    print("!!! WARNING: REAL DELETE MODE - File will be permanently deleted !!!\n")
    print("-" * 60)
    
    try:
        # Run and allow user to see output
        result = subprocess.run(cmd, check=False)

        # Call stty sane again after rclone completes
        os.system('stty sane')

        print("-" * 60)
        if result.returncode == 0:
            print("\n\033[92mOperation finished successfully.\033[0m Press Enter to return to mcrc...")
        else:
            print(f"\n\033[91mOperation failed (exit code {result.returncode}).\033[0m Press Enter to return to mcrc...")

        # Use a more robust input waiting mechanism
        try:
            sys.stdin.read(1)
        except:
            pass

    except KeyboardInterrupt:
        os.system('stty sane')
        print("\n\n\033[91mOperation cancelled by user.\033[0m")
        print("Press Enter to return to mcrc...")
        try:
            sys.stdin.read(1)
        except:
            pass
    except Exception as e:
        os.system('stty sane')
        print(f"\n\n\033[91mError in rclone execution: {e}\033[0m")
        print("Press Enter to return to mcrc...")
        try:
            sys.stdin.read(1)
        except:
            pass

def run_rclone_purge(remote_path: str, dry_run: bool = True):
    """Run rclone purge command.
    
    Args:
        remote_path: The remote path to purge (remote:path/to/dir)
        dry_run: If True, adds --dry-run flag
    """
    import sys
    import subprocess
    import os

    cmd = ["rclone", "purge", remote_path, "--progress"]
    if dry_run:
        cmd.append("--dry-run")

    # Clear screen for a clean output and ensure sane terminal state
    os.system('stty sane && clear')
    print(f"Executing: {' '.join(cmd)}\n")
    if dry_run:
        print("!!! DRY RUN MODE - No files will be deleted !!!\n")
    else:
        print("!!! WARNING: REAL PURGE MODE - Files will be permanently deleted !!!\n")
    print("-" * 60)
    
    try:
        # Run and allow user to see output
        result = subprocess.run(cmd, check=False)

        # Call stty sane again after rclone completes
        os.system('stty sane')

        print("-" * 60)
        if result.returncode == 0:
            print("\n\033[92mOperation finished successfully.\033[0m Press Enter to return to mcrc...")
        else:
            print(f"\n\033[91mOperation failed (exit code {result.returncode}).\033[0m Press Enter to return to mcrc...")

        # Use a more robust input waiting mechanism
        try:
            sys.stdin.read(1)
        except:
            pass

    except KeyboardInterrupt:
        os.system('stty sane')
        print("\n\n\033[91mOperation cancelled by user.\033[0m")
        print("Press Enter to return to mcrc...")
        try:
            sys.stdin.read(1)
        except:
            pass
    except Exception as e:
        os.system('stty sane')
        print(f"\n\n\033[91mError in rclone execution: {e}\033[0m")
        print("Press Enter to return to mcrc...")
        try:
            sys.stdin.read(1)
        except:
            pass

def run_rclone_sync(src: str, dst: str, dry_run: bool = True):
    """Run rclone sync command.
    
    Args:
        src: Source path
        dst: Destination path
        dry_run: If True, adds --dry-run flag
    """
    import sys
    import subprocess
    import os

    # Common exclude patterns - use /** for directories to exclude their contents
    exclude_patterns = [
        "--exclude", ".git/**",
        "--exclude", ".venv/**",
        "--exclude", "venv/**",
        "--exclude", "env/**",
        "--exclude", ".opencode/**",
        "--exclude", ".openai_*",
        "--exclude", ".*~",
        "--exclude", ".python-version",
        "--exclude", ".python-cache/**",
        "--exclude", ".pytest_cache/**",
    ]

    cmd = ["rclone", "sync", src, dst, "--metadata", "--progress"] + exclude_patterns
    if dry_run:
        cmd.append("--dry-run")

    # Clear screen for a clean output and ensure sane terminal state
    os.system('stty sane && clear')
    print(f"Executing: {' '.join(cmd)}\n")
    if dry_run:
        print("!!! DRY RUN MODE - No files will be deleted or moved !!!\n")
    else:
        print("!!! WARNING: REAL SYNC MODE - Files in destination may be DELETED to match source !!!\n")
    print("-" * 60)
    
    try:
        # Run and allow user to see output
        result = subprocess.run(cmd, check=False)

        # Call stty sane again after rclone completes
        os.system('stty sane')

        print("-" * 60)
        if result.returncode == 0:
            print("\n\033[92mOperation finished successfully.\033[0m Press Enter to return to mcrc...")
        else:
            print(f"\n\033[91mOperation failed (exit code {result.returncode}).\033[0m Press Enter to return to mcrc...")

        # Use a more robust input waiting mechanism
        try:
            sys.stdin.read(1)
        except:
            pass

    except KeyboardInterrupt:
        os.system('stty sane')
        print("\n\n\033[91mOperation cancelled by user.\033[0m")
        print("Press Enter to return to mcrc...")
        try:
            sys.stdin.read(1)
        except:
            pass
    except Exception as e:
        os.system('stty sane')
        print(f"\n\n\033[91mError in rclone execution: {e}\033[0m")
        print("Press Enter to return to mcrc...")
        try:
            sys.stdin.read(1)
        except:
            pass

def run_rclone_mkdir(remote_path: str):
    """Run rclone mkdir command.
    
    Args:
        remote_path: The remote path to create (remote:path/to/dir)
    """
    import sys
    import subprocess
    import os

    cmd = ["rclone", "mkdir", remote_path]

    # Clear screen for a clean output and ensure sane terminal state
    os.system('stty sane && clear')
    print(f"Executing: {' '.join(cmd)}\n")
    print("-" * 60)
    
    try:
        # Run and allow user to see output
        result = subprocess.run(cmd, capture_output=True, text=True, check=False)

        # Call stty sane again after rclone completes
        os.system('stty sane')

        print("-" * 60)
        if result.returncode == 0:
            print("\n\033[92mDirectory created successfully.\033[0m Press Enter to return to mcrc...")
        else:
            print(f"\n\033[91mError: {result.stderr}\033[0m")
            print("\n\033[91mOperation failed.\033[0m Press Enter to return to mcrc...")

        # Use a more robust input waiting mechanism
        try:
            sys.stdin.read(1)
        except:
            pass

    except KeyboardInterrupt:
        os.system('stty sane')
        print("\n\n\033[91mOperation cancelled by user.\033[0m")
        print("Press Enter to return to mcrc...")
        try:
            sys.stdin.read(1)
        except:
            pass
    except Exception as e:
        os.system('stty sane')
        print(f"\n\n\033[91mError in rclone execution: {e}\033[0m")
        print("Press Enter to return to mcrc...")
        try:
            sys.stdin.read(1)
        except:
            pass

def run_rclone_check(src: str, dst: str):
    """Run rclone check command.

    Args:
        src: Source path
        dst: Destination path
    """
    import sys
    import subprocess
    import os

    # Common exclude patterns - use /** for directories to exclude their contents
    exclude_patterns = [
        "--exclude", ".git/**",
        "--exclude", ".venv/**",
        "--exclude", "venv/**",
        "--exclude", "env/**",
        "--exclude", ".opencode/**",
        "--exclude", ".openai_*",
        "--exclude", ".*~",
        "--exclude", ".python-version",
        "--exclude", ".python-cache/**",
        "--exclude", ".pytest_cache/**",
    ]

    cmd = ["rclone", "check", src, dst, "--size-only", "--progress"] + exclude_patterns

    # Clear screen for a clean output and ensure sane terminal state
    os.system('stty sane && clear')
    print(f"Executing: {' '.join(cmd)}\n")
    print("!!! INFO: Check compares files by size only, not content !!!\n")
    print("-" * 60)

    try:
        # Run and allow user to see output
        result = subprocess.run(cmd, check=False)

        # Call stty sane again after rclone completes
        os.system('stty sane')

        print("-" * 60)
        if result.returncode == 0:
            print("\n\033[92mCheck completed - no differences found.\033[0m Press Enter to return to mcrc...")
        else:
            print(f"\n\033[93mCheck completed with differences (exit code {result.returncode}).\033[0m Press Enter to return to mcrc...")

        # Use a more robust input waiting mechanism
        try:
            sys.stdin.read(1)
        except:
            pass

    except KeyboardInterrupt:
        os.system('stty sane')
        print("\n\n\033[91mCheck cancelled by user.\033[0m")
        print("Press Enter to return to mcrc...")
        try:
            sys.stdin.read(1)
        except:
            pass
    except Exception as e:
        os.system('stty sane')
        print(f"\n\n\033[91mError in rclone execution: {e}\033[0m")
        print("Press Enter to return to mcrc...")
        try:
            sys.stdin.read(1)
        except:
            pass
