import bpy
import math
import os
from mathutils import Vector


MODEL_PATH = "/home/vela/Downloads/model.glb"
OUTPUT_DIR = "/home/vela/workspace/domain/tn-silver/web/tn-site/.runtime/reference/model_inspect"


bpy.ops.wm.read_factory_settings(use_empty=True)
bpy.ops.import_scene.gltf(filepath=MODEL_PATH)

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

material = bpy.data.materials.new("InspectionMaterial")
material.diffuse_color = (0.66, 0.68, 0.72, 1.0)
material.metallic = 0.0
material.roughness = 0.72
for obj in meshes:
    obj.data.materials.clear()
    obj.data.materials.append(material)

corners = []
for obj in meshes:
    corners.extend(obj.matrix_world @ Vector(corner) for corner in obj.bound_box)
minimum = Vector((min(v.x for v in corners), min(v.y for v in corners), min(v.z for v in corners)))
maximum = Vector((max(v.x for v in corners), max(v.y for v in corners), max(v.z for v in corners)))
center = (minimum + maximum) * 0.5
extent = maximum - minimum

world = bpy.context.scene.world
if world is None:
    world = bpy.data.worlds.new("InspectionWorld")
    bpy.context.scene.world = world
world.color = (0.045, 0.045, 0.045)

key = bpy.data.lights.new("Key", type="AREA")
key.energy = 900
key.shape = "DISK"
key.size = 4.0
key_obj = bpy.data.objects.new("Key", key)
bpy.context.collection.objects.link(key_obj)
key_obj.location = center + Vector((-2.5, -3.0, 3.5))

fill = bpy.data.lights.new("Fill", type="AREA")
fill.energy = 500
fill.size = 5.0
fill_obj = bpy.data.objects.new("Fill", fill)
bpy.context.collection.objects.link(fill_obj)
fill_obj.location = center + Vector((3.0, 2.0, 2.0))

camera_data = bpy.data.cameras.new("InspectionCamera")
camera = bpy.data.objects.new("InspectionCamera", camera_data)
bpy.context.collection.objects.link(camera)
bpy.context.scene.camera = camera
camera_data.type = "ORTHO"
camera_data.ortho_scale = max(extent) * 1.18

scene = bpy.context.scene
scene.render.engine = "BLENDER_EEVEE"
scene.render.resolution_x = 768
scene.render.resolution_y = 768
scene.render.resolution_percentage = 100
scene.render.image_settings.file_format = "PNG"
scene.render.film_transparent = False
scene.render.image_settings.color_mode = "RGBA"


def point_camera(position):
    camera.location = position
    direction = center - camera.location
    camera.rotation_euler = direction.to_track_quat("-Z", "Y").to_euler()


distance = max(extent) * 2.7
views = {
    "front_neg_y": center + Vector((0, -distance, 0)),
    "back_pos_y": center + Vector((0, distance, 0)),
    "side_pos_x": center + Vector((distance, 0, 0)),
    "side_neg_x": center + Vector((-distance, 0, 0)),
}

os.makedirs(OUTPUT_DIR, exist_ok=True)
for name, position in views.items():
    point_camera(position)
    scene.render.filepath = os.path.join(OUTPUT_DIR, f"{name}.png")
    bpy.ops.render.render(write_still=True)

# Desired 03:50-style portrait crop: retain the full mesh but crop it with the camera.
crop_target = center + Vector((0.0, 0.0, -0.15))
camera_data.ortho_scale = 1.60
scene.render.resolution_x = 768
scene.render.resolution_y = 960
camera.location = crop_target + Vector((0.0, -distance, 0.0))
camera.rotation_euler = (crop_target - camera.location).to_track_quat("-Z", "Y").to_euler()
scene.render.filepath = os.path.join(OUTPUT_DIR, "close_crop.png")
bpy.ops.render.render(write_still=True)

crop_target = center + Vector((0.0, 0.0, -0.20))
camera_data.ortho_scale = 1.32
camera.location = crop_target + Vector((0.0, -distance, 0.0))
camera.rotation_euler = (crop_target - camera.location).to_track_quat("-Z", "Y").to_euler()
scene.render.filepath = os.path.join(OUTPUT_DIR, "desired_crop.png")
bpy.ops.render.render(write_still=True)

print({"bounds_min": tuple(minimum), "bounds_max": tuple(maximum), "extent": tuple(extent)})
