// Nova Configurator — iso drag-to-place planner + live quote + financing.
// The product catalog and material lines now live in /shared/catalog.js (loaded
// before this script) so the browser and the checkout function price from one
// source. This file keeps the client-only axonometric projection helpers.

// ---- Projection ---------------------------------------------------------
// Pixels per foot (zoom)
const PX_PER_FT = 14;

// Each view is an axonometric projection defined by 2D basis vectors for the
// x (width), y (depth) and z (height) world axes. screen = x*ax + y*ay + z*az.
const C30 = Math.cos(Math.PI / 6), S30 = Math.sin(Math.PI / 6);
const CFG_VIEWS = {
  iso:   { label: "Iso",   ax: [ C30 * PX_PER_FT,  S30 * PX_PER_FT], ay: [-C30 * PX_PER_FT, S30 * PX_PER_FT], az: [0, -PX_PER_FT] },
  front: { label: "Front", ax: [ PX_PER_FT,        0],               ay: [ 0,               0],              az: [0, -PX_PER_FT] },
  top:   { label: "Top",   ax: [ PX_PER_FT,        0],               ay: [ 0,               PX_PER_FT],      az: [0, 0] },
};

// Build a projector for a given view -> proj(x,y,z) returns [px, py]
function makeProjector(view) {
  const V = CFG_VIEWS[view] || CFG_VIEWS.iso;
  return (xFt, yFt, zFt = 0) => [
    xFt * V.ax[0] + yFt * V.ay[0] + zFt * V.az[0],
    xFt * V.ax[1] + yFt * V.ay[1] + zFt * V.az[1],
  ];
}

// Invert a screen-px delta back to ground-plane (z=0) feet for the given view.
// Falls back to the dominant axis when the projection is degenerate (e.g. the
// front elevation has no on-screen depth axis).
function groundInverse(view, sx, sy) {
  const V = CFG_VIEWS[view] || CFG_VIEWS.iso;
  const a = V.ax, b = V.ay;
  const det = a[0] * b[1] - b[0] * a[1];
  if (Math.abs(det) > 1e-6) {
    return [(sx * b[1] - b[0] * sy) / det, (a[0] * sy - sx * a[1]) / det];
  }
  const denom = a[0] * a[0] + a[1] * a[1] || 1;
  const t = (sx * a[0] + sy * a[1]) / denom;
  return [t, 0];
}

// Legacy iso helper (kept for compatibility)
function iso(xFt, yFt, zFt = 0) {
  return makeProjector("iso")(xFt, yFt, zFt);
}

// Pretty USD
const $ = (n) => n.toLocaleString("en-US", { style: "currency", currency: "USD", maximumFractionDigits: 0 });

window.CFG_VIEWS = CFG_VIEWS;
window.PX_PER_FT = PX_PER_FT;
window.makeProjector = makeProjector;
window.groundInverse = groundInverse;
window.iso = iso;
window.fmtUSD = $;
