import unreal


RECIPE_FOLDER = "/Game/Agrarian/DataAssets/Recipes"

EXPECTED_RECIPES = {
    "DA_Recipe_Campfire": {
        "recipe_id": "campfire",
        "ingredients": {"wood": 5, "stone": 8, "fiber": 2},
        "result": ("campfire", 1),
    },
    "DA_Recipe_PrimitiveShelter": {
        "recipe_id": "primitive_shelter",
        "ingredients": {
            "primitive_frame": 2,
            "primitive_wall_panel": 4,
            "primitive_roof_panel": 2,
            "hide": 2,
            "fiber": 6,
        },
        "result": ("primitive_shelter", 1),
    },
    "DA_Recipe_PrimitiveFrame": {
        "recipe_id": "primitive_frame",
        "ingredients": {"wood": 4, "fiber": 2},
        "result": ("primitive_frame", 1),
    },
    "DA_Recipe_PrimitiveWallPanel": {
        "recipe_id": "primitive_wall_panel",
        "ingredients": {"wood": 3, "fiber": 2},
        "result": ("primitive_wall_panel", 1),
    },
    "DA_Recipe_PrimitiveRoofPanel": {
        "recipe_id": "primitive_roof_panel",
        "ingredients": {"wood": 3, "fiber": 3},
        "result": ("primitive_roof_panel", 1),
    },
    "DA_Recipe_BasicTool": {
        "recipe_id": "basic_tool",
        "ingredients": {"wood": 1, "stone": 2, "fiber": 1},
        "result": ("basic_tool", 1),
    },
    "DA_Recipe_SimpleContainer": {
        "recipe_id": "simple_container",
        "ingredients": {"wood": 3, "fiber": 6, "hide": 2},
        "result": ("simple_container", 1),
    },
    "DA_Recipe_Bandage": {
        "recipe_id": "bandage",
        "ingredients": {"fiber": 3, "hide": 1},
        "result": ("bandage", 1),
    },
}


def stack_item_id(stack):
    return str(stack.get_editor_property("item_id"))


def main():
    missing = []

    for asset_name, expected in EXPECTED_RECIPES.items():
        path = f"{RECIPE_FOLDER}/{asset_name}"
        asset = unreal.EditorAssetLibrary.load_asset(path)
        if not asset:
            missing.append(f"{path} missing")
            continue

        recipe = asset.get_editor_property("recipe")
        recipe_id = str(recipe.get_editor_property("recipe_id"))
        display_name = str(recipe.get_editor_property("display_name"))
        craft_seconds = recipe.get_editor_property("craft_seconds")
        result = recipe.get_editor_property("result")
        ingredients = list(recipe.get_editor_property("ingredients"))

        if recipe_id != expected["recipe_id"]:
            missing.append(f"{path} recipe_id expected {expected['recipe_id']}, got {recipe_id}")
        if not display_name:
            missing.append(f"{path} display_name empty")
        if craft_seconds <= 0.0:
            missing.append(f"{path} craft_seconds must be positive")

        expected_result_id, expected_result_quantity = expected["result"]
        if stack_item_id(result) != expected_result_id:
            missing.append(f"{path} result id expected {expected_result_id}, got {stack_item_id(result)}")
        if result.get_editor_property("quantity") != expected_result_quantity:
            missing.append(f"{path} result quantity expected {expected_result_quantity}")
        if result.get_editor_property("unit_weight") <= 0.0:
            missing.append(f"{path} result unit weight must be positive")

        actual_ingredients = {stack_item_id(stack): stack for stack in ingredients}
        for expected_item_id, expected_quantity in expected["ingredients"].items():
            stack = actual_ingredients.get(expected_item_id)
            if not stack:
                missing.append(f"{path} missing ingredient {expected_item_id}")
                continue
            if stack.get_editor_property("quantity") != expected_quantity:
                missing.append(f"{path} ingredient {expected_item_id} expected quantity {expected_quantity}")
            if stack.get_editor_property("unit_weight") <= 0.0:
                missing.append(f"{path} ingredient {expected_item_id} unit weight must be positive")

        unexpected = set(actual_ingredients.keys()) - set(expected["ingredients"].keys())
        if unexpected:
            missing.append(f"{path} has unexpected ingredients: {sorted(unexpected)}")

    if missing:
        raise RuntimeError("Recipe definition verification failed: " + "; ".join(missing))

    unreal.log("Agrarian recipe definition verification complete.")


main()
