# smart_organizer/cli.py

import typer
from pathlib import Path
from typing import Optional

from .organizer import organize_directory, clean_empty_folders
from .duplicate import find_duplicates, print_duplicates, get_duplicate_stats
from .logger import setup_logger

app = typer.Typer(help="Smart File Organizer - Organize files by type, find duplicates, and clean up.")


@app.command()
def organize(
    path: str = typer.Argument(..., help="Directory path to organize"),
    recursive: bool = typer.Option(True, help="Organize files in subdirectories"),
    dry_run: bool = typer.Option(False, help="Show what would be done without making changes"),
    include_hidden: bool = typer.Option(False, help="Include hidden files"),
    overwrite: bool = typer.Option(False, help="Overwrite existing files"),
    log_file: Optional[str] = typer.Option(None, help="Log file path")
):
    """Organize files in directory by moving them to category folders."""
    directory = Path(path)
    if not directory.exists() or not directory.is_dir():
        typer.echo(f"Error: {path} is not a valid directory")
        raise typer.Exit(1)

    if log_file:
        setup_logger(log_file)

    typer.echo(f"Organizing files in {directory}...")
    moved, errors, moves = organize_directory(directory, recursive, dry_run, include_hidden, overwrite)

    if not dry_run:
        # Save moves for undo
        import json
        undo_file = directory / ".smart_organizer_undo_organize.json"
        with open(undo_file, 'w') as f:
            json.dump([[str(src), str(dst)] for src, dst in moves], f)

    if dry_run:
        typer.echo(f"Dry run complete. Would move {moved} files.")
    else:
        typer.echo(f"Organization complete. Moved {moved} files.")

    if errors:
        typer.echo(f"Errors encountered: {len(errors)}")
        for error in errors[:5]:  # Show first 5 errors
            typer.echo(f"  {error}")
        if len(errors) > 5:
            typer.echo(f"  ... and {len(errors) - 5} more")


@app.command()
def duplicates(
    path: str = typer.Argument(..., help="Directory path to scan for duplicates"),
    recursive: bool = typer.Option(True, help="Scan subdirectories"),
    include_hidden: bool = typer.Option(False, help="Include hidden files"),
    log_file: Optional[str] = typer.Option(None, help="Log file path")
):
    """Find and display duplicate files."""
    directory = Path(path)
    if not directory.exists() or not directory.is_dir():
        typer.echo(f"Error: {path} is not a valid directory")
        raise typer.Exit(1)

    if log_file:
        setup_logger(log_file)

    typer.echo(f"Scanning for duplicates in {directory}...")
    dups = find_duplicates(directory, recursive, include_hidden)

    if dups:
        groups, dup_count, total_files = get_duplicate_stats(dups)
        typer.echo(f"Found {groups} duplicate groups with {dup_count} duplicate files ({total_files} total files)")
        print_duplicates(dups)
    else:
        typer.echo("No duplicates found.")


@app.command()
def clean(
    path: str = typer.Argument(..., help="Directory path to clean"),
    dry_run: bool = typer.Option(False, help="Show what would be done without making changes"),
    log_file: Optional[str] = typer.Option(None, help="Log file path")
):
    """Remove empty folders."""
    directory = Path(path)
    if not directory.exists() or not directory.is_dir():
        typer.echo(f"Error: {path} is not a valid directory")
        raise typer.Exit(1)

    if log_file:
        setup_logger(log_file)

    typer.echo(f"Cleaning empty folders in {directory}...")
    removed, removed_folders = clean_empty_folders(directory, dry_run)

    if not dry_run:
        # Save removed folders for undo
        import json
        undo_file = directory / ".smart_organizer_undo_clean.json"
        with open(undo_file, 'w') as f:
            json.dump([str(f) for f in removed_folders], f)

    if dry_run:
        typer.echo(f"Dry run complete. Would remove {removed} empty folders.")
    else:
        typer.echo(f"Clean complete. Removed {removed} empty folders.")


@app.command()
def undo(
    path: str = typer.Argument(..., help="Directory path to undo last operation"),
    operation: str = typer.Option("organize", help="Operation to undo: 'organize' or 'clean'"),
    log_file: Optional[str] = typer.Option(None, help="Log file path")
):
    """Undo the last organize or clean operation."""
    directory = Path(path)
    if not directory.exists() or not directory.is_dir():
        typer.echo(f"Error: {path} is not a valid directory")
        raise typer.Exit(1)

    if log_file:
        setup_logger(log_file)

    import json
    if operation == "organize":
        undo_file = directory / ".smart_organizer_undo_organize.json"
        if not undo_file.exists():
            typer.echo("No organize operation to undo.")
            return
        with open(undo_file, 'r') as f:
            data = json.load(f)
        moves = [(Path(pair[0]), Path(pair[1])) for pair in data]
        typer.echo(f"Undoing organize: moving {len(moves)} files back...")
        for src, dst in moves:
            if dst.exists():
                try:
                    dst.rename(src)
                    print(f"Restored: {dst} -> {src}")
                except Exception as e:
                    typer.echo(f"Error restoring {dst}: {e}")
            else:
                typer.echo(f"File not found: {dst}")
        undo_file.unlink()
    elif operation == "clean":
        undo_file = directory / ".smart_organizer_undo_clean.json"
        if not undo_file.exists():
            typer.echo("No clean operation to undo.")
            return
        with open(undo_file, 'r') as f:
            removed_folders = [Path(f) for f in json.load(f)]
        typer.echo(f"Undoing clean: recreating {len(removed_folders)} folders...")
        for folder in removed_folders:
            try:
                folder.mkdir(parents=True, exist_ok=True)
                print(f"Recreated: {folder}")
            except Exception as e:
                typer.echo(f"Error recreating {folder}: {e}")
        undo_file.unlink()
    else:
        typer.echo("Invalid operation. Use 'organize' or 'clean'.")


@app.command()
def info():
    """Show information about file categories."""
    from .rules import get_all_categories
    categories = get_all_categories()
    typer.echo("File Categories:")
    for category, extensions in categories.items():
        typer.echo(f"  {category}: {', '.join(extensions)}")


if __name__ == "__main__":
    app()