import { clamp } from "../../../math/clamp.js";
import { min2 } from "../../../math/min2.js";

/**
 *
 * @param {number[]|ArrayLike<number>} result
 * @param {number} x0
 * @param {number} y0
 * @param {number} z0
 * @param {number} x1
 * @param {number} y1
 * @param {number} z1
 * @param {number} r_x
 * @param {number} r_y
 * @param {number} r_z
 */
export function aabb3_nearest_point_on_surface(result, x0, y0, z0, x1, y1, z1, r_x, r_y, r_z) {
    // clamp the reference to the box; for exterior points this is already the nearest surface point
    const cx = clamp(r_x, x0, x1);
    const cy = clamp(r_y, y0, y1);
    const cz = clamp(r_z, z0, z1);

    const inside = (cx === r_x) && (cy === r_y) && (cz === r_z);

    if (!inside) {
        result[0] = cx;
        result[1] = cy;
        result[2] = cz;
        return;
    }

    // interior point: snap to the nearest face
    const dx0 = r_x - x0;
    const dx1 = x1 - r_x;
    const dy0 = r_y - y0;
    const dy1 = y1 - r_y;
    const dz0 = r_z - z0;
    const dz1 = z1 - r_z;

    const dx = min2(dx0, dx1);
    const dy = min2(dy0, dy1);
    const dz = min2(dz0, dz1);

    if (dx <= dy && dx <= dz) {
        result[0] = (dx0 <= dx1) ? x0 : x1;
        result[1] = r_y;
        result[2] = r_z;
    } else if (dy <= dz) {
        result[0] = r_x;
        result[1] = (dy0 <= dy1) ? y0 : y1;
        result[2] = r_z;
    } else {
        result[0] = r_x;
        result[1] = r_y;
        result[2] = (dz0 <= dz1) ? z0 : z1;
    }
}
