"""Original Cycles product-lighting study; run with background Blender, no scene UI."""

import json
import math
from pathlib import Path

import bpy
from mathutils import Vector

ROOT = Path(__file__).resolve().parents[2] / "public" / "blog"
bpy.ops.wm.read_factory_settings(use_empty=True)
scene = bpy.context.scene
scene.render.engine = "CYCLES"
scene.cycles.samples = 32
scene.cycles.use_denoising = True
scene.render.resolution_x = 1280
scene.render.resolution_y = 720
scene.render.resolution_percentage = 100
scene.render.image_settings.file_format = "PNG"
scene.view_settings.view_transform = "AgX"
scene.world = bpy.data.worlds.new("Dim studio world")
scene.world.use_nodes = True
scene.world.node_tree.nodes["Background"].inputs["Color"].default_value = (0.12, 0.14, 0.20, 1)
scene.world.node_tree.nodes["Background"].inputs["Strength"].default_value = 0.12


def material(name, color, roughness):
    m = bpy.data.materials.new(name)
    m.diffuse_color = (*color, 1)
    m.use_nodes = True
    n = m.node_tree.nodes.get("Principled BSDF")
    n.inputs["Base Color"].default_value = (*color, 1)
    n.inputs["Roughness"].default_value = roughness
    return m


blue = material("Original cobalt glaze", (0.012, 0.06, 0.42), 0.24)
peach = material("Warm peach sweep", (0.55, 0.22, 0.105), 0.65)
profile = [
    (0, 0.05),
    (0.43, 0.05),
    (0.48, 0.12),
    (0.51, 0.3),
    (0.54, 0.9),
    (0.55, 1.22),
    (0.54, 1.28),
    (0.49, 1.28),
    (0.48, 1.21),
    (0.46, 0.25),
    (0.40, 0.18),
    (0, 0.18),
]
N = 96
verts = []
faces = []
for r, z in profile:
    verts.extend(
        [
            (r * math.cos(2 * math.pi * i / N), r * math.sin(2 * math.pi * i / N), z)
            for i in range(N)
        ]
    )
for j in range(len(profile) - 1):
    for i in range(N):
        faces.append((j * N + i, j * N + (i + 1) % N, (j + 1) * N + (i + 1) % N, (j + 1) * N + i))
mesh = bpy.data.meshes.new("Lathed original cup mesh")
mesh.from_pydata(verts, [], faces)
mesh.update()
cup = bpy.data.objects.new("Cobalt cup", mesh)
scene.collection.objects.link(cup)
cup.data.materials.append(blue)
for p in mesh.polygons:
    p.use_smooth = True
bevel = cup.modifiers.new("Soft ceramic edges", "BEVEL")
bevel.width = 0.02
bevel.segments = 3
curve = bpy.data.curves.new("Original loop handle", "CURVE")
curve.dimensions = "3D"
curve.bevel_depth = 0.075
curve.bevel_resolution = 5
s = curve.splines.new("POLY")
s.points.add(64)
for i, p in enumerate(s.points):
    t = -math.pi / 2 + 2 * math.pi * i / 64
    p.co = (0.55 + 0.34 * math.cos(t), 0, 0.68 + 0.43 * math.sin(t), 1)
handle = bpy.data.objects.new("Ceramic loop", curve)
scene.collection.objects.link(handle)
handle.data.materials.append(blue)
bpy.ops.mesh.primitive_plane_add(size=200, location=(0, 0, 0))
floor = bpy.context.object
floor.name = "Peach studio floor"
floor.data.materials.append(peach)


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


bpy.ops.object.camera_add(location=(0, -6, 3))
camera = bpy.context.object
camera.name = "Study camera"
camera.data.lens = 52
aim(camera, (0, 0, 0.65))
scene.camera = camera
specs = [
    ("Key", (-3, -4, 4), 800, 3, (1, 0.82, 0.65)),
    ("Fill", (3, -2, 2.5), 160, 3, (0.72, 0.84, 1)),
    ("Rim", (1, 3, 3.5), 600, 2, (1, 0.93, 0.82)),
]
lights = []
for name, loc, energy, size, color in specs:
    data = bpy.data.lights.new(name, "AREA")
    data.energy = energy
    data.shape = "DISK"
    data.size = size
    data.color = color
    obj = bpy.data.objects.new(name, data)
    scene.collection.objects.link(obj)
    obj.location = loc
    aim(obj, (0, 0, 0.65))
    lights.append(obj)
for i, name in enumerate(["key", "key-fill", "key-fill-rim"]):
    for j, light in enumerate(lights):
        light.hide_render = j > i
    scene.render.filepath = str(ROOT / f"lighting-study-{name}.png")
    bpy.ops.render.render(write_still=True)
for light in lights:
    light.hide_render = False
bpy.ops.wm.save_as_mainfile(filepath=str(ROOT / "lighting-study.blend"))
meta = {
    "blenderVersion": bpy.app.version_string,
    "engine": "Cycles",
    "samples": 32,
    "denoising": True,
    "viewTransform": "AgX",
    "imageSize": [1280, 720],
    "worldStrength": 0.12,
    "camera": {"position": list(camera.location), "lensMm": 52, "target": [0, 0, 0.65]},
    "lights": [
        {
            "name": n,
            "position": list(loc),
            "blenderEnergyW": e,
            "size": size,
            "colorLinearRGB": list(c),
        }
        for n, loc, e, size, c in specs
    ],
    "scope": "Original conventional 3D render study, not a camera shoot or generative image model output",
    "limits": "Blender powers are scene settings, not meter readings or real fixture recommendations; diagram uses arbitrary plan units; no lux, exposure ratio or AI parameter equivalence is claimed",
}
(ROOT / "lighting-study-scene.json").write_text(json.dumps(meta, indent=2) + "\n")
