/**
 *
 * @param {number} d0 distance at v0
 * @param {number} d1 distance at v1
 * @param {number} x0 X coordinate of v0
 * @param {number} y0 Y coordinate of v0
 * @param {number} z0 Z coordinate of v0
 * @param {number} x1 X coordinate of v1
 * @param {number} y1 Y coordinate of v1
 * @param {number} z1 Z coordinate of v1
 * @param {number} px X coordinate of reference point
 * @param {number} py Y coordinate of reference point
 * @param {number} pz Z coordinate of reference point
 * @returns {number} The exact geodesic distance
 */
export function line3_compute_segment_point_distance_eikonal(
    d0, d1,
    x0, y0, z0,
    x1, y1, z1,
    px, py, pz
) {
    // 2. Map to 2D Local Coordinate System
    // A (v0) is origin (0,0), B (v1) is (L, 0)
    const ab_x = x1 - x0;
    const ab_y = y1 - y0;
    const ab_z = z1 - z0;
    const L = Math.hypot(ab_x, ab_y, ab_z);

    if (L < 1e-9) return Math.min(d0, d1);

    // Vector AC
    const ac_x = px - x0;
    const ac_y = py - y0;
    const ac_z = pz - z0;

    // Project AC onto AB to find x coordinate of C
    const dot = ac_x * ab_x + ac_y * ab_y + ac_z * ab_z;
    const x = dot / L;

    // Find height (y coordinate) of C
    const ac_sq_len = ac_x * ac_x + ac_y * ac_y + ac_z * ac_z;
    const y_sq = ac_sq_len - x * x;
    const y = y_sq > 0 ? Math.sqrt(y_sq) : 0;

    // 3. Prepare for Eikonal Update
    let u0 = d0;
    let u1 = d1;
    let x_local = x;

    // We need to track which vertex corresponds to u0 for fallback logic
    let dist_to_u0_vertex_sq = ac_sq_len;

    // Mirror if d1 < d0 to ensure u0 <= u1
    if (d1 < d0) {
        u0 = d1;
        u1 = d0;
        x_local = L - x;
        // If u0 is now v1, we need distance from v1 to C (BC squared)
        // BC^2 = AC^2 + L^2 - 2 * AC * AB_normalized (Law of Cosines / Vector arithmetic)
        // Or simply recalculate:
        const bc_x = px - x1;
        const bc_y = py - y1;
        const bc_z = pz - z1;
        dist_to_u0_vertex_sq = bc_x * bc_x + bc_y * bc_y + bc_z * bc_z;
    }

    const u = u1 - u0;

    // 4. Causality & Consistency Checks

    // Lipschitz / Gradient limit check
    if (u >= L) {
        // FIX: Use the distance to the vertex associated with u0 (the smaller value)
        return u0 + Math.sqrt(dist_to_u0_vertex_sq);
    }

    // "Virtual Source" Direction check
    const p = u;
    const q = L;
    const det = q * q - p * p;
    const det_sqrt = Math.sqrt(Math.max(0, det));
    const coef = p / det_sqrt;
    const s = x_local - y * coef; // Intersection with x-axis

    if (s > 0) {
        // 5. Valid Eikonal Update
        return u0 + (p * x_local + y * det_sqrt) / q;
    } else {
        // 6. Fallback (The path comes strictly from one of the vertices)
        const dist_to_v0 = Math.sqrt(ac_sq_len);
        // Recalculate dist_to_v1 explicitly to be safe
        const dist_to_v1 = Math.hypot(px - x1, py - y1, pz - z1);
        return Math.min(d0 + dist_to_v0, d1 + dist_to_v1);
    }
}