"""File operations for configuration generation."""

from pathlib import Path
import sys
from typing import Any

import click
from pydantic import ValidationError

from antipasta.core.config import AntipastaConfig


def save_config(config: AntipastaConfig, output: Path) -> None:
    """Save configuration to file with helpful comments."""
    # Convert to dict for customization
    data = config.model_dump(exclude_none=True, mode="json")

    # Create YAML content with comments
    yaml_lines = []
    yaml_lines.append("# antipasta configuration file")  # noqa: FURB113
    yaml_lines.append("# Generated by: antipasta config generate")
    yaml_lines.append("")
    yaml_lines.append("# Default thresholds for all languages")
    yaml_lines.append("defaults:")

    defaults = data.get("defaults", {})
    cyclo_max = defaults.get("max_cyclomatic_complexity", 10)
    cog_max = defaults.get("max_cognitive_complexity", 15)
    maint_min = defaults.get("min_maintainability_index", 50)
    yaml_lines.append(f"  max_cyclomatic_complexity: {cyclo_max}")  # noqa: FURB113
    yaml_lines.append(f"  max_cognitive_complexity: {cog_max}")
    yaml_lines.append(f"  min_maintainability_index: {maint_min}")
    yaml_lines.append("  # Halstead metrics (advanced)")
    yaml_lines.append(f"  max_halstead_volume: {defaults.get('max_halstead_volume', 1000)}")
    yaml_lines.append(f"  max_halstead_difficulty: {defaults.get('max_halstead_difficulty', 10)}")
    yaml_lines.append(f"  max_halstead_effort: {defaults.get('max_halstead_effort', 10000)}")

    yaml_lines.append("")
    yaml_lines.append("# Language-specific configurations")
    yaml_lines.append("languages:")

    for lang in data.get("languages", []):
        yaml_lines.append(f"  - name: {lang['name']}")
        if lang.get("extensions"):
            yaml_lines.append("    extensions:")
            for ext in lang["extensions"]:
                yaml_lines.append(f"      - {ext}")
        yaml_lines.append("    metrics:")
        for metric in lang.get("metrics", []):
            yaml_lines.append(f"      - type: {metric['type']}")  # noqa: FURB113
            yaml_lines.append(f"        threshold: {metric['threshold']}")
            yaml_lines.append(f'        comparison: "{metric["comparison"]}"')
            if metric != lang["metrics"][-1]:  # Not the last metric
                yaml_lines.append("")

    yaml_lines.append("")  # noqa: FURB113
    yaml_lines.append("# Files and patterns to ignore during analysis")
    patterns = data.get("ignore_patterns", [])
    if patterns:
        yaml_lines.append("ignore_patterns:")
        for pattern in patterns:
            yaml_lines.append(f'  - "{pattern}"')
    else:
        yaml_lines.append("ignore_patterns: []")

    yaml_lines.append("")  # noqa: FURB113
    yaml_lines.append("# Whether to use .gitignore file for excluding files")
    yaml_lines.append(f"use_gitignore: {str(data.get('use_gitignore', True)).lower()}")

    # Write file
    try:
        Path(output).write_text("\n".join(yaml_lines) + "\n")

        click.echo(f"✅ Configuration saved to {output}")
        click.echo(f"\nRun 'antipasta config validate {output}' to verify.")
        click.echo("Run 'antipasta metrics' to start analyzing your code!")

    except Exception as e:
        click.echo(f"❌ Error saving configuration: {e}", err=True)
        sys.exit(1)


def confirm_file_overwrite(output: Path) -> bool:
    """Confirm file overwrite if file exists.

    Args:
        output: Output file path.

    Returns:
        True if should proceed, False otherwise.
    """
    click.echo(f"\nConfiguration will be saved to: {output}")

    if output.exists() and not click.confirm("File already exists. Overwrite?", default=False):
        click.echo("Aborted.")
        return False

    return True


def create_validated_config(config_dict: dict[str, Any]) -> AntipastaConfig:
    """Create and validate configuration object.

    Args:
        config_dict: Configuration dictionary.

    Returns:
        Validated AntipastaConfig object.

    Raises:
        SystemExit: If validation fails.
    """
    try:
        return AntipastaConfig(**config_dict)
    except ValidationError as e:
        handle_validation_error(e)
        sys.exit(1)
    except Exception as e:
        click.echo(f"\n❌ Unexpected error creating configuration: {e}", err=True)
        sys.exit(1)


def handle_validation_error(error: ValidationError) -> None:
    """Handle and display validation errors.

    Args:
        error: ValidationError from Pydantic.
    """
    click.echo("\n❌ Configuration validation failed:", err=True)
    for err in error.errors():
        loc = " -> ".join(str(x) for x in err["loc"])
        click.echo(f"  - {loc}: {err['msg']}", err=True)
    click.echo("\nPlease run the command again with valid values.", err=True)
