bl_info = {
    "name": "Snow Trail Export",
    "author": "Snow Trail",
    "version": (1, 0, 0),
    "blender": (5, 0, 0),
    "location": "3D Viewport > Sidebar > Snow Trail",
    "description": "One-click glTF export to project assets folder",
    "category": "Import-Export",
}

import bpy
from pathlib import Path


def find_project_root():
    blend_path = Path(bpy.data.filepath)
    if not blend_path.exists():
        return None
    candidate = blend_path.parent
    while candidate != candidate.parent:
        if (candidate / "assets").is_dir() and (candidate / "blender").is_dir():
            return candidate
        candidate = candidate.parent
    return None


def get_export_path():
    blend_path = Path(bpy.data.filepath)
    project_root = find_project_root()
    if project_root is None:
        return None
    stem = blend_path.stem
    return project_root / "assets" / "meshes" / f"{stem}.gltf"


class SNOWTRAIL_OT_export_gltf(bpy.types.Operator):
    bl_idname = "snow_trail.export_gltf"
    bl_label = "Export to Project"
    bl_description = "Export selected objects as glTF to assets/meshes/"
    bl_options = {'REGISTER'}

    def execute(self, context):
        if not bpy.data.filepath:
            self.report({'ERROR'}, "Save the .blend file first")
            return {'CANCELLED'}

        export_path = get_export_path()
        if export_path is None:
            self.report({'ERROR'}, "Could not find project root (looking for assets/ + blender/ dirs)")
            return {'CANCELLED'}

        export_path.parent.mkdir(parents=True, exist_ok=True)

        selected = [obj for obj in context.selected_objects if obj.type == 'MESH']
        if not selected:
            self.report({'ERROR'}, "No mesh objects selected")
            return {'CANCELLED'}

        props = context.scene.snow_trail_export

        bpy.ops.export_scene.gltf(
            filepath=str(export_path),
            export_format='GLTF_SEPARATE',
            use_selection=True,
            export_apply=props.apply_modifiers,
            export_yup=True,
            export_texcoords=True,
            export_normals=True,
            export_colors=props.export_vertex_colors,
            export_materials='NONE' if not props.export_materials else 'EXPORT',
            export_animations=props.export_animations,
        )

        rel_path = export_path.relative_to(find_project_root())
        self.report({'INFO'}, f"Exported → {rel_path}")
        return {'FINISHED'}


class SNOWTRAIL_OT_export_heightmap(bpy.types.Operator):
    bl_idname = "snow_trail.export_heightmap"
    bl_label = "Bake Heightmap"
    bl_description = "Run heightmap bake script for selected terrain"
    bl_options = {'REGISTER'}

    def execute(self, context):
        project_root = find_project_root()
        if project_root is None:
            self.report({'ERROR'}, "Could not find project root")
            return {'CANCELLED'}

        script_path = project_root / "blender" / "scripts" / "generate_heightmap.py"
        if not script_path.exists():
            self.report({'ERROR'}, f"Script not found: {script_path}")
            return {'CANCELLED'}

        import importlib.util
        spec = importlib.util.spec_from_file_location("generate_heightmap", str(script_path))
        mod = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(mod)

        terrain_obj = context.active_object
        if terrain_obj is None or terrain_obj.type != 'MESH':
            self.report({'ERROR'}, "Select a mesh object first")
            return {'CANCELLED'}

        output_path = project_root / "assets" / "textures" / "terrain_heightmap.exr"
        mod.bake_heightmap(
            terrain_obj=terrain_obj,
            resolution=context.scene.snow_trail_export.heightmap_resolution,
            output_path=str(output_path),
        )

        self.report({'INFO'}, f"Heightmap → assets/textures/terrain_heightmap.exr")
        return {'FINISHED'}


class SNOWTRAIL_ExportProperties(bpy.types.PropertyGroup):
    apply_modifiers: bpy.props.BoolProperty(
        name="Apply Modifiers",
        default=True,
        description="Apply modifiers before export",
    )
    export_vertex_colors: bpy.props.BoolProperty(
        name="Vertex Colors",
        default=True,
        description="Export vertex colors",
    )
    export_materials: bpy.props.BoolProperty(
        name="Materials",
        default=False,
        description="Export materials (usually not needed for retro aesthetic)",
    )
    export_animations: bpy.props.BoolProperty(
        name="Animations",
        default=False,
        description="Export animations",
    )
    heightmap_resolution: bpy.props.IntProperty(
        name="Heightmap Resolution",
        default=1024,
        min=128,
        max=4096,
        description="Resolution for heightmap bake",
    )


class SNOWTRAIL_PT_export_panel(bpy.types.Panel):
    bl_label = "Snow Trail Export"
    bl_idname = "SNOWTRAIL_PT_export_panel"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
    bl_category = "Snow Trail"

    def draw(self, context):
        layout = self.layout
        props = context.scene.snow_trail_export

        export_path = get_export_path()
        if export_path:
            project_root = find_project_root()
            rel = export_path.relative_to(project_root)
            layout.label(text=f"Target: {rel}", icon='FILE')
        elif not bpy.data.filepath:
            layout.label(text="Save .blend file first!", icon='ERROR')
        else:
            layout.label(text="Project root not found!", icon='ERROR')

        layout.separator()

        box = layout.box()
        box.label(text="glTF Options:", icon='MESH_DATA')
        box.prop(props, "apply_modifiers")
        box.prop(props, "export_vertex_colors")
        box.prop(props, "export_materials")
        box.prop(props, "export_animations")

        selected_meshes = [o for o in context.selected_objects if o.type == 'MESH']
        row = layout.row()
        row.scale_y = 1.5
        row.operator("snow_trail.export_gltf", icon='EXPORT')
        if not selected_meshes:
            row.enabled = False

        if selected_meshes:
            layout.label(text=f"{len(selected_meshes)} mesh(es) selected")
        else:
            layout.label(text="Select mesh objects to export", icon='INFO')

        layout.separator()

        box = layout.box()
        box.label(text="Terrain Tools:", icon='WORLD')
        box.prop(props, "heightmap_resolution")
        box.operator("snow_trail.export_heightmap", icon='IMAGE_DATA')


classes = (
    SNOWTRAIL_ExportProperties,
    SNOWTRAIL_OT_export_gltf,
    SNOWTRAIL_OT_export_heightmap,
    SNOWTRAIL_PT_export_panel,
)


def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    bpy.types.Scene.snow_trail_export = bpy.props.PointerProperty(type=SNOWTRAIL_ExportProperties)


def unregister():
    del bpy.types.Scene.snow_trail_export
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)


if __name__ == "__main__":
    register()
