import bpy
import bmesh
import math
from mathutils import Vector, Matrix


def safe_set_input(node, name, value):
    """Safely set a node input value with type checking."""
    try:
        if name in node.inputs:
            socket = node.inputs[name]
            socket.default_value = value
    except Exception:
        pass


def create_material(name, base_color, metallic=0.0, roughness=0.5, subsurface=0.0, specular=0.5):
    """Create a Principled BSDF material defensively."""
    mat = bpy.data.materials.new(name=name)
    mat.use_nodes = True
    nodes = mat.node_tree.nodes
    principled = None
    for n in nodes:
        if n.type == 'BSDF_PRINCIPLED':
            principled = n
            break
    if principled:
        safe_set_input(principled, "Base Color", base_color)
        safe_set_input(principled, "Metallic", metallic)
        safe_set_input(principled, "Roughness", roughness)
        try:
            safe_set_input(principled, "Subsurface Weight", subsurface)
        except Exception:
            try:
                safe_set_input(principled, "Subsurface", subsurface)
            except Exception:
                pass
        try:
            safe_set_input(principled, "Specular IOR Level", specular)
        except Exception:
            try:
                safe_set_input(principled, "Specular", specular)
            except Exception:
                pass
    return mat


def assign_material(obj, mat):
    """Assign material to object safely."""
    if obj is None or obj.data is None:
        return
    if len(obj.data.materials) == 0:
        obj.data.materials.append(mat)
    else:
        obj.data.materials[0] = mat


def add_smooth_shading(obj):
    """Add smooth shading to object."""
    if obj is None or obj.data is None:
        return
    for poly in obj.data.polygons:
        poly.use_smooth = True


