#!/usr/bin/env python3
"""Junction Box v3 — parametric, matches original structure exactly.
Original: 60x60x17 base + 60x60x10 lid.
Target: 80x70x50 total = 80x70x32 base + 80x70x18 lid.
"""
from build123d import *
import os

OUT = "/app/projects/esp32-box/exports"
os.makedirs(OUT, exist_ok=True)

# Parameters
W=80.0; D=70.0; H=50.0
TOL=0.15
WALL=2.0        # thin wall ~ original
POST_W=10.0     # corner post ~ proportional to original 7.6mm
BASE_H=32.0; LID_H=18.0

# Window dimensions (proportional to original)
WIN_W=14.0      # window panel width (fits in slot)
SLOT_H=BASE_H-7.0  # window opening height

SCREW_R=1.3     # M2.5

def box_like(parts_list):
    result = parts_list[0]
    for p in parts_list[1:]:
        result += p
    return result

def build_base():
    parts = []
    # 4 corner posts
    for sx in [-1, 1]:
        for sy in [-1, 1]:
            cx = sx * (W/2 - POST_W/2)
            cy = sy * (D/2 - POST_W/2)
            post = Box(POST_W, POST_W, BASE_H)
            hole = Cylinder(SCREW_R+TOL, SCREW_R+TOL, BASE_H+0.2)
            parts.append(Pos(cx, cy, BASE_H/2) * (post - hole))

    # Walls: X-axis (front/back Y=±D/2), Y-axis (left/right X=±W/2)
    for sy in [-1, 1]:
        py = sy * (D/2 - WALL/2)
        parts.append(Pos(0, py, BASE_H/2) * Box(W, WALL, BASE_H))
    for sx in [-1, 1]:
        px = sx * (W/2 - WALL/2)
        parts.append(Pos(px, 0, BASE_H/2) * Box(WALL, D, BASE_H))

    base = box_like(parts)

    # Cut window openings in walls
    # X-walls (front/back): opening between corner posts
    slot_gap = 1.5  # gap from post corner
    for sy in [-1, 1]:
        py = sy * (D/2 - WALL/2)
        sx_len = W - 2*POST_W - 2*slot_gap
        slot = Pos(0, py, 2.0+SLOT_H/2) * Box(sx_len, WALL+0.4, SLOT_H)
        base -= slot

    # Y-walls (left/right): opening between corner posts
    for sx in [-1, 1]:
        px = sx * (W/2 - WALL/2)
        sy_len = D - 2*POST_W - 2*slot_gap
        slot = Pos(px, 0, 2.0+SLOT_H/2) * Box(WALL+0.4, sy_len, SLOT_H)
        base -= slot

    return base

def build_lid():
    lid = Box(W, D, 2.0)  # top plate

    # Edge walls
    for sx in [-1, 1]:
        lid += Pos(0, sx*(D/2 - WALL/2), 1.5/2) * Box(W, WALL, 1.5)
    for sy in [-1, 1]:
        lid += Pos(sy*(W/2 - WALL/2), 0, 1.5/2) * Box(WALL, D, 1.5)

    # Tongue blocks (fit into base corner posts)
    tsize = POST_W - 1.0  # slightly smaller than post
    th = 3.0
    for sx in [-1, 1]:
        for sy in [-1, 1]:
            cx = sx * (W/2 - POST_W/2)
            cy = sy * (D/2 - POST_W/2)
            t = Pos(cx, cy, -th/2) * Box(tsize-TOL, tsize-TOL, th)
            lid += t

    # Screw holes
    for sx in [-1, 1]:
        for sy in [-1, 1]:
            cx = sx * (W/2 - POST_W/2)
            cy = sy * (D/2 - POST_W/2)
            lid -= Pos(cx, cy, 0) * Cylinder(SCREW_R+TOL, SCREW_R+TOL, LID_H+0.2)

    # Internal ribs (matching original pattern)
    # X ribs (3 ribs spanning Y direction)
    for i in range(3):
        rx = -W/4 + i * W/4
        lid += Pos(rx, 0, -LID_H/2 + 4.0) * Box(1.5, D-2*POST_W, 8.0)
    # Y ribs (3 ribs spanning X direction)
    for i in range(3):
        ry = -D/4 + i * D/4
        lid += Pos(0, ry, -LID_H/2 + 4.0) * Box(W-2*POST_W, 1.5, 8.0)

    return lid

def build_window(cutouts=None):
    pw = W - 2*POST_W  # panel width between corner posts
    ph = WIN_W          # panel thickness
    pd = SLOT_H         # panel depth
    panel = Box(pw, ph, pd)
    # Retention tabs (small bumps)
    for side in [-1, 1]:
        tab = Pos(0, side*(ph/2-0.5), 0) * Box(pw-2, 1.0, pd+0.5)
        panel += tab
    if cutouts:
        for cx, cy, cw, ch in cutouts:
            panel -= Pos(cx, cy, 0) * Box(cw, ch, pd+0.2)
    return panel

# Generate
print("Building base...")
base = build_base()
export_stl(base, "%s/base.stl" % OUT)
print("  base.stl: %.0fx%.0fx%.0fmm" % (W, D, BASE_H))

print("Building lid...")
lid = build_lid()
export_stl(lid, "%s/lid.stl" % OUT)
print("  lid.stl: %.0fx%.0fx%.0fmm" % (W, D, LID_H))

print("Building window panels...")
pw = W - 2*POST_W
export_stl(build_window(), "%s/window_smooth.stl" % OUT)
print("  window_smooth.stl (x2): %dx%dmm" % (pw, WIN_W))

# Keystone+DC: keystone 17x14mm, DC 9x9mm
kc = [(-pw/4, 0, 17, WIN_W+0.5), (pw/4, 0, 9, 9)]
export_stl(build_window(kc), "%s/window_keystone_dc.stl" % OUT)
print("  window_keystone_dc.stl")

# USB: 9x5mm
export_stl(build_window([(0, 0, 9, 5)]), "%s/window_usb.stl" % OUT)
print("  window_usb.stl")

print("Building screw...")
screw = Cylinder(3.0, 3.0, 2.0) + Pos(0, 0, -5.0) * Cylinder(SCREW_R, SCREW_R, 10.0)
export_stl(screw, "%s/screw.stl" % OUT)
print("  screw.stl")

print("\nDONE! Preview at: http://workspace.3d.popcomputadores.com.br/esp32-box/exports/")
