import bpy
import json
import math
import os
from mathutils import Vector


MODEL_PATH = "/home/vela/Downloads/model (2).glb"
OUTPUT_DIR = "/home/vela/workspace/domain/tn-silver/web/tn-site/.runtime/model2-inspect"


def look_at(obj, target):
    direction = Vector(target) - obj.location
    obj.rotation_euler = direction.to_track_quat("-Z", "Y").to_euler()


bpy.ops.object.select_all(action="SELECT")
bpy.ops.object.delete(use_global=False)
bpy.ops.import_scene.gltf(filepath=MODEL_PATH)

mesh_objects = [obj for obj in bpy.context.scene.objects if obj.type == "MESH"]
if not mesh_objects:
    raise RuntimeError("No mesh objects imported")

world_corners = []
for obj in mesh_objects:
    world_corners.extend([obj.matrix_world @ Vector(corner) for corner in obj.bound_box])

minimum = Vector((
    min(point.x for point in world_corners),
    min(point.y for point in world_corners),
    min(point.z for point in world_corners),
))
maximum = Vector((
    max(point.x for point in world_corners),
    max(point.y for point in world_corners),
    max(point.z for point in world_corners),
))
center = (minimum + maximum) * 0.5
extent = maximum - minimum

scene = bpy.context.scene
scene.render.engine = "BLENDER_EEVEE"
scene.render.resolution_x = 960
scene.render.resolution_y = 960
scene.render.resolution_percentage = 100
scene.render.image_settings.file_format = "PNG"
scene.render.film_transparent = False
scene.render.image_settings.color_mode = "RGBA"
scene.view_settings.look = "AgX - Medium High Contrast"
scene.world.color = (0.055, 0.05, 0.047)

camera_data = bpy.data.cameras.new("InspectionCamera")
camera = bpy.data.objects.new("InspectionCamera", camera_data)
scene.collection.objects.link(camera)
scene.camera = camera
camera.data.type = "ORTHO"
camera.data.ortho_scale = max(extent.z * 1.14, extent.x * 1.24, extent.y * 1.24)

key_data = bpy.data.lights.new(name="Key", type="AREA")
key_data.energy = 1500
key_data.shape = "DISK"
key_data.size = max(extent) * 1.2
key = bpy.data.objects.new(name="Key", object_data=key_data)
scene.collection.objects.link(key)
key.location = center + Vector((max(extent) * 1.1, -max(extent) * 1.1, max(extent) * 1.5))
look_at(key, center)

fill_data = bpy.data.lights.new(name="Fill", type="AREA")
fill_data.energy = 700
fill_data.size = max(extent) * 1.4
fill = bpy.data.objects.new(name="Fill", object_data=fill_data)
scene.collection.objects.link(fill)
fill.location = center + Vector((-max(extent) * 1.1, max(extent) * 0.7, max(extent) * 0.8))
look_at(fill, center)

rim_data = bpy.data.lights.new(name="Rim", type="AREA")
rim_data.energy = 1100
rim_data.size = max(extent) * 0.9
rim = bpy.data.objects.new(name="Rim", object_data=rim_data)
scene.collection.objects.link(rim)
rim.location = center + Vector((0, max(extent) * 1.3, max(extent) * 1.2))
look_at(rim, center)

radius = max(extent) * 3.2
elevation = center.z + extent.z * 0.06
for angle in range(0, 360, 45):
    radians = math.radians(angle)
    camera.location = Vector((
        center.x + math.sin(radians) * radius,
        center.y - math.cos(radians) * radius,
        elevation,
    ))
    look_at(camera, center)
    scene.render.filepath = os.path.join(OUTPUT_DIR, f"angle-{angle:03d}.png")
    bpy.ops.render.render(write_still=True)

metadata = {
    "mesh_count": len(mesh_objects),
    "object_count": len(bpy.context.scene.objects),
    "vertices": sum(len(obj.data.vertices) for obj in mesh_objects),
    "triangles": sum(len(obj.data.loop_triangles) for obj in mesh_objects),
    "materials": sorted({slot.material.name for obj in mesh_objects for slot in obj.material_slots if slot.material}),
    "images": [
        {
            "name": image.name,
            "size": list(image.size),
            "source": image.source,
        }
        for image in bpy.data.images
    ],
    "bounds_min": list(minimum),
    "bounds_max": list(maximum),
    "extent": list(extent),
    "objects": [
        {
            "name": obj.name,
            "vertices": len(obj.data.vertices),
            "polygons": len(obj.data.polygons),
            "dimensions": list(obj.dimensions),
        }
        for obj in mesh_objects
    ],
}
print("MODEL_METADATA=" + json.dumps(metadata, ensure_ascii=False))
