from core.services.delete_service import delete_map_files
from core import constants
from core.constants import CATEGORY_OPTIONS, MAP_OPTIONS
from core.io.umc_parser import parse_umc_file
from core.io.umc_writer import write
from core.services.map_install_service import (
    add_existing_maps_to_category,
    get_sorted_categories_workflow,
    handle_maps_installation_workflow,
)
from core.services.mapcycle_service import regenerate_umc_mapcycle
from flask import Blueprint, abort, request
from web.routes.api.utils import ApiResponse, handle_api_response

maps_api = Blueprint("maps_api", __name__)


@maps_api.route("/install", methods=["POST"])
def install() -> ApiResponse:
    """Rough guide for installing BSP cards."""
    response_data = handle_maps_installation_workflow(
        flask_files=request.files.getlist("maps"),
        category_name=request.form.get("category_name"),
        category_options_raw=request.form.get("category_options"),
        maps_options_raw=request.form.get("maps_options"),
    )

    return handle_api_response(response_data)


@maps_api.route("/options")
def get_options() -> ApiResponse:
    """Returns the available configurations and options for categories and maps."""
    data = {"status": "success", "category_options": CATEGORY_OPTIONS, "map_options": MAP_OPTIONS}

    return handle_api_response(data)


@maps_api.route("/categories")
def get_categories() -> ApiResponse:
    """Returns the sorted list of categories in a standardized format."""
    categories = get_sorted_categories_workflow()
    return handle_api_response({"status": "success", "categories": categories})


@maps_api.route("/update", methods=["POST"])
def api_update_map() -> ApiResponse:
    """Updates a map's options in real time for a specific category."""
    req_data = request.json
    map_name = req_data.get("map_name")
    category = req_data.get("category")

    if not map_name or not category:
        abort(400, description="Missing parameters (map_name or category).")

    master_data = parse_umc_file(constants.UMC_MASTER_FILE)

    if (
        category not in master_data
        or "maps" not in master_data[category]
        or map_name not in master_data[category]["maps"]
    ):
        abort(404, description="Map not found in the selected category of UMC Master.")

    map_data = master_data[category]["maps"][map_name]

    for field in ["target_mods", "command", "weight"]:
        val = req_data.get(field)
        val_str = str(val).strip() if val is not None else ""

        if val_str:
            map_data[field] = val_str
        elif field in map_data:
            del map_data[field]

    write(constants.UMC_MASTER_FILE, master_data, create_backup=True)
    regenerate_umc_mapcycle()

    return handle_api_response({"status": "success"})


@maps_api.route("/delete", methods=["POST"])
def api_delete_map() -> ApiResponse:
    """Permanently deletes a map from the UMC."""
    req_data = request.json
    map_name = req_data.get("map_name")
    category = req_data.get("category")

    master_data = parse_umc_file(constants.UMC_MASTER_FILE)

    if (
        category in master_data
        and "maps" in master_data[category]
        and map_name in master_data[category]["maps"]
    ):
        del master_data[category]["maps"][map_name]

        write(constants.UMC_MASTER_FILE, master_data, create_backup=True)
        regenerate_umc_mapcycle()
        return handle_api_response({"status": "success"})

    abort(404, description="Map not found.")
    return None


@maps_api.route("/delete_all", methods=["POST"])
def api_delete_map_completely() -> ApiResponse:
    """Permanently deletes a map from all categories in the UMC."""
    req_data = request.json
    map_name = req_data.get("map_name")
    if not map_name:
        abort(400, description="Missing parameter: map_name.")
    master_data = parse_umc_file(constants.UMC_MASTER_FILE)
    map_found = False
    for category_name in master_data:
        if "maps" in master_data[category_name] and map_name in master_data[category_name]["maps"]:
            del master_data[category_name]["maps"][map_name]
            map_found = True
    if not map_found:
        abort(404, description="Map not found in any category.")
    write(constants.UMC_MASTER_FILE, master_data, create_backup=True)
    regenerate_umc_mapcycle()

    return handle_api_response({"status": "success"})


@maps_api.route("/add_existing", methods=["POST"])
def api_add_existing_maps() -> ApiResponse:
    """Adds existing maps to a category."""
    req_data = request.get_json(silent=True) or {}
    response_data = add_existing_maps_to_category(
        category_name=req_data.get("category_name", ""),
        category_options=req_data.get("category_options", {}),
        maps=req_data.get("maps", {}),
    )
    regenerate_umc_mapcycle()
    return handle_api_response(response_data)

@maps_api.route("/delete_files", methods=["POST"])
def api_delete_map_files() -> ApiResponse:
    """Deletes the physical files of a map if it is no longer referenced."""

    req_data = request.get_json(silent=True) or {}
    map_name = req_data.get("map_name", "").strip()
    if not map_name:
        abort(400, description="Missing parameter: map_name.")
    response_data = delete_map_files(map_name)
    return handle_api_response(response_data)
