import { system, world, EquipmentSlot, GameMode } from "@minecraft/server";
import { settingForm } from "./settings";
import { playAnimationWithClock, AnimationHelper} from "./animation_controller";
import { isHoldingWeapon } from "./combat_mechanic";
import { ENABLE_HIT_CHECK, Spell } from "./combat_config";

const ModeSwitch = {
    onUse({ source }) {
        if (source.isSneaking){
            settingForm(source);
        } else {
            if (!source.getDynamicProperty('combat_state')) {
                source.setDynamicProperty('combat_state', true);
                source.runCommand("say Combat Mode On");
                const cameraPreset = source.getDynamicProperty("camera_preset");
                if (cameraPreset === "dynamic_df") {
                    if (!source.hasTag("ae_fpm.is_first_person")) {
                        source.runCommand("/ae_fpm:toggle_model")
                    }
                    source.addTag("ae_fpm.disable_animation");
                }
                if (ENABLE_HIT_CHECK) {
                    startCombat(source)
                }
            } else {
                source.setDynamicProperty('combat_state', false);
                source.runCommand("say Combat Mode Off")
                source.runCommand("camera @s clear")
                stopCombat(source);
                // if (source.hasTag("ae_fpm.is_first_person")) {
                //     source.runCommand("/ae_fpm:toggle_model")
                // }
                source.removeTag("ae_fpm.disable_animation");
            }
        }
    }
}

system.beforeEvents.startup.subscribe(({ itemComponentRegistry }) => {
    itemComponentRegistry.registerCustomComponent("imc:mode_switch", ModeSwitch);
});

export function setOrbitCamera(player) {
    // player.runCommand(`/camera @s set minecraft:follow_orbit entity_offset ${camera_horizontal} ${camera_vertical} ${camera_forward}`)
    let cameraPreset = player.getDynamicProperty("camera_preset");
    if (cameraPreset === "3rd") {
        player.runCommand(`/camera @s set minecraft:third_person`)
    } else if (cameraPreset === "1st") {
        player.runCommand(`/camera @s set minecraft:first_person`)
    }
}

export function startCombat(source) {
    // source.runCommand("camera @s set minecraft:third_person")
    source.runCommand("/ride @e[type=parrot] stop_riding")
    const spawnX = source.location.x;
    const spawnY = source.location.y;
    const spawnZ = source.location.z;
    const spawnedEntity = source.dimension.spawnEntity("imc:entity_placeholder", {
        x: spawnX,
        y: spawnY,
        z: spawnZ
    });
    spawnedEntity.addTag("id:" + source.id);
    const spawnedEntityHItCheck = source.dimension.spawnEntity("imc:entity_hit_check", {
        x: spawnX,
        y: spawnY,
        z: spawnZ
    });
    spawnedEntityHItCheck.addTag("id:" + source.id);
    source.addTag("id:" + source.id);
}

export function stopCombat(source) {
  source.runCommand(`/camera @s clear`);
  system.runTimeout(() => {
    source.runCommand(`/camera @s clear`);
  }, 10);
  let tag = "id:" + source.id;
  source.runCommand(`/event entity @e[tag=${tag}] des`)
}


export const usingSpell = new Map();

world.afterEvents.itemUse.subscribe((eventData) => {
    const { source: player, itemStack } = eventData;
    if (!itemStack) return;
    const typeId = itemStack.typeId;
    if (!player.getDynamicProperty("combat_state")) return;
    if ((usingSpell.get(player.id))) {
        player.runCommand(`title @s actionbar §cCan't Comsume Now...`);
        return;
    }
    if (isHoldingWeapon(player)) return;
    // Find a spell key that matches part of the typeId
    const key = Object.keys(Spell).find(word => typeId.includes(word));

    if (key) {
        const useTime = Spell[key].useTime;
        const animation = Spell[key].animation;
        const sound = Spell[key].sound;
        useSpell(player, useTime, itemStack, animation, sound, key);
    } else {
        // if (isRangedWeapon(player)) return;
        // const useTime = 40;
        // useSpell(player, useTime, itemStack, "animation.combat.use_other", null);
        return;
    }
});

export function useSpell(player, useTime, itemStack, animation, sound, spellKey){
    const now = system.currentTick;
    const spell = Spell[spellKey];
    // still in cooldown?
    if ((usingSpell.get(player.id) ?? 0) > now) {
        return;
    }
    const expiry = now + useTime;

    // 🟢 Store both startTick and expiry
    usingSpell.set(player.id, { startTick: now, expiry });

    playAnimationWithClock(player, AnimationHelper(animation, player), useTime);
    // Apply effects
    if (spell){
        player.addEffect("slowness", 60, { 
            amplifier: 3, 
            showParticles: true
        });
        clearItem(player);
    }
    // Auto cleanup
    system.runTimeout(() => {
    const state = usingSpell.get(player.id);
    if (state && state.expiry === expiry) {
        usingSpell.delete(player.id);
    }
    }, useTime);

    system.runTimeout(() => {
    const state = usingSpell.get(player.id);
    if (state && state.expiry === expiry) {
        if (!spell) return;
        for (const eff of spell.effects) {
            player.addEffect(eff.id, eff.duration, { 
                amplifier: eff.amplifier, 
                showParticles: eff.showParticles 
            });
        }
        player.runCommand(`/particle ${spell.particle} ~~~`);
        player.runCommand(`/playsound ${sound} @a ~~~`);
    }
    }, spell.effectTime);
}


// function useSpell(player, useTime, itemStack, animation, spellKey) {
//     const spell = Spell[spellKey];

//     // Play animation
//     playAnimationWithClock(player, spell.animation, useTime);

//     // Play sound
//     player.playSound(spell.sound);

//     // Apply effects
//     for (const eff of spell.effects) {
//         player.addEffect(eff.id, eff.duration, { 
//             amplifier: eff.amplifier, 
//             showParticles: eff.showParticles 
//         });
//     }
// }


function clearItem(source) {
    if (!source) return;

    const equippable = source.getComponent("minecraft:equippable");
    if (!equippable) return;

    const mainhand = equippable.getEquipmentSlot(EquipmentSlot.Mainhand);
    if (!mainhand.hasItem()) return;

    if (source.getGameMode() !== GameMode.Creative) {
        if (mainhand.amount > 1) {
            mainhand.amount--; // Remove one item from the stack
        } else {
            mainhand.setItem(undefined); // Remove the item stack
        }
    }
}