"""Export every tile to real NWN ASCII .mdl + .wok via Neverblender (Blender 4.0.2).

    blender-4.0.2 --background <built.blend> --python export_mdl.py -- <outdir> [CODE ...]

Requires the Neverblender addon enabled in this Blender (Import-Export:
Neverblender). Confirmed working headless against ~/.config/blender/4.0. For each
tile it assembles a Neverblender-native model in its own scene — an AuroraBase
(Empty, classification TILE, name == resref), a trimesh child (the VIS geometry),
and one aabb walkmesh child (from tiles.wok_quads) — then calls
scene.nvb_mdlexport(export_walkmesh=True) to emit <resref>.mdl and <resref>.wok.

Walkmesh surface materials use Neverblender's name->surfacemat mapping
(nvb_def.wok_materials): walkable faces = wok_Stone (idx 4), blockers = wok_Nonwalk
(idx 7). Refine per tile later (wok_Water/wok_StoneBridge/etc.) if desired.
"""

import os
import sys

import bpy
import addon_utils

sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import tiles  # noqa: E402

# Neverblender writes each walkmesh face's material_index (slot) verbatim as the
# surfacemat id (nvb_node.py), and create_wok_materials() fills slots 0..22 in
# nvb_def.wok_materials order. So the slot index IS the surfacemat index:
WALK_SURF = 4    # wok_Stone
BLOCK_SURF = 7   # wok_Nonwalk


def build_wok(spec, name):
    from neverblender import nvb_utils
    quads = tiles.wok_quads(spec)
    verts, faces, surf = [], [], []
    for quad, walk in quads:
        b = len(verts)
        verts += quad
        faces.append((b, b + 1, b + 2, b + 3))
        surf.append(WALK_SURF if walk else BLOCK_SURF)
    me = bpy.data.meshes.new(name)
    me.from_pydata(verts, [], faces)
    nvb_utils.create_wok_materials(me)          # slots 0..22 == wok_materials order
    me.update()
    for poly, s in zip(me.polygons, surf):
        poly.material_index = s                 # slot == surfacemat id on export
    ob = bpy.data.objects.new(name, me)
    ob.nvb.meshtype = "aabb"
    return ob


def export_tile(spec, outdir):
    ref = tiles.resref(spec)
    vis = bpy.data.objects.get("VIS_" + spec["code"])
    if vis is None:
        return {"code": spec["code"], "ok": False, "error": "missing VIS object"}

    scn = bpy.data.scenes.new("exp_" + spec["code"])
    bpy.context.window.scene = scn

    root = bpy.data.objects.new(ref, None)          # AuroraBase; name == filename
    root.nvb.emptytype = "dummy"
    root.nvb.classification = "tile"
    scn.collection.objects.link(root)

    v = vis.copy()
    v.data = vis.data.copy()
    v.name = ref + "_01"
    v.nvb.meshtype = "trimesh"
    scn.collection.objects.link(v)
    v.parent = root

    w = build_wok(spec, ref + "_wg")                # single aabb walkmesh (rule: 1 per tile)
    scn.collection.objects.link(w)
    w.parent = root

    mdl = os.path.join(outdir, ref + ".mdl")
    bpy.ops.scene.nvb_mdlexport(filepath=mdl, export_walkmesh=True,
                                check_existing=False, batch_mode="OFF")
    wok = os.path.join(outdir, ref + ".wok")
    return {"code": spec["code"], "ref": ref, "ok": os.path.isfile(mdl),
            "mdl": os.path.isfile(mdl), "wok": os.path.isfile(wok)}


def main():
    argv = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
    outdir = os.path.abspath(argv[0]) if argv else os.path.abspath("mdl")
    only = set(argv[1:])
    os.makedirs(outdir, exist_ok=True)

    addon_utils.enable("neverblender", default_set=False)

    results = [export_tile(s, outdir) for s in tiles.TILES if not only or s["code"] in only]
    ok = sum(1 for r in results if r["ok"])
    bad = [r for r in results if not r["ok"]]
    print(f"EXPORTED {ok}/{len(results)} tiles -> {outdir}")
    if bad:
        print("FAILED:", bad)


if __name__ == "__main__":
    main()
