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 goldExperience extends stand_defaultAttack {
    constructor(player) {
        super(player);
        this.standMaster = player;
        this.UI = titleUIList.ui;
        this.GUI = titleUIList.gui;
        
        
        this.createdEntity = this.global("goldExperience.entity");
        this.blockFace = this.global("clicked_blockFace");
        
        this.create_life_cd = this.global("stand_skill2");
        this.cure_cd = this.global("stand_skill3");
        this.cure_cd2 = this.global("stand_skill3_2");
        this.projectile_iGL = this.global("stand_skill4");
        this.ticking();
        
    }
    
    
    ticking() {
        
        let player = this.standMaster;
        let handItem = this.getHandItem(player);
        
        
        this.skills_count = 2;
        
        this.LoadingGUI({
            name: "goldExperience",
            value: this.UIslotData
        });
        
        if (!player?.hasTag("entity.in_timeStop")) {
            this.summon({
                anim_id: "gold_experience",
                sounds: [
                    "goldExperience.name"
                ]
            });
            this.defaultAttack({
                damage: 3,
                attack_interval: 3,
                delay: 5,
                power: 0.25,
                max_fist_count: 2,
                mental: 1,
                loss: 15,
                sound1: "kingCrimson.punch"
            })
            this.quickFist({
                range: 4,
                damage: 3,
                duration: 3,
                cooldown_reply: 3,
                fist_sounds: [
                    "goldExperience.quick_fist1->2",
                    "goldExperience.muda->58"
                ],
                hit_sounds: [
                    "goldExperience.muda_loud->38"
                ],
                mental: {
                    value: 1,
                    interval: Math.floor(Mathf.random(40,60))
                }
            });
            
            this.createLife({
                range: 4,
                duration: 4,
                count: this.createdEntity.var == "goldexperience:spider" ? Math.floor(Mathf.random(1,3)) : Math.floor(Mathf.random(3,6)),
                mental: Math.floor(Mathf.random(3,5))
            });
            
            this.cure({
                duration: 4,
                value: Math.floor(Mathf.random(10,20)),
                mental: 3
            });
        }
        // this.tree();
    }
    
    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/goldExperience/icon1"/>
                        <button id="skill2" text="ui.stand_settings.3.how_to_use.goldExperience_createLife" icon="textures/gui/goldExperience/icon2"/>
                        <button id="skill3" text="ui.stand_settings.3.how_to_use.goldExperience_cure" icon="textures/gui/goldExperience/icon3"/>
                        <button id="skill4" text="ui.stand_settings.3.how_to_use.goldExperience_createLife2" icon="textures/gui/goldExperience/icon4"/>
                        <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.goldExperience")
        }
        _this.listenForEvent("minecraft:itemStartUse", (eventData) => {
            let entity = eventData.source;
            let item = eventData.itemStack;
            if (c(entity)) {
                let player = entity;
                let inventory = player?.getComponent("inventory").container;
                if (item.typeId == "jojo:stand_settings" && player?.isSneaking) {
                    
                    let menu = _this.ui();
                    menu.layout(player, `
                        <ui id="_entity_choice_"/>
                            <title text="ui.stand_settings.option_slot"/>
                                <body text="ui.stand_settings.gold_experience"/>
                                    <button id="silverfish" text="ui.stand_settings.3.stand.slot.1" icon="textures/gui/goldExperience/silverfish"/>
                                    <button id="bee" text="ui.stand_settings.3.stand.slot.2" icon="textures/gui/goldExperience/bee"/>
                                    <button id="bat" text="ui.stand_settings.3.stand.slot.3" icon="textures/gui/goldExperience/bat"/>
                                    <button id="spider" text="ui.stand_settings.3.stand.slot.4" icon="textures/gui/goldExperience/spider"/>
                                    <button id="tree" text="ui.stand_settings.3.stand.slot.5" icon="textures/gui/goldExperience/tree"/>
                                    <button id="null1" text="ui.stand_settings.3.stand.slot.6" icon="null"/>
                                    <button id="null2" text="ui.stand_settings.3.stand.slot.7" icon="null"/>
                                    <button id="null3" text="ui.stand_settings.3.stand.slot.8" icon="null"/>
                                    <button id="close" text="ui.stand_settings.3" icon="null"/>
                                </body>
                            </title>
                        </ui>
                    `
                    );
                    menu.trigger("_entity_choice_", e => {
                        player?.removeTag("ui_using");
                        let selection = e.getElementById;
                        let createdEntity = "goldexperience:" + selection;
                        let text = {
                            rawtext: [
                                {
                                    translate: `chat.goldExperience.entity.is_chose`
                                },
                                {
                                    translate: `entity.${createdEntity}.name`
                                }
                            ]
                        };
                        if (selection !== "null1" && selection !== "null2" && selection !== "null3" && selection !== "close"){
                            _this.GlobalVar(player,"goldExperience.entity").var = createdEntity;
                            player?.sendMessage(text);
                        }
                        
                    });
                }
            }
        });
        _this.listenForEvent("minecraft:itemUseOn", (e) => {
            let item = e.itemStack;
            let player = e.source;
            // _this.runCommand(`say ${blockFace}`, player)
            if (c(player) && item?.typeId == "stand:skill1" && player?.isSneaking) {
                player?.addTag("goldExperience.createLife");
            }
        })
        _this.listenForEvent("minecraft:itemStartUse", (e) => {
            let item = e.itemStack;
            let player = e.source;
            if (c(player) && item.typeId == "stand:skill2") {
                if (player?.isSneaking) {
                    let check = player?.hasTag("goldExperience.projectile_giveLife0");
                    
                    if (!check) {
                        player?.addTag("goldExperience.projectile_giveLife0");
                    }
                    if (check) {
                        player?.addTag("goldExperience.projectile_giveLife1");
                    }
                    
                    // player?.addTag("goldExperience.projectile_giveLife" + (1 - check));
                    // console.error("goldExperience.projectile_giveLife" + (1 - check));
                    // console.error(+!check)
                } else {
                    player?.addTag("goldExperience.cure");
                }
            }
        })
        _this.listenForEvent("minecraft:itemStopUse", (e) => {
            let item = e.itemStack;
            let player = e.source;
            if (c(player) && item?.typeId == "stand:skill2") {
                player?.removeTag("goldExperience.cure");
            }
        })
        _this.listenForEvent("minecraft:projectileHitBlock", (e) => {
            let { dimension, hitVector, location, projectile, source } = e;
            if (c(source) && source?.hasTag("goldExperience.projectile_giveLife0") && (projectile !== undefined && projectile !== null)) {
                projectile?.addTag("projectile.is_givenLife");
            }
        })
        _this.tick(() => this.tree(_this),8)
        /*
        _this.listenForEvent("minecraft:entityHurt", (e) => {
            let { cause, damage, damagingEntity, hurtEntity, projectile } = e;
            if (c(damagingEntity) && hurtEntity !== damagingEntity) {
                _this.runCommand(`damage @e[family=stand_attack,tag=owner_${damagingEntity.name}] 0 suicide entity @s[tag=!owner_${damagingEntity.name}]`, hurtEntity);
            }
            if (c(hurtEntity) && damagingEntity !== hurtEntity) {
                _this.runCommand(`damage @e[family=stand_attack,tag=owner_${hurtEntity.name}] 0 suicide entity @s[tag=!owner_${hurtEntity.name}]`, damagingEntity);
            }
        })
        */
    }
    
    static tree(_this) {
        let Facing = (x,y,x2,y2,rot) => {
            return 57.2958 * Math.atan2(y - y2, x - x2) + rot;
        };
        let trees = _this.getEntities({type:"goldexperience:tree"});
        if (trees.length > 0) {
            trees.forEach(tree => {
                let tree_pos = "xyz".split("").map(xyz => {
                    return tree.location[xyz];
                })
                let hitEntities = _this.getEntities({excludeTypes:["goldexperience:tree"]},tree.dimension).filter(entity => Math.round(new Vec3(...tree_pos).Distance(entity.location.x,entity.location.y,entity.location.z)) <= 3);
                if (hitEntities.length > 0) {
                    hitEntities.forEach(entity => {
                        
                        let v = 1.5;
                        
                        
                        if (entity.typeId === "minecraft:player") {
                            if (tree.getTags().filter(tag => tag.startsWith("ownerName_")).join("").replaceAll("ownerName_","") !== entity.name) {
                                let d = Object.fromEntries("xyz".split("").map(xyz => {
                                    return [ xyz, entity.getVelocity()[xyz] != 0 ? Mathf.clamp(entity.getVelocity()[xyz],-1,1) : _this.getLc(entity)[xyz] ]
                                }));
                                entity.applyDamage(3);
                                entity.applyKnockback(-d.x, -d.z, v * _this.getLc2(-90,0).y - Math.abs(Math.round(entity.getViewDirection().y)), -entity.getViewDirection().y * v);
                            }
                        } else {
                            let d2 = _this.getLc2(0,Facing(tree.location.x,tree.location.z,entity.location.x,entity.location.z,0));
                            entity.applyDamage(5);
                            entity.applyImpulse(new Vec3(-d2.x * v * 2, v * 0.23, -d2.z * v * 2).Vector());
                        }
                        
                    })
                }
            })
        }
    }
    
    createLife(data) {
        let player = this.standMaster;
        
        this.slot_data[1].var = [
            (this.use_skill1 || this.use_skill2) && player?.isSneaking,
            (this.create_life_cd.var / 20).toFixed(1),
            data.duration,
            this.projectile_iGL.var
        ].join("|")
        this.slot_data[3].var = [
            false,
            1,
            1,
            NaN
        ].join("|")
        
        if (this.mental_value.var > 0 && this.create_life_cd.var >= 0 && this.create_life_cd.var < data.duration * 20) {
            this.create_life_cd.var += 1;
        }
        if (player?.hasTag("goldExperience.projectile_giveLife0") && this.mental_value.var > 0) {
            this.projectile_iGL.var = 1;
        }
        if (!player?.hasTag("goldExperience.projectile_giveLife0") || this.mental_value.var <= 0) {
            this.projectile_iGL.var = 0;
        }
        if (player?.hasTag("goldExperience.projectile_giveLife1") && this.create_life_cd.var >= data.duration * 20 && this.mental_value.var > 0) {
            let projectiles = this.getEntities({tags:["projectile.is_givenLife"]});
            if (projectiles.length > 0) {
                this.removeMentalValue(data.mental);
                projectiles.forEach(entity => {
                    this.create_life_cd.var = 0;
                    
                    let direction = {
                        up: 0,
                        down: 1,
                        north: 2,
                        south: 3,
                        east: 4,
                        west: 5
                    };
                    let blockPos = entity?.location;
                    // let createdEntity = player?.dimension.spawnEntity(this.createdEntity.var, new Vec3(blockPos.x, blockPos.y, blockPos.z).Position());
                    // createdEntity.addTag("owner_" + player?.name);
                    // if (createdEntity.id === "goldexperience.silverfish") {
                        // createdEntity.getComponent("minecraft:mark_variant").value = index;
                    // }
                    // if (createdEntity.id === "goldexperience.tree") {
                        // createdEntity.getComponent("minecraft:mark_variant").value = direction[this.blockFace.var];
                    // }
                    
                    if (this.createdEntity.var === "goldexperience:tree") {
                        let createdEntity = player?.dimension.spawnEntity(this.createdEntity.var, new Vec3(blockPos.x, blockPos.y, blockPos.z).PositionFloor());
                        createdEntity.addTag("ownerName_" + player?.name);
                        // console.error("ownerName_" + player?.name);
                        let test = new mc.MolangVariableMap();
                        player?.dimension.spawnParticle("effect:leaf",new Vec3(blockPos.x, blockPos.y, blockPos.z).PositionFloor(),test)
                    } else {
                        let createdEntity = player?.dimension.spawnEntity(`goldexperience:create_life`, new Vec3(blockPos.x, blockPos.y, blockPos.z).Position());
                        createdEntity.addTag(this.createdEntity.var);
                        this.runCommand(`damage @s 0 entity_attack entity @a[name="${player?.name}"]`, createdEntity);
                    }
                    
                    entity.removeTag("projectile.is_givenLife");
                    entity.kill();
                })
            }
            player?.removeTag("goldExperience.projectile_giveLife0");
            player?.removeTag("goldExperience.projectile_giveLife1");
        }
        if (player?.hasTag("goldExperience.createLife") && this.create_life_cd.var >= data.duration * 20 && this.mental_value.var > 0) {
            let block = this.getBlockFromViewVector(player, data.range + 3, {liquid: false, passable: false});
            let items = this.getEntitiesFromViewVector(player, data.range + 3).filter(e => e?.entity?.typeId === "minecraft:item")
            
            let blockType = {
                grass: 0,
                dirt: 1,
                stone: 2,
                wood: 3,
                sand: 4
            }
            
            let a = (target) => {
                this.runCommands([
                    `playsound goldExperience.create_life @a ~ ~ ~`
                ], player);

                this.removeMentalValue(data.mental);
                this.create_life_cd.var = 0;
                this.broadcastAnim(`gold_experience->fist`);
                this.set_stand_range2(target);
            }
            
            if (block !== null && block !== undefined) {
                let playerPos = player?.location;
                let blockPos = "xyz".split("").map(xyz => {
                    return block[xyz]
                })
                let blockPos2 = "xyz".split("").map(xyz => {
                    return block[xyz] + (xyz === "y")
                })
                if (this.createdEntity.var === "goldexperience:tree") {
                    a(block);
                    let direction = {
                        up: 0,
                        down: 1,
                        north: 2,
                        south: 3,
                        east: 4,
                        west: 5
                    };
                    let createdEntity = player?.dimension.spawnEntity(this.createdEntity.var, new Vec3(...blockPos2).PositionFloor());
                    createdEntity.addTag("ownerName_" + player?.name);
                    let test = new mc.MolangVariableMap();
                    player?.dimension.spawnParticle("effect:leaf",new Vec3(...blockPos2).PositionFloor(),test)
                    /*
                    let mark_variant = createdEntity.getComponent("minecraft:mark_variant");
                    mark_variant.value = direction[this.blockFace.var];*/
                } else {
                    Object.keys(blockType).forEach((type,index) => {
                        if (block?.typeId.includes(type)) {
                            a(block);
                            this.runCommand(`setblock ${blockPos.join(" ")} air [] replace`, player);
                            for (let count of range(0,data.count)) {
                                let createdEntity = player?.dimension.spawnEntity(`goldexperience:create_life`, new Vec3(...blockPos).Position());
                                createdEntity?.addTag(this.createdEntity.var);
                                this.runCommand(`damage @s 0 entity_attack entity @a[name="${player?.name}"]`, createdEntity);
                            }
                        }
                    })
                }
            }
            if (items !== undefined) {
                let playerPos = player?.location;
                items.forEach(itemRaycastHit => {
                    let item = itemRatcastHit?.entity;
                    if (item?.typeId === "minecraft:item") {
                        let blockPos = "xyz".split("").map(xyz => {
                            return item?.location[xyz]
                        })
                        if (this.createdEntity.var === "goldexperience:tree") {
                            a(block);
                            let direction = {
                                up: 0,
                                down: 1,
                                north: 2,
                                south: 3,
                                east: 4,
                                west: 5
                            };
                            let createdEntity = player?.dimension.spawnEntity(this.createdEntity.var, new Vec3(...blockPos).PositionFloor());
                            createdEntity.addTag("ownerName_" + player?.name);
                            let test = new mc.MolangVariableMap();
                            player?.dimension.spawnParticle("effect:leaf",new Vec3(...blockPos).PositionFloor(),test)
                            /*
                            let mark_variant = createdEntity.getComponent("minecraft:mark_variant");
                            mark_variant.value = direction[this.blockFace.var];*/
                        } else {
                            a(block);
                            let createdEntity = player?.dimension.spawnEntity(`goldexperience:create_life`, new Vec3(...blockPos).Position());
                            createdEntity?.addTag(this.createdEntity.var);
                            this.runCommand(`damage @s 0 entity_attack entity @a[name="${player?.name}"]`, createdEntity);
                        }
                        item?.kill();
                    }
                })
            }
            player?.removeTag("goldExperience.createLife");
        } else if (player?.hasTag("goldExperience.createLife") && this.create_life_cd.var < data.duration * 20) {
            player?.removeTag("goldExperience.createLife");
        }
        if (!player?.hasTag("goldExperience.createLife") && this.create_life_cd.var == 1) {
            this.removeAnim("gold_experience->fist");
        }
    }
    
    cure(data) {
        let player = this.standMaster;
        
        this.slot_data[2].var = [
            this.use_skill2 && !player?.isSneaking,
            (this.cure_cd.var / 20).toFixed(1),
            data.duration,
            NaN
        ].join("|")

        if (this.mental_value.var > 0 && this.cure_cd.var >= 0 && this.cure_cd.var < data.duration * 20) {
            this.cure_cd.var += 1;
        }
        if (player?.hasTag("goldExperience.cure") && this.mental_value.var > 0) {
            this.cure_cd2.var += 1;
            if (this.cure_cd.var >= data.duration * 20) {
                let entityFV = this.getEntitiesFromViewVector(player,3)[0];
                if (this.cure_cd2.var == 1) {
                    this.broadcastAnim(`gold_experience->cure.${entityFV === undefined ? "self" : "other"}`);
                }
                if (this.cure_cd2.var == 15) {
                    this.removeMentalValue(data.mental);
                    this.runCommands([
                        `tag @s add goldExperience.stopCure`,
                        `playsound goldExperience.create_life @a ~ ~ ~`
                    ], player);
                    if (entityFV === undefined) {
                        this.runCommands([
                            `damage @s 0 suicide`,
                            `particle goldexperience:cure ~ ~ ~`
                        ], player);
                        let health = player?.getComponent("minecraft:health");
                        this.addHealth(data.value);
                    } else {
                        let entity = entityFV?.entity;
                        this.runCommands([
                            `damage @s 0 suicide`,
                            `particle goldexperience:cure ~ ~ ~`
                        ], entity);
                        if (entity?.getTags().join("|").includes("standMaster.")) {
                            let shealth = this.GlobalVar(entity,"standMaster.health");
                            if (shealth.var >= 0) {
                                shealth.var += data.value;
                            }
                        }
                        let health = entity?.getComponent("minecraft:health");
                        health?.setCurrentValue(health?.currentValue + data.value)
                    }
                    this.cure_cd.var = 0;
                }
            }
        }
        if (player?.hasTag("goldExperience.stopCure") && this.cure_cd2.var > 0) {
            if (this.cure_cd2.var == 25) {
                this.removeAnim("gold_experience->cure");
                this.cure_cd2.var = 0;
                player?.removeTag(`goldExperience.cure`);
                player?.removeTag(`goldExperience.stopCure`);
            }
        }
        if (!player?.hasTag("goldExperience.cure") && this.cure_cd2.var > 0) {
            this.removeAnim("gold_experience->cure");
            this.cure_cd2.var = 0;
            // player?.removeTag(`goldExperience.cure`);
            // player?.removeTag(`goldExperience.stopCure`);
        }
    }
    
    
}

