import * as mc from '@minecraft/server';
import * as mcui from '@minecraft/server-ui';
import stand_defaultAttack from '../default/stand_defaultAttack.js';
import titleUIList from './_ui_/titleUIList.js';
import Vec3 from '../../../modules/Vec3.js';
import range from '../../../modules/arrayRange.js';
import Mathf from '../../../modules/Mathf.js';


export default class purpleHaze extends stand_defaultAttack {
    constructor(player) {
        super(player);
        this.standMaster = player;
        this.UI = titleUIList.ui;
        this.GUI = titleUIList.gui;
        
        
        this.projectile_count = this.global("stand_skill2");
        this.throw_value = this.global("stand_skill2_2");
        this.ticking();
        
    }
    
    
    ticking() {
        
        let player = this.standMaster;
        let handItem = this.getHandItem(player);
        
        let projectile_count = 6;
        
        this.skills_count = 2;
        
        this.LoadingGUI({
            name: "purpleHaze",
            value: this.UIslotData
        });
        
        
        this.slot_data[2].var = [
            false,
            1,
            1,
            NaN
        ].join("|")
        this.slot_data[3].var = [
            false,
            1,
            1,
            NaN
        ].join("|")
        
        if (!player?.hasTag("entity.in_timeStop")) {
            this.summon({
                anim_id: "purple_haze",
                sounds: [
                    "purpleHaze.name"
                ]
            });
            this.defaultAttack({
                damage: 5,
                attack_interval: 3,
                delay: 5,
                power: 0.25,
                max_fist_count: 2,
                mental: 1,
                loss: 18,
                sound1: "kingCrimson.punch"
            })
            this.quickFist({
                range: 4,
                damage: 5,
                duration: 2,
                cooldown_reply: 2,
                once_sounds: [
                    "purpleHaze.growl->999"
                ],
                fist_sounds: [
                    "purpleHaze.barrage->999"
                ],
                hit_sounds: [
                    "purpleHaze.punch->999"
                ],
                mental: {
                    value: 1,
                    interval: Math.floor(Mathf.random(40,60))
                }
            },{
                onHitEntity: (source,data,fist_data,entity) => {
                    let random = Math.floor(Mathf.random(1,3));
                    if (this.projectile_count.var > 0 && random === 2) {
                        this.projectile_count.var = Mathf.clamp(this.projectile_count.var - 20, 0, projectile_count * 20)
                        this.removeMentalValue(2)
                        entity?.addTag("infected.purpleVirus");
                        entity?.addTag("infected.purpleVirus_small");
                    }
                }
            });
            this.throwVirus({
                projectile_count: projectile_count,
                projectile_reply: 0.5,
                projectile_power: 1.5,
                charge_duration: 0.5,
                cooldown: 4,
                mental: Math.floor(Mathf.random(2,4))
            });
        }
    }
    
    static description(player,system) {
        let _this = system;
        let menu = _this.ui();
        menu.layout(player, `
            <ui id="_stand_description_"/>
                <title text="ui.stand_settings.skills_description"/>
                    <body text="ui.how_to_use.no_stand"/>
                        <button id="skill1" text="ui.stand_settings.3.how_to_use.stand_fist" icon="textures/gui/purpleHaze/icon1"/>
                        <button id="skill2" text="ui.stand_settings.3.how_to_use.purpleHaze_throwVirus" icon="textures/gui/purpleHaze/icon2"/>
                        <button id="close" text="ui.stand_settings.3"/>
                    </body>
                </title>
            </ui>
        `
        );
        menu.trigger("_stand_description_", e => {
            let canceled = e.canceled;
            _this.ui_using(player,0);
            
            let selection = e.getElementById;
            _this.menu_op(player);
        });
    }
    
