"""
Parses EnhDB.mhd -> enhancements[], enhancement_sets[]

Field order verified against MidsReborn/Core/Enhancement.cs (`Enhancement(BinaryReader)`)
and MidsReborn/Core/EnhancementSet.cs (`EnhancementSet(BinaryReader)`).
"""
from mhd_reader import MhdReader
from effect_schema import read_effect
from enums import E_TYPE, E_ENH_MUTEX, E_BUFF_DEBUFF, E_EFF_MODE, E_SCHEDULE, E_PVX, name_of

HEADER = "Mids Reborn Enhancement Database"


def read_enhancement(r):
    d = {}
    d["static_index"] = r.read_int32()
    d["name"] = r.read_string()
    d["short_name"] = r.read_string()
    d["desc"] = r.read_string()
    d["type_id"] = name_of(E_TYPE, r.read_int32())
    d["sub_type_id"] = r.read_int32()
    d["class_id"] = r.read_int32_array()
    d["image"] = r.read_string()
    d["n_id_set"] = r.read_int32()
    d["uid_set"] = r.read_string()
    d["effect_chance"] = r.read_single()
    d["level_min"] = r.read_int32()
    d["level_max"] = r.read_int32()
    d["unique"] = r.read_boolean()
    mut_ex = r.read_int32()
    d["mut_ex_id"] = name_of(E_ENH_MUTEX, mut_ex if mut_ex >= 0 else 0)
    d["buff_mode"] = name_of(E_BUFF_DEBUFF, r.read_int32())

    effect_count = r.read_int32() + 1
    effects = []
    for _ in range(effect_count):
        mode = name_of(E_EFF_MODE, r.read_int32())
        buff_mode = name_of(E_BUFF_DEBUFF, r.read_int32())
        enhance_id = r.read_int32()
        enhance_sub_id = r.read_int32()
        schedule = name_of(E_SCHEDULE, r.read_int32())
        multiplier = r.read_single()
        has_fx = r.read_boolean()
        fx = read_effect(r) if has_fx else None
        effects.append({
            "mode": mode,
            "buff_mode": buff_mode,
            "enhance_id": enhance_id,
            "enhance_sub_id": enhance_sub_id,
            "schedule": schedule,
            "multiplier": multiplier,
            "fx": fx,
        })
    d["effect"] = effects

    d["uid"] = r.read_string()
    d["recipe_name"] = r.read_string()
    d["superior"] = r.read_boolean()
    d["is_proc"] = r.read_boolean()
    d["is_scalable"] = r.read_boolean()
    return d


def _read_bonus_item(r, has_pv_mode):
    special = r.read_int32()
    alt_string = r.read_string()
    pv_mode = name_of(E_PVX, r.read_int32()) if has_pv_mode else None
    slotted = r.read_int32() if has_pv_mode else None
    name_count = r.read_int32() + 1
    names = []
    indexes = []
    for _ in range(name_count):
        names.append(r.read_string())
        indexes.append(r.read_int32())
    item = {"special": special, "alt_string": alt_string, "names": names, "power_indexes_raw": indexes}
    if has_pv_mode:
        item["pv_mode"] = pv_mode
        item["slotted"] = slotted
    return item


def read_enhancement_set(r):
    d = {}
    d["display_name"] = r.read_string()
    d["short_name"] = r.read_string()
    d["uid"] = r.read_string()
    d["desc"] = r.read_string()
    d["set_type"] = r.read_int32()  # index into TypeGrades.json SetTypes
    d["image"] = r.read_string()
    d["level_min"] = r.read_int32()
    d["level_max"] = r.read_int32()
    d["enhancement_indexes"] = r.read_int32_array()

    bonus_count = r.read_int32() + 1
    d["bonus"] = [_read_bonus_item(r, has_pv_mode=True) for _ in range(bonus_count)]

    special_bonus_count = r.read_int32() + 1
    d["special_bonus"] = [_read_bonus_item(r, has_pv_mode=False) for _ in range(special_bonus_count)]

    return d


def parse_enhdb(path):
    r = MhdReader(path)
    try:
        r.expect_string(HEADER)
        r.read_single()  # version float, unused

        enh_count = r.read_int32() + 1
        enhancements = [read_enhancement(r) for _ in range(enh_count)]

        set_count = r.read_int32() + 1
        enhancement_sets = [read_enhancement_set(r) for _ in range(set_count)]

        return {"enhancements": enhancements, "enhancement_sets": enhancement_sets}
    finally:
        r.close()


if __name__ == "__main__":
    import json
    import sys

    path = sys.argv[1] if len(sys.argv) > 1 else \
        "/home/claude/mids-reborn/MidsReborn/Databases/Homecoming/EnhDB.mhd"
    result = parse_enhdb(path)
    print(f"Parsed {len(result['enhancements'])} enhancements, "
          f"{len(result['enhancement_sets'])} enhancement sets", file=sys.stderr)
    print(json.dumps(result, indent=None)[:2000])
