import * as utils from "../utils";
import { EquipmentSlot } from "@minecraft/server";
import { damageItem } from "../inventory_utils";
import * as vector3 from "../vector3";

const SPEED = 1;
const DISTANCE_TO_START_FROM = 1

const EXPLOSION_RADIUS = 3;
const EXPLOSION_DAMAGE = 5;
const EXPLOSION_RANDOMNESS = 1;
const EXPLOSION_DROP_CHANCE = 0.3;

export async function onItemUse(event) {
  const player = event.source;
  const playerHeadLocation = event.source.getHeadLocation();
  const direction = event.source.getViewDirection();
  let cd = player.getItemCooldown("tcs_cwp:dragon_staff");

  if (cd > 0) return;

  utils.playSound(player, `@a[x=${player.location.x}, y=${player.location.y}, z=${player.location.z}, r=2]`, 'tcs_cwp:dragon_staff_use');
  utils.playSound(player, `@a[x=${player.location.x}, y=${player.location.y}, z=${player.location.z}, r=15]`, 'tcs_cwp:dragon_staff_dragon_scream');

  const targetLocation = vector3.copy(playerHeadLocation).add(vector3.copy(direction).multiply(DISTANCE_TO_START_FROM));
  const dragonStaffHead = player.dimension.spawnEntity(`tcs_cwp:dragon_staff_head`, targetLocation);
  const pitchAndYaw = utils.directionToRotation(direction);
  const pitch = pitchAndYaw.x;
  const yaw = pitchAndYaw.y;
  dragonStaffHead.setProperty(`tcs_cwp:dragon_staff_head_pitch`, pitch);
  dragonStaffHead.setProperty(`tcs_cwp:dragon_staff_head_yaw`, yaw);

  dragonStaffHead.setDynamicProperty(`tcs_cwp_direction`, direction);
  dragonStaffHead.setDynamicProperty(`tcs_cwp_owner_player`, player.id);

    player.startItemCooldown("tcs_cwp_amethyst_staff_animation_shoot", 5.3);
    player.runCommandAsync(`playanimation @s animation.tcs_cwp.amethyst_staff.shoot.tp`);

  player.startItemCooldown("tcs_cwp:dragon_staff", 100);

  damageItem(player, EquipmentSlot.Mainhand, 1);
}

export async function onScriptEventReceive(event) {
  const entity = event.sourceEntity;

  let direction = entity?.getDynamicProperty(`tcs_cwp_direction`);
  if(!direction) return
  direction = vector3.copy(direction);
  entity.clearVelocity();

  entity.applyImpulse(direction.multiply(SPEED));

  // UNCOMMENT IF WANT NOT TO DESTROY BLOCKS AROUND PLAYER
  // const nearby = await utils.getPlayersInRange(entity.dimension, entity.location, 0, 3);
  // const ownerNear = nearby.some(p => p.id === entity?.getDynamicProperty('tcs_cwp_owner_player'));
  // if (ownerNear) return;

  try {
    createExplosion(entity, entity.location);
    utils.runEntityCommand(entity, `particle tcs_cwp:dragon_staff_head_particle`);
  } catch(e) {} 
}

function createExplosion(executeingEntity, location) {
    // Spawn explosion particle effect

    // Damage entities in the explosion radius
    const entities = executeingEntity.dimension.getEntities({
        location: location,
        excludeFamilies: ["utility", "projectile"],
        excludeTypes: ["minecraft:item"],
        maxDistance: EXPLOSION_RADIUS
    });

    for (const entity of entities) {
        if (entity.id === executeingEntity?.getDynamicProperty('tcs_cwp_owner_player')) continue;
        if (!entity.isValid()) continue;
    
        try { entity.applyDamage(EXPLOSION_DAMAGE); } catch (e) { }
        
        // Add knockback effect
        const knockbackDirection = vector3.unit(vector3.copy(entity.location).subtract(location));
        const distance = vector3.length(vector3.copy(entity.location).subtract(location));
        const damageMultiplier = Math.max(0, 1 - (distance / EXPLOSION_RADIUS));
        const knockbackForce = (1 - damageMultiplier) * 2 + 1;
        try { entity.applyKnockback(knockbackDirection.x, knockbackDirection.z, knockbackForce, knockbackDirection.y * 0.5); } catch (e) { }
    }

    // Destroy blocks in a spherical pattern
    const centerX = Math.floor(location.x);
    const centerY = Math.floor(location.y);
    const centerZ = Math.floor(location.z);

    for (let x = centerX - EXPLOSION_RADIUS; x <= centerX + EXPLOSION_RADIUS; x++) {
        for (let y = centerY - EXPLOSION_RADIUS; y <= centerY + EXPLOSION_RADIUS; y++) {
            for (let z = centerZ - EXPLOSION_RADIUS; z <= centerZ + EXPLOSION_RADIUS; z++) {
                const blockLocation = { x, y, z };
                const distance = Math.sqrt(
                    Math.pow(x - centerX, 2) + 
                    Math.pow(y - centerY, 2) + 
                    Math.pow(z - centerZ, 2)
                );

                // Only destroy blocks within the radius with some randomness
                if (distance <= EXPLOSION_RADIUS && Math.random() < EXPLOSION_RANDOMNESS) {
                    try {
                        // Check if block is destructible (not bedrock, etc.)
                        const block = executeingEntity.dimension.getBlock(blockLocation);
                        if (!block || block.typeId.endsWith('bedrock') || block.typeId.endsWith('barier') || block.typeId.endsWith('obsidian')) return
                        const shouldDropItem = Math.random() < EXPLOSION_DROP_CHANCE;
                        destroyBlock(executeingEntity ,blockLocation, shouldDropItem);
                    } catch (error) {
                        // Ignore errors for blocks that can't be accessed or destroyed
                    }
                }
            }
        }
    }
}

function destroyBlock(entity, location, dropItem = false) {
    entity.dimension.runCommandAsync(`/setblock ${location.x} ${location.y} ${location.z} air ${dropItem ? "destroy" : "replace"}`);
}

export async function onEntityHit(event) {
	const attacker = event.damagingEntity;
	if (!attacker || attacker.typeId !== "minecraft:player") return;

	const heldItem = attacker
		.getComponent("minecraft:equippable")
		?.getEquipment(EquipmentSlot.Mainhand);
	if (!heldItem || heldItem.typeId !== "tcs_cwp:dragon_staff") return;

	// Punch animations
	attacker.startItemCooldown("tcs_cwp_vampire_fang_punch", 8);
	attacker.playAnimation("animation.tcs_cwp.staff.tp_hit");
}