"""Seat coupon — a cheap test-fit print before committing to cast.

Cuts the HEAD of the fused body (seat, prongs, shoulder stubs) onto a flat
base tab. The jeweler prints it in ordinary rigid resin and drops the REAL
diamond in: verifies girdle diameter and level seating for pennies. Exported
at NOMINAL dims (it simulates the post-cast metal, not the shrink-compensated
print). Rigid resin has no prong spring — it checks the seat, not the set.
"""

from __future__ import annotations

import importlib.util
import sys
from pathlib import Path

from build123d import Align, Box, Pos, export_stl

from ringcli.cast import _make_watertight


def export_coupon(gen_path: str, out_stl: str) -> None:
    gen = Path(gen_path)
    spec = importlib.util.spec_from_file_location("gen_mod", gen)
    mod = importlib.util.module_from_spec(spec)
    sys.path.insert(0, str(gen.parent))
    spec.loader.exec_module(mod)
    from ringcli.templates import head_dims
    hd = head_dims(mod.SPEC)
    body = mod.gen_metal()
    z_cut = hd["outer_r"] - 1.0
    w = 2 * (hd["stone_l"] / 2 + 4.0)
    keep = Pos(0, 0, z_cut) * Box(w, w, 40, align=(Align.CENTER, Align.CENTER,
                                                   Align.MIN))
    head = body & keep
    tab = Pos(0, 0, z_cut + 0.01) * Box(w - 1.0, w - 1.0, 1.5,
                                        align=(Align.CENTER, Align.CENTER,
                                               Align.MAX))
    coupon = head + tab
    solids = coupon.solids()
    main = max(solids, key=lambda s: s.volume)
    if len(solids) > 1 and main.volume < 0.95 * sum(s.volume for s in solids):
        raise RuntimeError(f"coupon split into {len(solids)} solids")
    export_stl(main, out_stl, tolerance=0.01, angular_tolerance=0.3)
    _make_watertight(out_stl)


if __name__ == "__main__":
    export_coupon(sys.argv[1], sys.argv[2])
    print(f"coupon STL: {sys.argv[2]}")
