
from pathlib import Path
import shutil
from typing import List, Tuple

from .rules import get_category
from .utils import get_extension, is_hidden, is_system_file, safe_move
from .logger import logger


def organize_directory(
    directory: Path,
    recursive: bool = True,
    dry_run: bool = False,
    include_hidden: bool = False,
    overwrite: bool = False
) -> Tuple[int, List[str], List[Tuple[Path, Path]]]:
    """
    Organize files in directory by moving them to category folders.

    Returns (moved_count, error_messages, list_of_moves)
    """
    moved_count = 0
    errors = []
    moves = []

    if recursive:
        files = list(directory.rglob("*"))
    else:
        files = list(directory.iterdir())

    for file_path in files:
        if not file_path.is_file():
            continue

        if not include_hidden and (is_hidden(file_path) or is_system_file(file_path)):
            continue

        ext = get_extension(file_path)
        category = get_category(ext)

        target_folder = directory / category
        target_path = target_folder / file_path.name

        # Handle name conflicts
        counter = 1
        while target_path.exists() and not overwrite:
            stem = file_path.stem
            suffix = file_path.suffix
            target_path = target_folder / f"{stem}_{counter}{suffix}"
            counter += 1

        if dry_run:
            logger.info(f"[DRY RUN] Would move: {file_path} -> {target_path}")
            print(f"[DRY RUN] Would move: {file_path.name} -> {category}/")
            moved_count += 1
            moves.append((file_path, target_path))
        else:
            try:
                if safe_move(file_path, target_path, overwrite):
                    logger.info(f"Moved: {file_path} -> {target_path}")
                    print(f"Moved: {file_path.name} -> {category}/")
                    moved_count += 1
                    moves.append((file_path, target_path))
                else:
                    error = f"Failed to move (file exists): {file_path}"
                    errors.append(error)
                    logger.warning(error)
            except Exception as e:
                error = f"Error moving {file_path}: {e}"
                errors.append(error)
                logger.error(error)

    return moved_count, errors, moves


def clean_empty_folders(directory: Path, dry_run: bool = False) -> Tuple[int, List[Path]]:
    """Remove empty folders recursively. Returns (removed_count, list_of_removed_folders)"""
    removed_count = 0
    removed_folders = []

    for folder in sorted(directory.rglob("*"), reverse=True):
        if folder.is_dir() and not any(folder.iterdir()):
            if dry_run:
                print(f"[DRY RUN] Would remove empty folder: {folder}")
                logger.info(f"[DRY RUN] Would remove empty folder: {folder}")
                removed_count += 1
                removed_folders.append(folder)
            else:
                try:
                    folder.rmdir()
                    print(f"Removed empty folder: {folder}")
                    logger.info(f"Removed empty folder: {folder}")
                    removed_count += 1
                    removed_folders.append(folder)
                except Exception as e:
                    logger.error(f"Error removing folder {folder}: {e}")

    return removed_count, removed_folders