import bpy
import sys
import os

# --- Parse Arguments ---
# structure: [..., 'input.svg', 'output.stl', 'thickness', 'invert_flag', 'padding']
try:
    argv = sys.argv
    argv = argv[argv.index("--") + 1:]
    
    input_svg = argv[0]
    output_stl = argv[1]
    thickness_mm = float(argv[2])
    # Read the 4th argument as integer (1 or 0), convert to boolean
    invert_mode = bool(int(argv[3])) if len(argv) > 3 else False
    # Read Padding (Default 0.0)
    padding_mm = float(argv[4]) if len(argv) > 4 else 0.0
    
except (ValueError, IndexError) as e:
    print(f"Error parsing arguments: {e}")
    sys.exit(1)

# --- Step 1: Clean & Setup Units ---
bpy.ops.wm.read_factory_settings(use_empty=True)

scene = bpy.context.scene
scene.unit_settings.system = 'METRIC'
scene.unit_settings.length_unit = 'MILLIMETERS'
scene.unit_settings.scale_length = 0.001 

# --- Step 2: Import SVG ---
if not os.path.exists(input_svg):
    print(f"FATAL: File not found: {input_svg}")
    sys.exit(1)

bpy.ops.import_curve.svg(filepath=input_svg)

# --- Step 3: Geometry Processing ---
bpy.ops.object.select_all(action='SELECT')

if bpy.context.selected_objects:
    bpy.context.view_layer.objects.active = bpy.context.selected_objects[0]
    
    # 1. Join all parts
    bpy.ops.object.join()
    obj = bpy.context.active_object
    obj.name = "Pattern"

    # 2. Convert to Mesh
    bpy.ops.object.convert(target='MESH')

    # 3. Center Geometry
    bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY', center='BOUNDS')
    obj.location = (0, 0, 0)
    
    print(f"Imported Dimensions: {obj.dimensions.x:.2f}mm x {obj.dimensions.y:.2f}mm")

    def add_solidify(target_obj, thick, offset=0):
        mod = target_obj.modifiers.new(name='Solidify', type='SOLIDIFY')
        mod.thickness = thick
        mod.use_even_offset = True
        mod.use_rim = True
        mod.offset = offset 
        bpy.context.view_layer.objects.active = target_obj
        bpy.ops.object.modifier_apply(modifier=mod.name)

    # --- Step 4: Logic Branch ---
    if invert_mode:
        print(f"--- INVERSION MODE (Negative) ---")
        if padding_mm > 0:
            print(f"Applying Padding: {padding_mm}mm (Total Extra Width: {padding_mm*2}mm)")

        # 1. Cutter (thicker than base)
        cutter_thickness = thickness_mm * 3.0
        add_solidify(obj, cutter_thickness, offset=0)
        
        # 2. Base Plate
        bpy.ops.mesh.primitive_cube_add(location=(0,0,0))
        base = bpy.context.active_object
        base.name = "BasePlate"
        
        # Calculate Dimensions with Padding
        # Padding is added to all sides, so width increases by padding*2
        final_x = obj.dimensions.x + (padding_mm * 2)
        final_y = obj.dimensions.y + (padding_mm * 2)
        
        base.dimensions = (final_x, final_y, thickness_mm)
        
        # Apply transforms so scale is 1,1,1
        bpy.ops.object.transform_apply(scale=True)
        base.location = (0,0,0) 
        
        # 3. Boolean Difference
        print("Applying Boolean Difference...")
        bool_mod = base.modifiers.new(name='Boolean', type='BOOLEAN')
        bool_mod.object = obj
        bool_mod.operation = 'DIFFERENCE'
        bool_mod.solver = 'EXACT' 
        
        try:
            bpy.context.view_layer.objects.active = base
            bpy.ops.object.modifier_apply(modifier=bool_mod.name)
        except Exception as e:
            print(f"Warning: Exact Boolean failed. {e}")
            bool_mod.solver = 'FAST'
            bpy.ops.object.modifier_apply(modifier=bool_mod.name)

        bpy.data.objects.remove(obj, do_unlink=True)
        obj = base 

    else:
        print(f"--- STANDARD MODE (Positive) ---")
        add_solidify(obj, thickness_mm, offset=0)

    # --- Step 5: Final Placement (Z=0) ---
    bpy.context.view_layer.update()
    min_z = min([c[2] for c in obj.bound_box])
    obj.location.z -= min_z
    
    # --- Step 6: Export ---
    print(f"Exporting to: {output_stl}")
    bpy.ops.object.mode_set(mode='OBJECT')
    bpy.ops.object.select_all(action='DESELECT')
    obj.select_set(True)
    bpy.context.view_layer.objects.active = obj
    
    bpy.ops.wm.stl_export(filepath=output_stl, global_scale=1.0)
    
else:
    print("Error: No objects found in SVG.")
    sys.exit(1)