    static eventData(_this) {
        let c = (entity) => {
            return entity !== undefined && entity?.typeId == "minecraft:player" && entity?.hasTag("standMaster.purpleHaze")
        }
        _this.listenForEvent("minecraft:itemStartUse", (e) => {
            let item = e.itemStack;
            let player = e.source;
            if (c(player) && item?.typeId == "stand:skill1" && player?.isSneaking) {
                player?.addTag("purpleHaze.throwCharge");
            }
        })
        _this.listenForEvent("minecraft:itemStopUse", (e) => {
            let item = e.itemStack;
            let player = e.source;
            if (c(player) && item?.typeId == "stand:skill1") {
                player?.removeTag("purpleHaze.throwCharge");
            }
        })
        _this.tick(() => {
            let entities = _this.getEntities({excludeTypes:["item"],excludeFamilies:["inanimate"],excludeTags:["gameMode.creative","kingCrimson.timeErase"],tags:["infected.purpleVirus"]}).filter(e => e.hasComponent("minecraft:health") && (e.hasComponent("minecraft:movement") || e.typeId === "minecraft:ender_dragon"));
            if (entities.length > 0) {
                entities.forEach(entity => {
                    let virus_duration = {
                        var: 0
                    }
                    try {
                        virus_duration = _this.scores(entity,"virus_duration");
                    } catch(e) {
                        virus_duration = {
                            var: 0
                        }
                    }
                    let entity_pos = "xyz".split("").map(xyz => {
                        return entity?.location[xyz];
                    })
                    
                    let health = entity?.getComponent("minecraft:health");
                    let damage = Mathf.clamp(Math.round((entity?.getTags().join("|").includes("standMaster.") ? 99 : health.defaultValue) / health.currentValue), entity?.typeId == "minecraft:player" ? 2 : 3, 5)
                    entity?.applyDamage(damage)
                    health.setCurrentValue(health.currentValue - 1)
                    
                    let test = new mc.MolangVariableMap();
                    entity.dimension.spawnParticle("purplehaze:virus_attach",new Vec3(...entity_pos).Position(),test)
                    
                    let entities2 = _this.getEntities({excludeTypes:["item","xp_orb","armor_stand","minecart","boat"],excludeFamilies:["inanimate"],excludeTags:["gameMode.creative"]},entity.dimension).filter(entity2 => new Vec3(...entity_pos).Distance(entity2.location.x,entity2.location.y,entity2.location.z) <= 2.3);
                    if (entities2.length > 0) {
                        entities2.forEach(entity2 => {
                            entity2?.addTag("infected.purpleVirus")
                        })
                    }
                    if (entity?.typeId === "minecraft:player") {
                        // console.error(virus_duration.var)
                    }
                    if (virus_duration.var >= (entity?.hasTag("infected.purpleVirus_small") ? 2 : 6)) {
                        virus_duration.var = 0;
                        entity?.removeTag("infected.purpleVirus_small")
                        entity?.removeTag("infected.purpleVirus")
                    }
                })
            }
        },5)
        _this.tick(() => {
            let entities = _this.getEntities({excludeTypes:["item"],excludeTags:["gameMode.creative"],tags:["infected.purpleVirus"]}).filter(e => e.hasComponent("minecraft:health") && (e.hasComponent("minecraft:movement") || e.typeId === "minecraft:ender_dragon"));
            if (entities.length > 0) {
                entities.forEach(entity => {
                    let virus_duration = {
                        var: 0
                    }
                    try {
                        virus_duration = _this.scores(entity,"virus_duration");
                    } catch(e) {
                        virus_duration = {
                            var: 0
                        }
                    }
                    virus_duration.var += 1
                })
            }
        },20)
    }
    
    throwVirus(data) {
        let player = this.standMaster;
        let virus_data = (...args) => {
            if (player?.hasTag("ph.throw_cooldown") && !player?.hasTag("purpleHaze.throwCharge")) {
                return args[0];
            }
            if (!player?.hasTag("ph.throw_cooldown") && player?.hasTag("purpleHaze.throwCharge")) {
                return args[1];
            }
            if (!player?.hasTag("ph.throw_cooldown") && !player?.hasTag("purpleHaze.throwCharge")) {
                return 1;
            }
        }
        this.slot_data[1].var = [
            this.use_skill1 && player?.isSneaking,
            virus_data((this.throw_value.var / 20).toFixed(1), (this.throw_value.var / 20).toFixed(1)),
            virus_data(data.cooldown, data.charge_duration),
            Math.floor((this.projectile_count.var / 20).toFixed(1))
        ].join("|")
        if (this.projectile_count.var == 0) {
            player?.addTag("purpleHaze.recoveryProjectile")
        }
        if (player?.hasTag("purpleHaze.recoveryProjectile") && !player?.hasTag("stand.summon")) {
            this.projectile_count.var = Mathf.clamp(this.projectile_count.var + data.projectile_reply, 0, data.projectile_count * 20);
            if (this.projectile_count.var >= data.projectile_count * 20) {
                player?.removeTag("purpleHaze.recoveryProjectile")
            }
        }
        if (this.projectile_count.var > 0) {
            if (player?.hasTag("purpleHaze.throwCharge") && !player?.hasTag("ph.throw_cooldown")/* && this.projectile_count.var > 0 */&& this.mental_value.var > 0) {
                let charge_duration = data.charge_duration * 20
                this.throw_value.var = Mathf.clamp(this.throw_value.var + 1, 0, charge_duration);
                player?.removeTag("purpleHaze.stopUse")
                if (this.throw_value.var == 1) {
                    this.broadcastAnim(`purple_haze->throw_charge`);
                    this.runCommand(`playsound purpleHaze.charge @a ~ ~ ~`, player);
                }
                if (this.throw_value.var >= charge_duration) {
                    player?.addTag("purpleHaze.throwVirus")
                }
            }
        } else {
            player?.removeTag("purpleHaze.throwCharge")
        }
        if (!player?.hasTag("purpleHaze.throwCharge") && !player?.hasTag("purpleHaze.throwVirus") && !player?.hasTag("purpleHaze.stopUse")) {
            this.removeAnim(`purple_haze->throw_charge`);
            player?.addTag("purpleHaze.stopUse")
        }
        if (!player?.hasTag("purpleHaze.throwCharge") && !player?.hasTag("ph.throw_cooldown")) {
            this.throw_value.var = 0;
        }
        if (!player?.hasTag("purpleHaze.throwCharge") && player?.hasTag("purpleHaze.throwVirus")) {
            this.projectile_count.var = Mathf.clamp(this.projectile_count.var - 20, 0, data.projectile_count * 20)
            this.broadcastAnim(`purple_haze->throw`);
            this.runCommand(`playsound purpleHaze.throw @a ~ ~ ~`, player);
            this.shoot(player,"purplehaze:virus_maru",data.projectile_power/10,[0,0.8,0])
            this.removeMentalValue(data.mental)
            player?.addTag("ph.throw_cooldown")
            player?.removeTag("purpleHaze.throwVirus")
        }
        if (player?.hasTag("ph.throw_cooldown")) {
            this.throw_value.var += 1;
            if (this.throw_value.var >= data.cooldown * 20) {
                this.throw_value.var = 0;
                player?.removeTag("ph.throw_cooldown")
            }
        }
    }
    
    
}

