"""
Predefined augmentation presets for common document scenarios.

Presets provide ready-to-use configurations optimized for different
use cases, from conservative (preserves text readability) to aggressive
(simulates poor document quality).
"""

from typing import Any

from shared.augmentation.config import AugmentationConfig, AugmentationParams


PRESETS: dict[str, dict[str, Any]] = {
    "conservative": {
        "description": "Safe augmentations that preserve text readability",
        "config": {
            "lighting_variation": {
                "enabled": True,
                "probability": 0.5,
                "params": {
                    "brightness_range": (-0.1, 0.1),
                    "contrast_range": (0.9, 1.1),
                },
            },
            "gaussian_noise": {
                "enabled": True,
                "probability": 0.3,
                "params": {"std": (3, 10)},
            },
        },
    },
    "moderate": {
        "description": "Balanced augmentations for typical document degradation",
        "config": {
            "lighting_variation": {
                "enabled": True,
                "probability": 0.5,
                "params": {
                    "brightness_range": (-0.15, 0.15),
                    "contrast_range": (0.85, 1.15),
                },
            },
            "shadow": {
                "enabled": True,
                "probability": 0.3,
                "params": {"num_shadows": (1, 2), "opacity": (0.2, 0.35)},
            },
            "gaussian_noise": {
                "enabled": True,
                "probability": 0.3,
                "params": {"std": (5, 12)},
            },
            "gaussian_blur": {
                "enabled": True,
                "probability": 0.2,
                "params": {"kernel_size": (3, 5), "sigma": (0.5, 1.0)},
            },
            "paper_texture": {
                "enabled": True,
                "probability": 0.3,
                "params": {"intensity": (0.05, 0.12)},
            },
        },
    },
    "aggressive": {
        "description": "Heavy augmentations simulating poor scan quality",
        "config": {
            "perspective_warp": {
                "enabled": True,
                "probability": 0.3,
                "params": {"max_warp": 0.02},
            },
            "wrinkle": {
                "enabled": True,
                "probability": 0.4,
                "params": {"intensity": 0.3, "num_wrinkles": (2, 4)},
            },
            "stain": {
                "enabled": True,
                "probability": 0.3,
                "params": {
                    "num_stains": (1, 2),
                    "max_radius_ratio": 0.08,
                    "opacity": (0.1, 0.25),
                },
            },
            "lighting_variation": {
                "enabled": True,
                "probability": 0.6,
                "params": {
                    "brightness_range": (-0.2, 0.2),
                    "contrast_range": (0.8, 1.2),
                },
            },
            "shadow": {
                "enabled": True,
                "probability": 0.4,
                "params": {"num_shadows": (1, 2), "opacity": (0.25, 0.4)},
            },
            "gaussian_blur": {
                "enabled": True,
                "probability": 0.3,
                "params": {"kernel_size": (3, 5), "sigma": (0.5, 1.5)},
            },
            "motion_blur": {
                "enabled": True,
                "probability": 0.2,
                "params": {"kernel_size": (5, 7), "angle_range": (-30, 30)},
            },
            "gaussian_noise": {
                "enabled": True,
                "probability": 0.4,
                "params": {"std": (8, 18)},
            },
            "paper_texture": {
                "enabled": True,
                "probability": 0.4,
                "params": {"intensity": (0.08, 0.15)},
            },
            "scanner_artifacts": {
                "enabled": True,
                "probability": 0.3,
                "params": {"line_probability": 0.4, "dust_probability": 0.5},
            },
            "edge_damage": {
                "enabled": True,
                "probability": 0.2,
                "params": {"max_damage_ratio": 0.04},
            },
        },
    },
    "scanned_document": {
        "description": "Simulates typical scanned document artifacts",
        "config": {
            "scanner_artifacts": {
                "enabled": True,
                "probability": 0.5,
                "params": {"line_probability": 0.4, "dust_probability": 0.5},
            },
            "paper_texture": {
                "enabled": True,
                "probability": 0.4,
                "params": {"intensity": (0.05, 0.12)},
            },
            "lighting_variation": {
                "enabled": True,
                "probability": 0.3,
                "params": {
                    "brightness_range": (-0.1, 0.1),
                    "contrast_range": (0.9, 1.1),
                },
            },
            "gaussian_noise": {
                "enabled": True,
                "probability": 0.3,
                "params": {"std": (5, 12)},
            },
        },
    },
}


def get_preset_config(preset_name: str) -> dict[str, Any]:
    """
    Get the configuration dictionary for a preset.

    Args:
        preset_name: Name of the preset.

    Returns:
        Configuration dictionary.

    Raises:
        ValueError: If preset is not found.
    """
    if preset_name not in PRESETS:
        raise ValueError(
            f"Unknown preset: {preset_name}. "
            f"Available presets: {list(PRESETS.keys())}"
        )
    return PRESETS[preset_name]["config"]


def create_config_from_preset(preset_name: str) -> AugmentationConfig:
    """
    Create an AugmentationConfig from a preset.

    Args:
        preset_name: Name of the preset.

    Returns:
        AugmentationConfig instance.

    Raises:
        ValueError: If preset is not found.
    """
    config_dict = get_preset_config(preset_name)
    return AugmentationConfig.from_dict(config_dict)


def list_presets() -> list[dict[str, str]]:
    """
    List all available presets.

    Returns:
        List of dictionaries with name and description.
    """
    return [
        {"name": name, "description": preset["description"]}
        for name, preset in PRESETS.items()
    ]
