package com.tiedup.remake.v2.furniture;

import static org.junit.jupiter.api.Assertions.assertEquals;

import net.minecraft.world.phys.Vec3;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

/**
 * Tests for the server-side fallback seat-geometry math extracted from the
 * three inlined {@code EntityFurniture} call sites.
 *
 * <p>The formulas themselves are trivial; these tests are a regression guard
 * against someone "cleaning up" the right-axis expression and inverting a
 * sign, or changing the seat-spacing convention (which is observable in
 * gameplay — passengers shift left/right on asymmetric furniture).</p>
 */
class FurnitureSeatGeometryTest {

    private static final double EPS = 1e-9;

    @Nested
    @DisplayName("rightAxis — entity-local right in world XZ")
    class RightAxis {

        @Test
        @DisplayName("yaw=0 → right axis points to world -X (MC south-facing convention)")
        void yawZero() {
            Vec3 r = FurnitureSeatGeometry.rightAxis(0f);
            assertEquals(-1.0, r.x, EPS);
            assertEquals(0.0, r.y, EPS);
            assertEquals(0.0, r.z, EPS);
        }

        @Test
        @DisplayName("yaw=180 → right axis flips to +X")
        void yaw180() {
            Vec3 r = FurnitureSeatGeometry.rightAxis(180f);
            assertEquals(1.0, r.x, EPS);
            assertEquals(0.0, r.z, EPS);
        }

        @Test
        @DisplayName("yaw=90 → right axis points to world -Z")
        void yaw90() {
            Vec3 r = FurnitureSeatGeometry.rightAxis(90f);
            assertEquals(0.0, r.x, EPS);
            assertEquals(-1.0, r.z, EPS);
        }

        @Test
        @DisplayName("Y is always 0 (right axis is horizontal)")
        void yIsAlwaysZero() {
            for (float yaw = -360f; yaw <= 360f; yaw += 37f) {
                assertEquals(0.0, FurnitureSeatGeometry.rightAxis(yaw).y, EPS);
            }
        }
    }

    @Nested
    @DisplayName("seatOffset — even spacing around centre")
    class SeatOffset {

        @Test
        @DisplayName("1 seat → always 0 (centered)")
        void singleSeat() {
            assertEquals(0.0, FurnitureSeatGeometry.seatOffset(0, 1), EPS);
        }

        @Test
        @DisplayName("2 seats → -0.5, 0.5")
        void twoSeats() {
            assertEquals(-0.5, FurnitureSeatGeometry.seatOffset(0, 2), EPS);
            assertEquals(0.5, FurnitureSeatGeometry.seatOffset(1, 2), EPS);
        }

        @Test
        @DisplayName("3 seats → -1, 0, 1")
        void threeSeats() {
            assertEquals(-1.0, FurnitureSeatGeometry.seatOffset(0, 3), EPS);
            assertEquals(0.0, FurnitureSeatGeometry.seatOffset(1, 3), EPS);
            assertEquals(1.0, FurnitureSeatGeometry.seatOffset(2, 3), EPS);
        }

        @Test
        @DisplayName("4 seats → -1.5, -0.5, 0.5, 1.5")
        void fourSeats() {
            assertEquals(-1.5, FurnitureSeatGeometry.seatOffset(0, 4), EPS);
            assertEquals(-0.5, FurnitureSeatGeometry.seatOffset(1, 4), EPS);
            assertEquals(0.5, FurnitureSeatGeometry.seatOffset(2, 4), EPS);
            assertEquals(1.5, FurnitureSeatGeometry.seatOffset(3, 4), EPS);
        }
    }
}
