import { world, system, Player } from "@minecraft/server";
import * as ballistaArrays from "../arrays/ballista_arrays.js"
import * as ballistaData from "../data/ballista_data.js"
import * as mathUtilities from "../utilities/math_utilities.js"

export function getBallistaDirectionFromRotation(yawDegrees,pitchDegrees) {
	const pitchRad = (-pitchDegrees)*(Math.PI/180);
	const yawRad = yawDegrees*(Math.PI/180);
	return {x:-Math.sin(yawRad)*Math.cos(pitchRad),y:Math.sin(pitchRad),z:Math.cos(yawRad)*Math.cos(pitchRad)};
};

export function ballistaLooseBoltProjectile(ballista,rule,dir,player) {
	let projectileEntity = ballista.dimension.spawnEntity(rule.ammunition,{x:ballista.location.x+dir.x,y:ballista.location.y+rule.ammunition_y_offset+dir.y,z:ballista.location.z+dir.z});
	let projectileType = projectileEntity.getComponent("minecraft:projectile");
	projectileType.owner = player;
	projectileType.shoot({x:dir.x*rule.ammunition_speed,y:dir.y*rule.ammunition_speed,z:dir.z*rule.ammunition_speed});
	return projectileEntity;
};

export function ballistaMainComponents(ballista) {
	const ballistaOnList = ballistaArrays.ballistaIdentifierTypes.includes(ballista.typeId);
	if (!ballistaOnList) return;
	const rule = ballistaData.ballistaDataTypes[ballista.typeId];
	if (!rule) return;
	const xRot = ballista.getProperty(rule.properties.x_rot);
	const yRot = ballista.getProperty(rule.properties.y_rot);
	const hasBolt = ballista.getProperty(rule.properties.has_bolt);
	const state = ballista.getProperty(rule.properties.state.identifier);
	const rideable = ballista.getComponent("rideable");
	if (!rideable) return;
	const controllingSeat = rideable.controllingSeat;
	const riders = rideable.getRiders();
	if (!riders) return;
	const controllingRider = riders[controllingSeat];
	if (controllingRider instanceof Player) {
		handleBallistaControl(rule,ballista,controllingRider,hasBolt,state,xRot,yRot);
	}
};
function handleBallistaControl(rule,ballista,player,hasBolt,state,xRot,yRot) {
	const movement = player.inputInfo.getMovementVector();
	if (!movement) return;
	const normalizedX = Math.abs(movement.x)>=rule.input_threshold?(movement.x>0?1:-1):0;
	const normalizedY = Math.abs(movement.y)>=rule.input_threshold?(movement.y>0?1:-1):0;
	const inputKey = `${normalizedX},${normalizedY}`;
	const inputType = rule.input_directions[inputKey]??"none";
	player.runCommand(`title @s actionbar BX: ${xRot} BY: ${Math.round(ballista.getRotation().y*10)/10}\n PX: ${Math.round(player.getRotation().x*10)/10} PY: ${Math.round(player.getRotation().y)}`);
	player.playAnimation(rule.player_rider_animation_override,{stopExpression:"!q.is_riding_any_entity_of_type('megaverse:ballista')||v.is_first_person"});
	let bodyYaw = ballista.getRotation().y;
	bodyYaw = mathUtilities.wrapDegrees(bodyYaw);
	ballista.setProperty(rule.properties.y_rot,Math.round(bodyYaw));
	if (inputType=="elevation"||inputType=="elevation_rotate_left"||inputType=="elevation_rotate_right") ballista.triggerEvent(rule.events.look_up);
	if (inputType=="depression"||inputType=="depression_rotate_left"||inputType=="depression_rotate_right") ballista.triggerEvent(rule.events.look_down);
	if (inputType=="rotate_right"||inputType=="elevation_rotate_right"||inputType=="depression_rotate_right") {
		ballista.triggerEvent(rule.events.look_right);
		ballista.setRotation({x:ballista.getRotation().x,y:ballista.getRotation().y+rule.rotate_body_y_rot_amount});
	}
	if (inputType=="rotate_left"||inputType=="elevation_rotate_left"||inputType=="depression_rotate_left") {
		ballista.triggerEvent(rule.events.look_left);
		ballista.setRotation({x:ballista.getRotation().x,y:ballista.getRotation().y-rule.rotate_body_y_rot_amount});
	}
	if (player.isJumping&&state==rule.properties.state.values[0]) ballista.triggerEvent(rule.events.spanning);
	if (player.isJumping&&state==rule.properties.state.values[3]&&hasBolt) {
		ballista.triggerEvent(rule.events.loose);
		const yaw = ballista.getRotation().y;
		const dir = getBallistaDirectionFromRotation(yaw,xRot);
		ballistaLooseBoltProjectile(ballista,rule,dir,player);
	}
};