"""Interference check: every printed part against every solid of the official board STEP,
the camera mock-up and the flex cable. Contacts by design (standoffs, pillars) show up as
near-zero volumes; anything above the threshold is reported."""
import os
import sys
from build123d import import_step, Solid, Compound

HERE = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, HERE)
import coral_eye as ce  # noqa: E402

STEP = os.path.normpath(os.path.join(HERE, "..", "..", "referencia-oficial", "Synaptics_CoralBoard_SL.step"))
THRESH = 0.02   # mm^3


def bbox_overlap(a, b, pad=0.0):
    return not (a.max.X + pad < b.min.X or b.max.X + pad < a.min.X or
                a.max.Y + pad < b.min.Y or b.max.Y + pad < a.min.Y or
                a.max.Z + pad < b.min.Z or b.max.Z + pad < a.min.Z)


def check(part_name, part, others):
    pb = part.bounding_box()
    hits = []
    for name, s in others:
        sb = s.bounding_box()
        if not bbox_overlap(pb, sb):
            continue
        try:
            inter = part & s
            v = inter.volume if inter is not None else 0.0
        except Exception as e:  # noqa: BLE001
            v = -1.0
        if v > THRESH or v < 0:
            hits.append((name, v, sb))
    print(f"== {part_name}: {len(hits)} interference(s)")
    for name, v, sb in sorted(hits, key=lambda h: -h[1]):
        print(f"   {name:40s} {v:9.3f} mm3   x[{sb.min.X:6.2f},{sb.max.X:6.2f}] y[{sb.min.Y:6.2f},{sb.max.Y:6.2f}] z[{sb.min.Z:6.2f},{sb.max.Z:6.2f}]")
    return hits


if __name__ == "__main__":
    board = import_step(STEP)
    solids = board.solids()
    print("board solids:", len(solids))
    named = []
    for i, s in enumerate(solids):
        bb = s.bounding_box()
        named.append((f"board#{i} ({bb.size.X:.1f}x{bb.size.Y:.1f}x{bb.size.Z:.1f})", s))
    pcb, block, conn = ce.make_camera_mock()
    cam = [("camera pcb", pcb), ("camera lens", block), ("camera conn+flex", conn)]
    cable = [("flex cable seg%d" % i, p) for i, p in enumerate(ce.make_flex_cable())]
    body = ce.make_body()
    face = ce.make_face("skin")
    check("BODY vs board", body, named)
    check("FACE vs board", face, named)
    check("BODY vs camera/cable", body, cam + cable)
    check("FACE vs camera/cable", face, cam + cable)
    check("CAMERA vs board", Compound(children=[pcb, block, conn]), named)
    check("CABLE vs board", Compound(children=[c[1] for c in cable]), named)
    inter = body & face
    print("BODY vs FACE overlap volume: %.3f mm3" % (inter.volume if inter else 0.0))
