"""Workflow for updating map/category options in the UMC and triggering mapcycle regeneration."""

from pathlib import Path
from typing import Any

from filelock import FileLock

from core import constants
from core.domain.umc_operations import set_category_option, set_map_option
from core.io.umc_parser import parse_umc_file
from core.io.umc_writer import write
from core.logger_config import logger
from core.services.mapcycle_service import regenerate_umc_mapcycle

# ==========================================================================
# VALIDATION
# ==========================================================================


def validate_payload(payload: dict[str, Any]) -> None:
    """Validate the payload received from the frontend."""
    if not isinstance(payload, dict):
        raise ValueError("Payload must be a dictionary.")
    if "categories" not in payload:
        raise ValueError("Missing 'categories' field.")


# ==========================================================================
# APPLICATION DES MODIFICATIONS
# ==========================================================================


def _apply_category_options(
    umc_data: dict[str, Any], category_name: str, options: dict[str, Any]
) -> None:
    """Apply all category options."""
    for key, value in options.items():
        set_category_option(umc_data, category_name, key, value)


def _apply_map_options(umc_data: dict[str, Any], category_name: str, maps: dict[str, Any]) -> None:
    """Apply all map options."""
    for map_name, map_options in maps.items():
        for key, value in map_options.items():
            set_map_option(umc_data, category_name, map_name, key, value)


# ==========================================================================
# SERVICE
# ==========================================================================


def update_umc_options(payload: dict[str, Any], destination: Path | None = None) -> dict[str, Any]:
    """Replaces the UMC configuration with the one received from Category Manager."""
    validate_payload(payload)
    destination = destination or constants.UMC_MASTER_FILE
    lock = destination.with_suffix(".lock")
    logger.info("Updating UMC configuration...")
    with FileLock(lock, timeout=10):
        current_data = parse_umc_file(destination)
        new_data: dict[str, Any] = {}
        for category_name, category_payload in payload["categories"].items():
            if category_name not in current_data:
                logger.warning(f"Unknown category ignored: {category_name}")
                continue
            new_data[category_name] = {
                "options": dict(category_payload.get("options", {})),
                "maps": {},
            }
            current_maps = current_data[category_name].get("maps", {})
            for map_name, map_options in category_payload.get("maps", {}).items():
                if map_name not in current_maps:
                    logger.warning(
                        f"Unknown map '{map_name}' ignored in category '{category_name}'."
                    )
                    continue
                new_data[category_name]["maps"][map_name] = dict(map_options)
        write(destination=destination, umc_data=new_data)
        regenerate_umc_mapcycle()
    logger.info("UMC updated successfully.")
    return {"status": "success"}
