bl_info = {
    "name": "IGNLab Web GLB Exporter",
    "author": "IGNLab",
    "version": (1, 0, 0),
    "blender": (3, 6, 0),
    "location": "3D View > Sidebar > IGNLab",
    "description": "Export the current Blender scene as a web-ready GLB for IGNLab 3D",
    "category": "Import-Export",
}

import os
import bpy
from bpy.props import BoolProperty, StringProperty
from bpy_extras.io_utils import ExportHelper


class IGNLAB_OT_export_glb(bpy.types.Operator, ExportHelper):
    bl_idname = "ignlab.export_web_glb"
    bl_label = "Export web-ready GLB"
    bl_description = "Export locally with materials, textures and animation packed into one GLB"
    bl_options = {"REGISTER"}

    filename_ext = ".glb"
    filter_glob: StringProperty(default="*.glb", options={"HIDDEN"})
    selected_only: BoolProperty(
        name="Selected objects only",
        description="Export only selected objects instead of the complete scene",
        default=False,
    )
    apply_modifiers: BoolProperty(
        name="Apply modifiers",
        description="Apply compatible modifiers during export",
        default=True,
    )

    def invoke(self, context, event):
        source_name = os.path.splitext(os.path.basename(bpy.data.filepath))[0] or "ignlab-model"
        source_dir = os.path.dirname(bpy.data.filepath) or os.path.expanduser("~")
        self.filepath = os.path.join(source_dir, source_name + ".glb")
        return ExportHelper.invoke(self, context, event)

    def execute(self, context):
        if not self.filepath.lower().endswith(".glb"):
            self.filepath += ".glb"

        try:
            available = {item.identifier for item in bpy.ops.export_scene.gltf.get_rna_type().properties}
        except Exception:
            available = set()

        desired = {
            "filepath": self.filepath,
            "export_format": "GLB",
            "check_existing": True,
            "use_selection": self.selected_only,
            "export_apply": self.apply_modifiers,
            "export_texcoords": True,
            "export_normals": True,
            "export_tangents": True,
            "export_materials": "EXPORT",
            "export_image_format": "AUTO",
            "export_cameras": False,
            "export_lights": False,
            "export_animations": True,
            "export_skins": True,
            "export_morph": True,
            "export_yup": True,
        }
        options = ({key: value for key, value in desired.items() if key in available}
                   if available else {
                       "filepath": self.filepath,
                       "export_format": "GLB",
                       "use_selection": self.selected_only,
                   })

        try:
            result = bpy.ops.export_scene.gltf(**options)
        except Exception as error:
            self.report({"ERROR"}, "GLB export failed: " + str(error))
            return {"CANCELLED"}

        if "FINISHED" not in result:
            self.report({"ERROR"}, "Blender did not finish the GLB export")
            return {"CANCELLED"}

        self.report({"INFO"}, "GLB ready for 3d.ignlab.net: " + self.filepath)
        return {"FINISHED"}


class IGNLAB_PT_web_export(bpy.types.Panel):
    bl_label = "IGNLab Web Export"
    bl_idname = "IGNLAB_PT_web_export"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    bl_category = "IGNLab"

    def draw(self, context):
        layout = self.layout
        layout.label(text="Private local GLB export")
        layout.operator(IGNLAB_OT_export_glb.bl_idname, icon="EXPORT")
        layout.separator()
        layout.label(text="Then open the GLB at:")
        layout.label(text="3d.ignlab.net", icon="URL")


def export_menu(self, context):
    self.layout.operator(IGNLAB_OT_export_glb.bl_idname, text="IGNLab web-ready GLB (.glb)")


CLASSES = (IGNLAB_OT_export_glb, IGNLAB_PT_web_export)


def register():
    for item in CLASSES:
        bpy.utils.register_class(item)
    bpy.types.TOPBAR_MT_file_export.append(export_menu)


def unregister():
    bpy.types.TOPBAR_MT_file_export.remove(export_menu)
    for item in reversed(CLASSES):
        bpy.utils.unregister_class(item)


if __name__ == "__main__":
    register()
