#!/usr/bin/env python3
"""Caixa Eletrônica Paramétrica - Build123d 0.11.1"""
from build123d import *
import json, sys, os

# === Parâmetros (podem vir de JSON) ===
params = {
    "largura_interna": 100.0,
    "comprimento_interno": 160.0,
    "altura_interna": 40.0,
    "espessura_parede": 2.4,
    "espessura_fundo": 2.4,
    "espessura_tampa": 2.4,
    "tolerancia_encaixe": 0.2,
    "altura_rasgo": 3.0,
    "largura_rasgo": 3.0,
    "raio_canto_interno": 2.0,
    "raio_canto_externo": 3.0,  # reduzido para fillet funcionar
    "furos_parafuso": True,
    "diametro_furo": 3.2,
    "diametro_encaixe_parafuso": 6.0,
    "profundidade_encaixe": 4.0,
    "ventilacao": False,
    "num_furow_vent": 5,
    "diametro_furo_vent": 4.0,
}

if len(sys.argv) > 1:
    with open(sys.argv[1]) as f:
        params.update(json.load(f))

L = params["largura_interna"]
C = params["comprimento_interno"]
H = params["altura_interna"]
tp = params["espessura_parede"]
tf = params["espessura_fundo"]
tt = params["espessura_tampa"]
tol = params["tolerancia_encaixe"]
hr = params["altura_rasgo"]
lr = params["largura_rasgo"]
ri = params["raio_canto_interno"]
re = params["raio_canto_externo"]

L_ext = L + 2 * tp
C_ext = C + 2 * tp
H_ext = H + params["espessura_fundo"] + params["espessura_tampa"]

# BASE
with BuildPart() as base:
    Box(L + 2*params["espessura_parede"], C + 2*params["espessura_parede"], H + params["espessura_fundo"] + params["espessura_tampa"])
    
    with BuildSketch(Plane(origin=(0, 0, params["espessura_fundo"]))) as inner_sketch:
        Rectangle(params["largura_interna"], params["comprimento_interno"])
        fillet(inner_sketch.vertices(), params["raio_canto_interno"])
    extrude(amount=params["altura_interna"] + params["espessura_tampa"], mode=Mode.SUBTRACT)
    
    # Rasgo para tampa
    with Locations((0, params["comprimento_interno"]/2 - params["espessura_parede"]/2, params["altura_interna"]/2 + params["espessura_fundo"])):
        Box(params["largura_interna"] - 2*params["tolerancia_encaixe"], params["largura_rasgo"], params["altura_rasgo"], mode=Mode.SUBTRACT)
    with Locations((0, -params["comprimento_interno"]/2 + params["espessura_parede"]/2, params["altura_interna"]/2 + params["espessura_fundo"])):
        Box(params["largura_interna"] - 2*params["tolerancia_encaixe"], params["largura_rasgo"], params["altura_rasgo"], mode=Mode.SUBTRACT)

    # Fillet nas arestas superiores e inferiores (raio menor que a espessura)
    fillet(base.edges().group_by(Axis.Z)[-1], min(params["raio_canto_externo"], tp * 0.8))
    fillet(base.edges().group_by(Axis.Z)[0], min(params["raio_canto_externo"], tp * 0.8))

    # Furos de parafuso
    if params["furos_parafuso"]:
        d = params["diametro_furo"]
        de = params["diametro_encaixe_parafuso"]
        prof = params["profundidade_encaixe"]
        corners = [
            (-params["largura_interna"]/2 + params["espessura_parede"] + 5, -params["comprimento_interno"]/2 + params["espessura_parede"] + 5),
            (params["largura_interna"]/2 - params["espessura_parede"] - 5, -params["comprimento_interno"]/2 + params["espessura_parede"] + 5),
            (-params["largura_interna"]/2 + params["espessura_parede"] + 5, params["comprimento_interno"]/2 - params["espessura_parede"] - 5),
            (params["largura_interna"]/2 - params["espessura_parede"] - 5, params["comprimento_interno"]/2 - params["espessura_parede"] - 5),
        ]
        with BuildSketch(Plane(origin=(0, 0, params["espessura_fundo"]/2))) as screw_sketch:
            for cx, cy in corners:
                with Locations((cx, cy)):
                    Circle(params["diametro_furo"]/2)
                    Circle(params["diametro_encaixe_parafuso"]/2)
        extrude(amount=params["profundidade_encaixe"], mode=Mode.SUBTRACT)

# TAMPA
with BuildPart() as tampa:
    Box(params["largura_interna"] + 2*params["espessura_parede"] + 2*params["tolerancia_encaixe"],
        params["comprimento_interno"] + 2*params["espessura_parede"] + 2*params["tolerancia_encaixe"],
        params["espessura_tampa"])
    
    with BuildSketch(Plane(origin=(0, 0, 0))) as lid_inner:
        Rectangle(params["largura_interna"] + 2*params["tolerancia_encaixe"], 
                  params["comprimento_interno"] + 2*params["tolerancia_encaixe"])
        fillet(lid_inner.vertices(), params["raio_canto_externo"])
    extrude(amount=params["espessura_tampa"] - 0.2, mode=Mode.SUBTRACT)

    with BuildSketch(Plane(origin=(0, 0, 0))) as lip_sketch:
        Rectangle(params["largura_interna"] - 2*params["tolerancia_encaixe"], 
                  params["comprimento_interno"] - 2*params["tolerancia_encaixe"])
        fillet(lip_sketch.vertices(), params["raio_canto_interno"])
    extrude(amount=-params["altura_rasgo"], mode=Mode.ADD)
    
    fillet(tampa.edges().group_by(Axis.Z)[-1], 1.5)

# Export
export_dir = "/app/projects/caixa-eletronica/exports"
os.makedirs(export_dir, exist_ok=True)

export_stl(base.part, f"{export_dir}/caixa_base.stl")
export_stl(tampa.part, f"{export_dir}/caixa_tampa.stl")

try:
    export_step(base.part, f"{export_dir}/caixa_base.step")
    export_step(tampa.part, f"{export_dir}/caixa_tampa.step")
except:
    pass

vol_base = base.part.volume
vol_tampa = tampa.part.volume
print(f"=== Caixa Eletrônica ===")
print(f"Dimensoes internas: {params['largura_interna']}x{params['comprimento_interno']}x{params['altura_interna']} mm")
print(f"Parede: {params['espessura_parede']}mm")
print(f"Volume base: {base.part.volume:.0f} mm3")
print(f"Volume tampa: {tampa.part.volume:.0f} mm3")
print(f"Peso estimado PLA: {(base.part.volume + tampa.part.volume)*1.24/1000:.1f}g")
print(f"STL exportado para {export_dir}/")

if "SHOW" in os.environ:
    show(base.part, tampa.part)
