import { world } from "@minecraft/server";
import { VEHICLES } from "./VehiclesRoot.js";

export const dimensions = {};
export const dimensionHeightRanges = {};
export class Vec3 {
    static from(vec) {
        if (typeof vec === "object") {
            return new Vec3(vec.x, vec.y, vec.z);
        }
        return new Vec3(vec, arguments[1], arguments[2]);
    }

    constructor(x, y, z) {
        this.x = x || 0;
        this.y = y || 0;
        this.z = z || 0;
    }

    add(vec) {
        if (vec instanceof Vec3) {
            return new Vec3(this.x + vec.x, this.y + vec.y, this.z + vec.z);
        }
        return new Vec3(this.x + vec, this.y + vec, this.z + vec);
    }

    multiply(scalar) {
        return new Vec3(this.x * scalar, this.y * scalar, this.z * scalar);
    }

    subtract(vec) {
        return new Vec3(this.x - vec.x, this.y - vec.y, this.z - vec.z);
    }

    normalize() {
        const length = Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
        if (length === 0) return new Vec3(0, 0, 0);
        return new Vec3(this.x / length, this.y / length, this.z / length);
    }

    length() {
        return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
    }

    isZero() {
        return this.x === 0 && this.y === 0 && this.z === 0;
    }

    setY(y) {
        return new Vec3(this.x, y, this.z);
    }

    rotate(axis, angle) {
        const rad = (angle * Math.PI) / 180;
        const cos = Math.cos(rad);
        const sin = Math.sin(rad);
        const dot = this.x * axis.x + this.y * axis.y + this.z * axis.z;

        return new Vec3(
            (cos + (1 - cos) * axis.x * axis.x) * this.x +
                ((1 - cos) * axis.x * axis.y - sin * axis.z) * this.y +
                ((1 - cos) * axis.x * axis.z + sin * axis.y) * this.z,

            ((1 - cos) * axis.x * axis.y + sin * axis.z) * this.x +
                (cos + (1 - cos) * axis.y * axis.y) * this.y +
                ((1 - cos) * axis.y * axis.z - sin * axis.x) * this.z,

            ((1 - cos) * axis.x * axis.z - sin * axis.y) * this.x +
                ((1 - cos) * axis.y * axis.z + sin * axis.x) * this.y +
                (cos + (1 - cos) * axis.z * axis.z) * this.z
        );
    }

    static get Up() {
        return new Vec3(0, 1, 0);
    }
}

export function calculateHitLocation(projectileLocation, direction, origin, range) {
    return Vec3.from(projectileLocation).add(Vec3.from(direction).multiply(range));
}
export function calculateShootLocationAndDirection(player) {
    const direction = Vec3.from(player.getViewDirection()).normalize();
    const headLoc = Vec3.from(player.getHeadLocation());
    const playerLoc = Vec3.from(player.location);

    
    const tankTag = Array.from(player.getTags()).find(tag => tag.startsWith('tank_'));
    if (tankTag) {
        const tankId = tankTag.split('_')[1];
        const tank = player.dimension.getEntities().find(e => e.id === tankId);
        if (tank) {
            const vehicleConfig = Object.values(VEHICLES).find(v => v.identifier === tank.typeId);
            if (vehicleConfig) {
                headLoc.x = playerLoc.x;
                headLoc.y = playerLoc.y + vehicleConfig.headLocY;
                headLoc.z = playerLoc.z;
                return [headLoc, direction];
            }
        }
    }

    
    headLoc.x = playerLoc.x;
    headLoc.y = playerLoc.y + 2.27;
    headLoc.z = playerLoc.z;
    
    return [headLoc, direction];
}
export function getDimension(name) {
    if (dimensions[name]) return dimensions[name];
    return (dimensions[name] = world.getDimension(name));
}

export function getDimensionHeightRange(name) {
    if (dimensionHeightRanges[name]) return dimensionHeightRanges[name];
    return (dimensionHeightRanges[name] = getDimension(name).heightRange);
}

export function isInBoundaries(entity) {
    const heightRange = getDimensionHeightRange(entity.dimension.id);
    const inBound = entity.location.y >= heightRange.min && entity.location.y <= heightRange.max;
    if (!inBound) {
    }
    return inBound;
}