def create_duck_body():
    """Create the main torpedo-shaped body."""
    bpy.ops.mesh.primitive_uv_sphere_add(
        segments=32, ring_count=16, radius=1.0,
        location=(0, 0, 0)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = "DuckBody"
    obj.scale = (2.0, 0.85, 0.75)
    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
    
    bpy.ops.object.mode_set(mode='EDIT')
    bm = bmesh.from_edit_mesh(obj.data)
    bm.verts.ensure_lookup_table()
    
    for v in bm.verts:
        x, y, z = v.co
        if x > 0.8:
            taper = (x - 0.8) / 1.2
            v.co.y *= max(0.3, 1.0 - taper * 0.7)
            v.co.z *= max(0.4, 1.0 - taper * 0.5)
        if x < -0.5:
            v.co.z += 0.1 * ((-x - 0.5) / 1.5)
        if z < 0:
            v.co.z *= 0.85
    
    bmesh.update_edit_mesh(obj.data)
    bpy.ops.object.mode_set(mode='OBJECT')
    add_smooth_shading(obj)
    return obj


def create_duck_breast():
    """Create the chestnut breast area."""
    bpy.ops.mesh.primitive_uv_sphere_add(
        segments=24, ring_count=12, radius=0.55,
        location=(-1.1, 0, -0.05)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = "DuckBreast"
    obj.scale = (0.7, 0.75, 0.65)
    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
    add_smooth_shading(obj)
    return obj


def create_duck_neck():
    """Create the curved neck."""
    bpy.ops.mesh.primitive_cylinder_add(
        vertices=20, radius=0.22, depth=1.0,
        location=(-1.4, 0, 0.35)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = "DuckNeck"
    obj.rotation_euler = (0, math.radians(55), 0)
    bpy.ops.object.transform_apply(location=False, rotation=True, scale=False)
    
    bpy.ops.object.mode_set(mode='EDIT')
    bm = bmesh.from_edit_mesh(obj.data)
    bm.verts.ensure_lookup_table()
    
    for v in bm.verts:
        local_z = v.co.z
        if local_z > 0:
            scale = 1.0 - (local_z / 0.5) * 0.15
            v.co.x *= scale
            v.co.y *= scale
    
    bmesh.update_edit_mesh(obj.data)
    bpy.ops.object.mode_set(mode='OBJECT')
    add_smooth_shading(obj)
    return obj


def create_white_collar():
    """Create the distinctive white neck ring."""
    bpy.ops.mesh.primitive_torus_add(
        major_radius=0.24, minor_radius=0.035,
        major_segments=32, minor_segments=12,
        location=(-1.65, 0, 0.55)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = "DuckCollar"
    obj.rotation_euler = (0, math.radians(55), 0)
    add_smooth_shading(obj)
    return obj


def create_duck_head():
    """Create the iridescent green head."""
    bpy.ops.mesh.primitive_uv_sphere_add(
        segments=28, ring_count=14, radius=0.38,
        location=(-1.95, 0, 0.82)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = "DuckHead"
    obj.scale = (1.15, 0.88, 0.95)
    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
    
    bpy.ops.object.mode_set(mode='EDIT')
    bm = bmesh.from_edit_mesh(obj.data)
    bm.verts.ensure_lookup_table()
    
    for v in bm.verts:
        if v.co.x < -0.15:
            v.co.z += 0.03
        if v.co.z > 0.2:
            v.co.z += 0.05 * (v.co.z - 0.2)
    
    bmesh.update_edit_mesh(obj.data)
    bpy.ops.object.mode_set(mode='OBJECT')
    add_smooth_shading(obj)
    return obj


def create_duck_bill():
    """Create the flattened spatulate bill."""
    bpy.ops.mesh.primitive_cube_add(size=1.0, location=(-2.55, 0, 0.72))
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = "DuckBill"
    obj.scale = (0.55, 0.22, 0.09)
    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
    
    bpy.ops.object.mode_set(mode='EDIT')
    bm = bmesh.from_edit_mesh(obj.data)
    bm.verts.ensure_lookup_table()
    
    for v in bm.verts:
        if v.co.x < -0.1:
            progress = (-v.co.x - 0.1) / 0.45
            v.co.y *= 1.0 + progress * 0.35
            v.co.z *= 0.75 + progress * 0.1
        if v.co.x > 0.2:
            v.co.y *= 0.7
        if v.co.z < 0 and v.co.x < 0:
            v.co.z -= 0.02
    
    bmesh.update_edit_mesh(obj.data)
    bpy.ops.object.mode_set(mode='OBJECT')
    
    subsurf = obj.modifiers.new(name="Subsurf", type='SUBSURF')
    subsurf.levels = 2
    subsurf.render_levels = 2
    add_smooth_shading(obj)
    return obj


def create_bill_nail():
    """Create the darker nail at the bill tip."""
    bpy.ops.mesh.primitive_uv_sphere_add(
        segments=12, ring_count=6, radius=0.045,
        location=(-3.05, 0, 0.72)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = "DuckBillNail"
    obj.scale = (0.8, 1.8, 0.6)
    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
    add_smooth_shading(obj)
    return obj


def create_nostril():
    """Create nostril indentation."""
    bpy.ops.mesh.primitive_uv_sphere_add(
        segments=8, ring_count=4, radius=0.02,
        location=(-2.35, 0.12, 0.78)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = "DuckNostrilL"
    obj.scale = (1.5, 0.6, 0.5)
    add_smooth_shading(obj)
    return obj


def create_nostril_right():
    """Create right nostril."""
    bpy.ops.mesh.primitive_uv_sphere_add(
        segments=8, ring_count=4, radius=0.02,
        location=(-2.35, -0.12, 0.78)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = "DuckNostrilR"
    obj.scale = (1.5, 0.6, 0.5)
    add_smooth_shading(obj)
    return obj


def create_eye(side='left'):
    """Create eye sphere."""
    y_offset = 0.22 if side == 'left' else -0.22
    bpy.ops.mesh.primitive_uv_sphere_add(
        segments=16, ring_count=8, radius=0.055,
        location=(-2.12, y_offset, 0.92)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = f"DuckEye_{side.capitalize()}"
    add_smooth_shading(obj)
    return obj


def create_eye_ring(side='left'):
    """Create eye ring (bare skin around eye)."""
    y_offset = 0.23 if side == 'left' else -0.23
    bpy.ops.mesh.primitive_torus_add(
        major_radius=0.065, minor_radius=0.012,
        major_segments=16, minor_segments=8,
        location=(-2.12, y_offset, 0.92)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = f"DuckEyeRing_{side.capitalize()}"
    obj.rotation_euler = (math.radians(90), 0, 0)
    add_smooth_shading(obj)
    return obj


def create_wing(side='left'):
    """Create a folded wing."""
    y_offset = 0.48 if side == 'left' else -0.48
    bpy.ops.mesh.primitive_uv_sphere_add(
        segments=20, ring_count=10, radius=0.5,
        location=(0.35, y_offset, 0.1)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = f"DuckWing_{side.capitalize()}"
    obj.scale = (1.8, 0.12, 0.45)
    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
    
    bpy.ops.object.mode_set(mode='EDIT')
    bm = bmesh.from_edit_mesh(obj.data)
    bm.verts.ensure_lookup_table()
    
    for v in bm.verts:
        if v.co.x > 0.3:
            taper = (v.co.x - 0.3) / 0.6
            v.co.z *= max(0.4, 1.0 - taper * 0.6)
        if v.co.x < -0.4:
            v.co.z *= 0.85
    
    bmesh.update_edit_mesh(obj.data)
    bpy.ops.object.mode_set(mode='OBJECT')
    add_smooth_shading(obj)
    return obj


def create_speculum(side='left'):
    """Create the iridescent blue speculum on wing."""
    y_offset = 0.53 if side == 'left' else -0.53
    bpy.ops.mesh.primitive_cube_add(size=1.0, location=(0.1, y_offset, 0.12))
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = f"DuckSpeculum_{side.capitalize()}"
    obj.scale = (0.35, 0.025, 0.12)
    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
    
    subsurf = obj.modifiers.new(name="Subsurf", type='SUBSURF')
    subsurf.levels = 1
    add_smooth_shading(obj)
    return obj


def create_speculum_border(side='left'):
    """Create white border around speculum."""
    y_offset = 0.535 if side == 'left' else -0.535
    bpy.ops.mesh.primitive_cube_add(size=1.0, location=(0.1, y_offset, 0.0))
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = f"DuckSpecBorder_{side.capitalize()}"
    obj.scale = (0.38, 0.018, 0.04)
    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
    
    subsurf = obj.modifiers.new(name="Subsurf", type='SUBSURF')
    subsurf.levels = 1
    add_smooth_shading(obj)
    return obj


def create_tail_base():
    """Create the tail base."""
    bpy.ops.mesh.primitive_cone_add(
        vertices=16, radius1=0.28, radius2=0.08, depth=0.65,
        location=(1.75, 0, 0.05)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = "DuckTailBase"
    obj.rotation_euler = (0, math.radians(-15), 0)
    add_smooth_shading(obj)
    return obj


def create_tail_feather(index, total=6):
    """Create individual tail feathers."""
    angle = (index - total / 2 + 0.5) * 0.12
    y_offset = math.sin(angle) * 0.15
    z_offset = -abs(index - total / 2 + 0.5) * 0.03
    
    bpy.ops.mesh.primitive_cube_add(
        size=1.0,
        location=(2.0 + index * 0.02, y_offset, 0.02 + z_offset)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = f"DuckTailFeather_{index}"
    obj.scale = (0.35, 0.025, 0.06)
    obj.rotation_euler = (0, math.radians(-8), angle)
    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
    
    bpy.ops.object.mode_set(mode='EDIT')
    bm = bmesh.from_edit_mesh(obj.data)
    bm.verts.ensure_lookup_table()
    
    for v in bm.verts:
        if v.co.x > 0:
            v.co.z *= 0.7
            v.co.y *= 0.7
    
    bmesh.update_edit_mesh(obj.data)
    bpy.ops.object.mode_set(mode='OBJECT')
    
    subsurf = obj.modifiers.new(name="Subsurf", type='SUBSURF')
    subsurf.levels = 1
    add_smooth_shading(obj)
    return obj


def create_curl_feather():
    """Create the distinctive curled central tail feather of drake."""
    bpy.ops.mesh.primitive_torus_add(
        major_radius=0.09, minor_radius=0.025,
        major_segments=16, minor_segments=8,
        location=(2.15, 0, 0.12)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = "DuckCurlFeather"
    obj.rotation_euler = (math.radians(90), math.radians(30), 0)
    obj.scale = (1.0, 1.5, 0.8)
    bpy.ops.object.transform_apply(location=False, rotation=True, scale=True)
    
    bpy.ops.object.mode_set(mode='EDIT')
    bm = bmesh.from_edit_mesh(obj.data)
    bm.verts.ensure_lookup_table()
    
    verts_to_remove = [v for v in bm.verts if v.co.x < -0.02]
    if verts_to_remove:
        bmesh.ops.delete(bm, geom=verts_to_remove, context='VERTS')
    
    bmesh.update_edit_mesh(obj.data)
    bpy.ops.object.mode_set(mode='OBJECT')
    add_smooth_shading(obj)
    return obj


def create_undertail():
    """Create the black and white undertail coverts."""
    bpy.ops.mesh.primitive_uv_sphere_add(
        segments=16, ring_count=8, radius=0.2,
        location=(1.55, 0, -0.15)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = "DuckUndertail"
    obj.scale = (0.6, 0.8, 0.5)
    add_smooth_shading(obj)
    return obj


def create_leg(side='left'):
    """Create tarsometatarsus (visible leg)."""
    y_offset = 0.28 if side == 'left' else -0.28
    bpy.ops.mesh.primitive_cylinder_add(
        vertices=12, radius=0.04, depth=0.45,
        location=(0.15, y_offset, -0.65)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = f"DuckLeg_{side.capitalize()}"
    obj.rotation_euler = (math.radians(8), 0, 0)
    add_smooth_shading(obj)
    return obj


def create_ankle(side='left'):
    """Create ankle joint."""
    y_offset = 0.28 if side == 'left' else -0.28
    bpy.ops.mesh.primitive_uv_sphere_add(
        segments=10, ring_count=5, radius=0.055,
        location=(0.12, y_offset, -0.42)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = f"DuckAnkle_{side.capitalize()}"
    add_smooth_shading(obj)
    return obj


def create_foot(side='left'):
    """Create webbed foot."""
    y_offset = 0.28 if side == 'left' else -0.28
    bpy.ops.mesh.primitive_cube_add(
        size=1.0,
        location=(0.0, y_offset, -0.92)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = f"DuckFoot_{side.capitalize()}"
    obj.scale = (0.28, 0.35, 0.025)
    bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
    
    bpy.ops.object.mode_set(mode='EDIT')
    bm = bmesh.from_edit_mesh(obj.data)
    bm.verts.ensure_lookup_table()
    
    for v in bm.verts:
        if v.co.x < -0.05:
            factor = (-v.co.x - 0.05) / 0.23
            v.co.y *= 1.0 + factor * 0.5
        if v.co.x > 0.1:
            v.co.y *= 0.5
    
    bmesh.update_edit_mesh(obj.data)
    bpy.ops.object.mode_set(mode='OBJECT')
    
    subsurf = obj.modifiers.new(name="Subsurf", type='SUBSURF')
    subsurf.levels = 1
    add_smooth_shading(obj)
    return obj


def create_toe(side='left', toe_index=0):
    """Create individual toe."""
    y_base = 0.28 if side == 'left' else -0.28
    toe_angles = [-0.4, 0, 0.4]
    angle = toe_angles[toe_index]
    
    y_offset = y_base + math.sin(angle) * 0.15
    x_offset = -0.15 - math.cos(angle) * 0.05
    
    bpy.ops.mesh.primitive_cylinder_add(
        vertices=8, radius=0.018, depth=0.22,
        location=(x_offset, y_offset, -0.93)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = f"DuckToe_{side.capitalize()}_{toe_index}"
    obj.rotation_euler = (math.radians(90), angle, 0)
    add_smooth_shading(obj)
    return obj


def create_hind_toe(side='left'):
    """Create small hind toe (hallux)."""
    y_offset = 0.28 if side == 'left' else -0.28
    bpy.ops.mesh.primitive_cone_add(
        vertices=8, radius1=0.02, radius2=0.008, depth=0.08,
        location=(0.12, y_offset, -0.88)
    )
    obj = bpy.context.active_object
    if obj is None:
        return None
    obj.name = f"DuckHindToe_{side.capitalize()}"
    obj.rotation_euler = (math.radians(-120), 0, 0)
    add_smooth_shading(obj)
    return obj


def create_mallard_duck():
    """Main function to create complete mallard duck model."""
    
    # Define materials for male mallard (drake)
    mat_green_head = create_material(
        "MallardGreenHead",
        (0.0, 0.25, 0.12, 1.0),
        metallic=0.35, roughness=0.25, subsurface=0.1
    )
    mat_gray_body = create_material(
        "MallardGrayBody",
        (0.45, 0.42, 0.38, 1.0),
        metallic=0.0, roughness=0.65
    )
    mat_chestnut_breast = create_material(
        "MallardChestnutBreast",
        (0.35, 0.12, 0.08, 1.0),
        metallic=0.0, roughness=0.55, subsurface=0.05
    )
    mat_white = create_material(
        "MallardWhite",
        (0.95, 0.95, 0.95, 1.0),
        metallic=0.0, roughness=0.45
    )
    mat_yellow_bill = create_material(
        "MallardYellowBill",
        (0.75, 0.65, 0.15, 1.0),
        metallic=0.0, roughness=0.4, subsurface=0.05
    )
    mat_black = create_material(
        "MallardBlack",
        (0.02, 0.02, 0.02, 1.0),
        metallic=0.0, roughness=0.3
    )
    mat_orange_leg = create_material(
        "MallardOrangeLeg",
        (0.9, 0.45, 0.1, 1.0),
        metallic=0.0, roughness=0.5, subsurface=0.08
    )
    mat_blue_speculum = create_material(
        "MallardBlueSpeculum",
        (0.1, 0.15, 0.55, 1.0),
        metallic=0.4, roughness=0.2
    )
    mat_eye = create_material(
        "MallardEye",
        (0.08, 0.04, 0.02, 1.0),
        metallic=0.0, roughness=0.1
    )
    mat_dark_tail = create_material(
        "MallardDarkTail",
        (0.08, 0.06, 0.05, 1.0),
        metallic=0.0, roughness=0.6
    )
    
    part_names = []
    
    # Body
    body = create_duck_body()
    if body:
        assign_material(body, mat_gray_body)
        part_names.append(body.name)
    
    # Breast
    breast = create_duck_breast()
    if breast:
        assign_material(breast, mat_chestnut_breast)
        part_names.append(breast.name)
    
    # Neck
    neck = create_duck_neck()
    if neck:
        assign_material(neck, mat_green_head)
        part_names.append(neck.name)
    
    # White collar
    collar = create_white_collar()
    if collar:
        assign_material(collar, mat_white)
        part_names.append(collar.name)
    
    # Head
    head = create_duck_head()
    if head:
        assign_material(head, mat_green_head)
        part_names.append(head.name)
    
    # Bill
    bill = create_duck_bill()
    if bill:
        assign_material(bill, mat_yellow_bill)
        part_names.append(bill.name)
    
    # Bill nail
    nail = create_bill_nail()
    if nail:
        assign_material(nail, mat_black)
        part_names.append(nail.name)
    
    # Nostrils
    nostril_l = create_nostril()
    if nostril_l:
        assign_material(nostril_l, mat_black)
        part_names.append(nostril_l.name)
    
    nostril_r = create_nostril_right()
    if nostril_r:
        assign_material(nostril_r, mat_black)
        part_names.append(nostril_r.name)
    
    # Eyes
    for side in ['left', 'right']:
        eye = create_eye(side)
        if eye:
            assign_material(eye, mat_eye)
            part_names.append(eye.name)
        
        eye_ring = create_eye_ring(side)
        if eye_ring:
            assign_material(eye_ring, mat_black)
            part_names.append(eye_ring.name)
    
    # Wings
    for side in ['left', 'right']:
        wing = create_wing(side)
        if wing:
            assign_material(wing, mat_gray_body)
            part_names.append(wing.name)
        
        speculum = create_speculum(side)
        if speculum:
            assign_material(speculum, mat_blue_speculum)
            part_names.append(speculum.name)
        
        spec_border = create_speculum_border(side)
        if spec_border:
            assign_material(spec_border, mat_white)
            part_names.append(spec_border.name)
    
    # Tail
    tail_base = create_tail_base()
    if tail_base:
        assign_material(tail_base, mat_dark_tail)
        part_names.append(tail_base.name)
    
    for i in range(6):
        feather = create_tail_feather(i)
        if feather:
            assign_material(feather, mat_dark_tail)
            part_names.append(feather.name)
    
    curl = create_curl_feather()
    if curl:
        assign_material(curl, mat_dark_tail)
        part_names.append(curl.name)
    
    undertail = create_undertail()
    if undertail:
        assign_material(undertail, mat_black)
        part_names.append(undertail.name)
    
    # Legs and feet
    for side in ['left', 'right']:
        leg = create_leg(side)
        if leg:
            assign_material(leg, mat_orange_leg)
            part_names.append(leg.name)
        
        ankle = create_ankle(side)
        if ankle:
            assign_material(ankle, mat_orange_leg)
            part_names.append(ankle.name)
        
        foot = create_foot(side)
        if foot:
            assign_material(foot, mat_orange_leg)
            part_names.append(foot.name)
        
        for toe_i in range(3):
            toe = create_toe(side, toe_i)
            if toe:
                assign_material(toe, mat_orange_leg)
                part_names.append(toe.name)
        
        hind_toe = create_hind_toe(side)
        if hind_toe:
            assign_material(hind_toe, mat_orange_leg)
            part_names.append(hind_toe.name)
    
    # Join all parts
    bpy.ops.object.select_all(action='DESELECT')
    
    base_obj = None
    for name in part_names:
        obj = bpy.data.objects.get(name)
        if obj:
            obj.select_set(True)
            if base_obj is None:
                base_obj = obj
    
    if base_obj:
        bpy.context.view_layer.objects.active = base_obj
        bpy.ops.object.join()
        
        duck = bpy.context.active_object
        if duck:
            duck.name = "Mallard_Duck_Anas_platyrhynchos"
            
            # Apply modifiers
            bpy.ops.object.select_all(action='DESELECT')
            duck.select_set(True)
            bpy.context.view_layer.objects.active = duck
            
            for mod in duck.modifiers:
                try:
                    bpy.ops.object.modifier_apply(modifier=mod.name)
                except Exception:
                    pass
            
            duck = bpy.data.objects.get("Mallard_Duck_Anas_platyrhynchos")
            if duck:
                # Add final subdivision
                subsurf = duck.modifiers.new(name="Subdivision", type='SUBSURF')
                subsurf.levels = 1
                subsurf.render_levels = 2
                
                # Set origin to center
                bpy.ops.object.select_all(action='DESELECT')
                duck.select_set(True)
                bpy.context.view_layer.objects.active = duck
                bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY', center='BOUNDS')
                
                duck.location = (0, 0, 0)
                duck.rotation_euler = (0, 0, 0)
    
    return bpy.data.objects.get("Mallard_Duck_Anas_platyrhynchos")


# Execute
create_mallard_duck()