```python
import bpy
import math

# -----------------------------------------------------------------------------
# Clean Scene Setup
# -----------------------------------------------------------------------------
def clear_scene():
    bpy.ops.object.select_all(action='SELECT')
    bpy.ops.object.delete(use_global=False)

    # Remove any leftover materials and lights
    for mat in bpy.data.materials:
        bpy.data.materials.remove(mat)
    for light in bpy.data.lights:
        bpy.data.lights.remove(light)
    for cam in bpy.data.cameras:
        bpy.data.cameras.remove(cam)

# -----------------------------------------------------------------------------
# Material Creation Helpers
# -----------------------------------------------------------------------------
def create_paint_material():
    mat = bpy.data.materials.new(name="Lantern_Paint")
    mat.use_nodes = True
    nodes = mat.node_tree.nodes
    nodes.clear()

    bsdf = nodes.new(type='ShaderNodeBsdfPrincipled')
    bsdf.inputs['Base Color'].default_value = (0.28, 0.02, 0.02, 1.0) # Rich vintage crimson burgundy
    bsdf.inputs['Roughness'].default_value = 0.22

    if 'Coat Weight' in bsdf.inputs:
        bsdf.inputs['Coat Weight'].default_value = 0.5
        bsdf.inputs['Coat Roughness'].default_value = 0.1

    # Soft porcelain/paint surface wave look
    tex_noise = nodes.new(type='ShaderNodeTexNoise')
    tex_noise.inputs['Scale'].default_value = 12.0
    tex_noise.inputs['Detail'].default_value = 2.0

    bump = nodes.new(type='ShaderNodeBump')
    bump.inputs['Strength'].default_value = 0.02
    bump.inputs['Distance'].default_value = 0.05

    output = nodes.new(type='ShaderNodeOutputMaterial')
    mat.node_tree.links.new(tex_noise.outputs['Factor'], bump.inputs['Height'])
    mat.node_tree.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])
    mat.node_tree.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])
    return mat

def create_brass_material():
    mat = bpy.data.materials.new(name="Lantern_Brass")
    mat.use_nodes = True
    nodes = mat.node_tree.nodes
    nodes.clear()

    bsdf = nodes.new(type='ShaderNodeBsdfPrincipled')
    bsdf.inputs['Base Color'].default_value = (0.58, 0.39, 0.16, 1.0) # Antique Brass/Bronze
    bsdf.inputs['Metallic'].default_value = 1.0
    bsdf.inputs['Roughness'].default_value = 0.28

    tex_noise = nodes.new(type='ShaderNodeTexNoise')
    tex_noise.inputs['Scale'].default_value = 110.0
    tex_noise.inputs['Detail'].default_value = 6.0

    bump = nodes.new(type='ShaderNodeBump')
    bump.inputs['Strength'].default_value = 0.04
    bump.inputs['Distance'].default_value = 0.05

    output = nodes.new(type='ShaderNodeOutputMaterial')
    mat.node_tree.links.new(tex_noise.outputs['Factor'], bump.inputs['Height'])
    mat.node_tree.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])
    mat.node_tree.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])
    return mat

def create_glass_material():
    mat = bpy.data.materials.new(name="Lantern_Glass")
    mat.use_nodes = True
    nodes = mat.node_tree.nodes
    nodes.clear()

    bsdf = nodes.new(type='ShaderNodeBsdfPrincipled')
    bsdf.inputs['Base Color'].default_value = (0.97, 0.99, 1.0, 1.0)
    bsdf.inputs['Roughness'].default_value = 0.01
    bsdf.inputs['IOR'].default_value = 1.5

    if 'Transmission Weight' in bsdf.inputs:
        bsdf.inputs['Transmission Weight'].default_value = 1.0
    else:
        bsdf.inputs['Transmission'].default_value = 1.0

    output = nodes.new(type='ShaderNodeOutputMaterial')
    mat.node_tree.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])
    return mat

def create_glow_material():
    mat = bpy.data.materials.new(name="Lantern_Glow")
    mat.use_nodes = True
    nodes = mat.node_tree.nodes
    nodes.clear()

    bsdf = nodes.new(type='ShaderNodeBsdfPrincipled')
    bsdf.inputs['Base Color'].default_value = (1.0, 0.62, 0.15, 1.0)

    if 'Emission Color' in bsdf.inputs:
        bsdf.inputs['Emission Color'].default_value = (1.0, 0.42, 0.05, 1.0)
        bsdf.inputs['Emission Strength'].default_value = 25.0
    else:
        bsdf.inputs['Emission'].default_value = (1.0, 0.42, 0.05, 1.0)
        bsdf.inputs['Emission Strength'].default_value = 25.0

    output = nodes.new(type='ShaderNodeOutputMaterial')
    mat.node_tree.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])
    return mat

def create_floor_material():
    mat = bpy.data.materials.new(name="Floor_Slate")
    mat.use_nodes = True
    nodes = mat.node_tree.nodes
    nodes.clear()

    bsdf = nodes.new(type='ShaderNodeBsdfPrincipled')
    bsdf.inputs['Base Color'].default_value = (0.04, 0.042, 0.045, 1.0) # Dark rich slate
    bsdf.inputs['Roughness'].default_value = 0.45

    tex_noise = nodes.new(type='ShaderNodeTexNoise')
    tex_noise.inputs['Scale'].default_value = 30.0
    tex_noise.inputs['Detail'].default_value = 8.0
    tex_noise.inputs['Roughness'].default_value = 0.65

    bump = nodes.new(type='ShaderNodeBump')
    bump.inputs['Strength'].default_value = 0.12
    bump.inputs['Distance'].default_value = 0.02

    output = nodes.new(type='ShaderNodeOutputMaterial')
    mat.node_tree.links.new(tex_noise.outputs['Factor'], bump.inputs['Height'])
    mat.node_tree.links.new(bump.outputs['Normal'], bsdf.inputs['Normal'])
    mat.node_tree.links.new(bsdf.outputs['BSDF'], output.inputs['Surface'])
    return mat

# -----------------------------------------------------------------------------
# Modeling Helpers
# -----------------------------------------------------------------------------
def safe_join_objects(objects, active_obj):
    bpy.ops.object.select_all(action='DESELECT')
    for obj in objects:
        obj.select_set(True)
    bpy.context.view_layer.objects.active = active_obj
    bpy.ops.object.join()
    return active_obj

def add_bevel_modifier(obj, width=0.005, segments=3):
    bev = obj.modifiers.new(name="Bevel", type='BEVEL')
    bev.width = width
    bev.segments = segments
    bev.limit_method = 'ANGLE'
    bev.angle_limit = 0.52 # ~30 deg
    return bev

def create_bezier_spline(curve_data, points_coords_handles):
    spline = curve_data.splines.new(type='BEZIER')
    num_to_add = len(points_coords_handles) - 1
    if num_to_add > 0:
        spline.bezier_points.add(num_to_add)

    for idx, data in enumerate(points_coords_handles):
        p = spline.bezier_points[idx]
        p.co = data['co']
        p.handle_left = data['hl']
        p.handle_right = data['hr']

# -----------------------------------------------------------------------------
# Lantern Component Builders
# -----------------------------------------------------------------------------
def build_lantern_base(paint_mat, brass_mat):
    parts = []

    # Bottom plate rim
    bpy.ops.mesh.primitive_cylinder_add(vertices=64, radius=0.45, depth=0.02, location=(0,0,0.01))
    p1 = bpy.context.active_object
    parts.append(p1)

    # Main tank body
    bpy.ops.mesh.primitive_cylinder_add(vertices=64, radius=0.43, depth=0.16, location=(0,0,0.1))
    p2 = bpy.context.active_object
    parts.append(p2)

    # Upper collar rim
    bpy.ops.mesh.primitive_cylinder_add(vertices=64, radius=0.26, depth=0.03, location=(0,0,0.195))
    p3 = bpy.context.active_object
    parts.append(p3)

    # Burner neck collar
    bpy.ops.mesh.primitive_cylinder_add(vertices=64, radius=0.16, depth=0.05, location=(0,0,0.235))
    p4 = bpy.context.active_object
    parts.append(p4)

    base_obj = safe_join_objects(parts, p2)
    base_obj.name = "Lantern_Base"
    base_obj.data.materials.append(paint_mat)

    bpy.ops.object.shade_smooth()
    add_bevel_modifier(base_obj, width=0.005, segments=3)

    # Add beautiful brass fuel filler cap on the side
    bpy.ops.mesh.primitive_cylinder_add(vertices=24, radius=0.042, depth=0.025, location=(0.28, 0, 0.17))
    cap = bpy.context.active_object
    cap.name = "Fuel_Cap"
    cap.rotation_euler = (0, math.radians(16), 0)
    cap.data.materials.append(brass_mat)
    bpy.ops.object.shade_smooth()
    add_bevel_modifier(cap, width=0.002, segments=2)
    cap.parent = base_obj

    return base_obj

def build_top_cap(paint_mat):
    parts = []

    # Base hood flange
    bpy.ops.mesh.primitive_cylinder_add(vertices=64, radius=0.25, depth=0.02, location=(0,0,0.76))
    p1 = bpy.context.active_object
    parts.append(p1)

    # Conical ventilation housing
    bpy.ops.mesh.primitive_cone_add(vertices=64, radius1=0.25, radius2=0.15, depth=0.08, location=(0,0,0.81))
    p2 = bpy.context.active_object
    parts.append(p2)

    # Vent spacers
    bpy.ops.mesh.primitive_cylinder_add(vertices=64, radius=0.12, depth=0.02, location=(0,0,0.86))
    p3 = bpy.context.active_object
    parts.append(p3)

    # Secondary cap / heat shield dome
    bpy.ops.mesh.primitive_cone_add(vertices=64, radius1=0.14, radius2=0.08, depth=0.05, location=(0,0,0.895))
    p4 = bpy.context.active_object
    parts.append(p4)

    # Top crown finial
    bpy.ops.mesh.primitive_cylinder_add(vertices=24, radius=0.04, depth=0.03, location=(0,0,0.935))
    p5 = bpy.context.active_object
    parts.append(p5)

    top_obj = safe_join_objects(parts, p2)
    top_obj.name = "Lantern_Top"
    top_obj.data.materials.append(paint_mat)

    bpy.ops.object.shade_smooth()
    add_bevel_modifier(top_obj, width=0.004, segments=3)

    return top_obj

def build_glass_globe(glass_mat):
    bpy.ops.mesh.primitive_uv_sphere_add(segments=48, ring_count=32, radius=1.0, location=(0,0,0.51))
    glass = bpy.context.active_object
    glass.name = "Lantern_Glass"

    # Shape into barrel/pear shape
    glass.scale = (0.22, 0.22, 0.24)
    bpy.ops.object.transform_apply(scale=True)

    glass.data.materials.append(glass_mat)
    bpy.ops.object.shade_smooth()

    # Add physical glass solidify depth
    solid = glass.modifiers.new(name="Solidify", type='SOLIDIFY')
    solid.thickness = 0.008

    return glass

def build_glow_core(glow_mat):
    # Flame/mantle mesh core
    bpy.ops.mesh.primitive_uv_sphere_add(segments=24, ring_count=16, radius=1.0, location=(0,0,0.48))
    core = bpy.context.active_object
    core.name = "Lantern_Glow_Core"
    core.scale = (0.05, 0.05, 0.12)
    bpy.ops.object.transform_apply(scale=True)

    core.data.materials.append(glow_mat)
    bpy.ops.object.shade_smooth()

    # Prevent the geometry core from blocking physical lights inside
    core.cycles.cast_shadow = False

    # Real point light matches exact coordinates
    light_data = bpy.data.lights.new(name="Lantern_Light_Data", type='POINT')
    light_obj = bpy.data.objects.new(name="Lantern_Light", object_data=light_data)
    bpy.context.collection.objects.link(light_obj)

    light_obj.location = (0, 0, 0.48)
    light_data.energy = 60.0
    light_data.color = (1.0, 0.55, 0.14) # Ultra-warm fire glow
    light_data.shadow_soft_size = 0.04   # Soft, beautiful shadows

    return core, light_obj

def build_side_struts(brass_mat):
    curve_data = bpy.data.curves.new(name="Side_Strut_Curve", type='CURVE')
    curve_data.dimensions = '3D'

    coords = [
        {'co': (0.36, 0.0, 0.16), 'hl': (0.36, 0.0, 0.1),  'hr': (0.38, 0.0, 0.25)},
        {'co': (0.41, 0.0, 0.48), 'hl': (0.41, 0.0, 0.38), 'hr': (0.41, 0.0, 0.60)},
        {'co': (0.21, 0.0, 0.76), 'hl': (0.25, 0.0, 0.73), 'hr': (0.18, 0.0, 0.78)}
    ]

    create_bezier_spline(curve_data, coords)

    curve_data.bevel_depth = 0.024
    curve_data.bevel_resolution = 6

    obj = bpy.data.objects.new(name="Side_Struts", object_data=curve_data)
    bpy.context.collection.objects.link(obj)

    obj.data.materials.append(brass_mat)

    # Symmetric mirror
    mirror = obj.modifiers.new(name="Mirror", type='MIRROR')
    mirror.use_axis[0] = True

    return obj

def build_guard_wires(brass_mat):
    parts = []

    # Lower protection ring loop
    bpy.ops.mesh.primitive_torus_add(align='WORLD', location=(0, 0, 0.44),
                                     major_radius=0.26, minor_radius=0.006,
                                     major_segments=48, minor_segments=12)
    t1 = bpy.context.active_object
    parts.append(t1)

    # Upper protection ring loop
    bpy.ops.mesh.primitive_torus_add(align='WORLD', location=(0, 0, 0.58),
                                     major_radius=0.24, minor_radius=0.006,
                                     major_segments=48, minor_segments=12)
    t2 = bpy.context.active_object
    parts.append(t2)

    # Quad-spaced vertical lines (wires)
    angles = [math.radians(45), math.radians(135), math.radians(225), math.radians(315)]
    for ang in angles:
        x = math.cos(ang) * 0.24
        y = math.sin(ang) * 0.24
        bpy.ops.mesh.primitive_cylinder_add(vertices=12, radius=0.005, depth=0.55, location=(x, y, 0.48))
        v_wire = bpy.context.active_object
        parts.append(v_wire)

    wires_obj = safe_join_objects(parts, t1)
    wires_obj.name = "Guard_Wires"
    wires_obj.data.materials.append(brass_mat)
    bpy.ops.object.shade_smooth()

    return wires_obj

def build_handle(brass_mat):
    curve_data = bpy.data.curves.new(name="Handle_Curve", type='CURVE')
    curve_data.dimensions = '3D'

    # Sweeping metal wire handle
    coords = [
        {'co': (-0.21, -0.02, 0.76), 'hl': (-0.21, -0.02, 0.70), 'hr': (-0.21, -0.02, 0.95)},
        {'co': (0.0, -0.06, 1.34),   'hl': (-0.12, -0.05, 1.34), 'hr': (0.12, -0.05, 1.34)},
        {'co': (0.21, -0.02, 0.76),  'hl': (0.21, -0.02, 0.95),  'hr': (0.21, -0.02, 0.70)}
    ]

    create_bezier_spline(curve_data, coords)

    curve_data.bevel_depth = 0.012
    curve_data.bevel_resolution = 4

    obj = bpy.data.objects.new(name="Bail_Handle", object_data=curve_data)
    bpy.context.collection.objects.link(obj)

    obj.data.materials.append(brass_mat)
    return obj

# -----------------------------------------------------------------------------
# World, Scene and Camera Presentation Architecture
# -----------------------------------------------------------------------------
def assemble_lantern():
    paint_mat = create_paint_material()
    brass_mat = create_brass_material()
    glass_mat = create_glass_material()
    glow_mat = create_glow_material()

    # Main parent assembly empty
    bpy.ops.object.empty_add(type='PLAIN_AXES', location=(0, 0, 0))
    lantern_parent = bpy.context.active_object
    lantern_parent.name = "Lantern_Hero_Prop"

    # Component builds
    base = build_lantern_base(paint_mat, brass_mat)
    top = build_top_cap(paint_mat)
    glass = build_glass_globe(glass_mat)
    core, light = build_glow_core(glow_mat)
    struts = build_side_struts(brass_mat)
    wires = build_guard_wires(brass_mat)
    handle = build_handle(brass_mat)

    # Hierarchy assignment
    parts = [base, top, glass, core, light, struts, wires, handle]
    for obj in parts:
        obj.parent = lantern_parent

    # Rotate slightly to break strict front symmetry and showcase layout
    lantern_parent.rotation_euler = (0, 0, math.radians(22))

    return lantern_parent

def build_floor():
    # Large beautiful ground table plane
    bpy.ops.mesh.primitive_plane_add(size=15.0, location=(0, 0, 0))
    floor = bpy.context.active_object
    floor.name = "Floor_Ground"

    floor_mat = create_floor_material()
    floor.data.materials.append(floor_mat)
    return floor

def setup_lighting():
    # Target orientation empty
    target_empty = bpy.data.objects.new("Target_Empty", None)
    target_empty.location = (0, 0, 0.5)
    bpy.context.collection.objects.link(target_empty)

    # 1. Cold Rim Light from rear left (creates sleek profile outline highlights)
    rim_data = bpy.data.lights.new(name="Rim_Light_Data", type='AREA')
    rim_obj = bpy.data.objects.new(name="Rim_Light", object_data=rim_data)
    bpy.context.collection.objects.link(rim_obj)
    rim_obj.location = (-1.8, 1.8, 1.5)
    rim_data.size = 1.6
    rim_data.energy = 85.0
    rim_data.color = (0.55, 0.72, 1.0) # Sky/moonlight contrast

    # 2. Warm Fill Area Light from front right (brings out metal texture/paint quality)
    fill_data = bpy.data.lights.new(name="Fill_Light_Data", type='AREA')
    fill_obj = bpy.data.objects.new(name="Fill_Light", object_data=fill_data)
    bpy.context.collection.objects.link(fill_obj)
    fill_obj.location = (1.5, -1.5, 0.8)
    fill_data.size = 2.0
    fill_data.energy = 20.0
    fill_data.color = (1.0, 0.90, 0.80)

    # Constrain illumination targets
    for light in [rim_obj, fill_obj]:
        tt = light.constraints.new(type='TRACK_TO')
        tt.target = target_empty
        tt.track_axis = 'TRACK_NEGATIVE_Z'
        tt.up_axis = 'UP_Y'

    # Ambient World night lighting
    world = bpy.context.scene.world
    world.use_nodes = True
    bg = world.node_tree.nodes.get("Background")
    if bg:
        bg.inputs['Color'].default_value = (0.004, 0.005, 0.010, 1.0) # Saturated deep dark blue
        bg.inputs['Strength'].default_value = 0.5

def setup_camera():
    cam_data = bpy.data.cameras.new(name="Product_Camera_Data")
    cam_obj = bpy.data.objects.new(name="Product_Camera", object_data=cam_data)
    bpy.context.collection.objects.link(cam_obj)

    # Cinematic studio setup parameters
    cam_obj.location = (0.06, -2.1, 0.75)
    cam_data.lens = 75 # Pro portrait-level 75mm lens compression

    bpy.context.scene.camera = cam_obj

    target = bpy.data.objects.get("Target_Empty")
    if target:
        tt = cam_obj.constraints.new(type='TRACK_TO')
        tt.target = target
        tt.track_axis = 'TRACK_NEGATIVE_Z'
        tt.up_axis = 'UP_Y'

    # Cinematic depth of field (DoF) focusing directly on the lantern center
    cam_data.dof.use_dof = True
    cam_data.dof.focus_object = target
    cam_data.dof.aperture_fstop = 3.2

# -----------------------------------------------------------------------------
# Compilation Execution
# -----------------------------------------------------------------------------
def configure_render():
    scene = bpy.context.scene
    scene.render.engine = 'CYCLES'
    scene.cycles.device = 'GPU'

    # Modern AgX dynamic response curves for optimal glowing embers range
    scene.view_settings.view_transform = 'AgX'
    scene.view_settings.look = 'Medium High Contrast'

    scene.render.resolution_x = 1536
    scene.render.resolution_y = 1536

def main():
    clear_scene()
    assemble_lantern()
    build_floor()
    setup_lighting()
    setup_camera()
    configure_render()

if __name__ == "__main__":
    main()
```