import { Player, system, world } from "@minecraft/server";
import { ActionManager } from "../lib/actionManager"
const actionManager = new ActionManager();
const mobs = [
    'ld_hw:the_butcher',
    'ld_hw:the_chain_warden',
    'ld_hw:the_corruptor',
    'ld_hw:the_wraith_keeper'
]
const stayDurationValue = 15*20
let stayDuration = stayDurationValue
system.runInterval(()=>{
    if(world.getDynamicProperty('ld_hw.:jumpscare')==false) return
    const time = world.getTimeOfDay()
    //console.warn(`Time of today is: ${time}`)
    world.getPlayers({gameMode:'survival'}).forEach(player=>{
        detection(player)
    })
    world.getPlayers({gameMode:'adventure'}).forEach(player=>{
        detection(player)
    })
})
function detection(player) {
    player.getEntitiesFromViewDirection().forEach(ray=>{
        if(!ray.entity.isValid()) return
        if(mobs.includes(ray.entity.typeId) && ray.distance <= 20 ) {
            if(ray.entity.getProperty('ld_hw:near_target')===false && player.getDynamicProperty('ld_hw:jumpscare_delay') === 0) {
                jumpscare(player, ray.entity)
            }
        }
    })
    const entities = player.dimension.getEntities({maxDistance:10,location:player.location,families:["ld_hw:mob"],closest:1})
    entities.forEach(entity=>{
        if(stayDuration == 0){
            if(entity.getProperty('ld_hw:near_target')===false && player.getDynamicProperty('ld_hw:jumpscare_delay') === 0) {
                jumpscare(player, entity)
            }
        }
        if(stayDuration > 0){stayDuration --}else if(stayDuration<=0){stayDuration=stayDurationValue}
    })
    if (entities.length == 0){stayDuration=stayDurationValue}
    if (getTimeOfDayForCurrentDay(world.getTimeOfDay()) == 'Night') {
        //console.warn('is Night Time')
        if (player.getDynamicProperty('ld_hw:night_js_available') == true){
            pre_jumpscare2_delay(player)
        }
    } else if (getTimeOfDayForCurrentDay(world.getTimeOfDay()) == 'Day') {
        //console.warn('is Day Time')
        if (player.getDynamicProperty('ld_hw:night_js_available') == false){
            player.setDynamicProperty('ld_hw:night_js_available', true)
        }
    }
}
function duration(entity) {
    if (entity.typeId === 'ld_hw:the_butcher') {
        return 1.5;
    } else if (entity.typeId === 'ld_hw:the_chain_warden') {
        return 1.5;
    } else if (entity.typeId === 'ld_hw:the_corruptor') {
        return 1.95;
    } else if (entity.typeId === 'ld_hw:the_wraith_keeper') {
        return 1.5;
    }
    return 1.5;
}
function jumpscare(player, entity) {
    
    const playerDelay = Math.round(Math.random() * (248 - 60) + 60);
    player.runCommand(`playsound ld_hw:pre_jumpscare.${entity.typeId} @s`)
    player.setDynamicProperty('ld_hw:jumpscare_delay',playerDelay)
    const rotInterval = system.runInterval(()=>{
        if (!entity.isValid() || !player.isValid()) return
        //console.warn(`TITIT`)
        entity.runCommand(`tp @s ~~~ facing ${player.location.x} ${player.location.y+1} ${player.location.z}`)
    })
    const delay = Math.round(Math.random() * (20-10)+10);
    system.runTimeout(()=>{
        player.runCommand(`playsound ld_hw:rising_tension @s`)
    },(delay-8)*20)
    const movement = entity.getComponent("minecraft:movement")
    movement.setCurrentValue(0)
    const effectTimer = system.runTimeout(()=>{
        player.addEffect('darkness',3*20)
    },(delay-2)*20)
    const timer = system.runTimeout(()=>{
        jumpscareStart(player,entity)
        const entityDuration = duration(entity)
        system.runTimeout(()=>{
            system.clearRun(rotInterval)
            //entity.setProperty("ld_hw:delay",false)
            //actionManager.stopAllActions(entity)
        },entityDuration*20)
    },delay*20)
    const funcInterval = system.runInterval(()=>{
        if (!entity.isValid())return
        if(player.getComponent("minecraft:health").currentValue === 0 || !player.isValid()) {
            system.clearRun(timer)
            cancelJumpscare(player,entity)
            system.clearRun(funcInterval)
        }
        if(entity.getProperty('ld_hw:near_target') == true || entity.getProperty('ld_hw:has_target') == true) {
            const entityDuration = duration(entity)
            system.runTimeout(()=>{
                system.clearRun(rotInterval)
                //entity.setProperty("ld_hw:delay",false)
                //actionManager.stopAllActions(entity)
            },entityDuration*20)
            system.clearRun(effectTimer)
            player.addEffect('darkness',2*20)
            system.clearRun(timer)
            jumpscareStart(player,entity)
            system.clearRun(funcInterval)
        }
    })
}
function jumpscareStart(player,entity) {
    if(world.getDynamicProperty(`ld_hw.:sound`)==true) {
        player.runCommand(`stopsound @s ld_hw:fight_song`)
        player.runCommand(`playsound ld_hw:fight_song @s`)
    }
    player.runCommand(`playsound ld_hw:jumpscare.${entity.typeId} @s`)
    player.runCommand(`playsound ld_hw:clingy_jumpscare @s`)
    const range = 2
    const tpLoc = {
        x:player.location.x+player.getViewDirection().x*range,
        y:player.location.y,
        z:player.location.z+player.getViewDirection().z*range
    }
    const face = {
        x:player.location.x,
        y:player.location.y+1,
        z:player.location.z
    }
    entity.teleport(tpLoc,{facingLocation:face})
    entity.triggerEvent('ld_hw:jumpscare')
    system.runTimeout(() => { 
        entity.setProperty("ld_hw:jumpscare", false) 
    }, 1)
    entity.applyDamage(1,{damagingEntity:player,cause:'contact'})
    //entity.setProperty("ld_hw:delay",true)
}
function cancelJumpscare(player,entity) {
    system.runTimeout(() => { entity.setProperty("ld_hw:jumpscare", false) }, 1)
    system.clearRun(rotInterval)
    actionManager.stopAllActions(entity)
}
function calculateAngle(entity, player) {
    // Hitung selisih posisi X dan Z
    let dx = player.location.x - entity.location.x;
    let dz = player.location.z - entity.location.z;
  
    // Hitung sudut dalam radian menggunakan atan2
    let angle = Math.atan2(dz, dx);
  
    // Ubah sudut dari radian ke derajat
    angle = angle * (180 / Math.PI);
  
    // Pastikan rotasi berada dalam rentang 0-360 derajat
    if (angle < 0) {
      angle += 360;
    }
  
    return angle - 90;
}
function pre_jumpscare2_delay(player) {
    player.setDynamicProperty('ld_hw:night_js_available', false)
    //console.warn('PRE JUMPSCARE TIMER ON!!!')
    const delay = Math.random() * (200-100) + 100
    const jsTimer = system.runTimeout(()=>{
        pre_jumpscare2(player)
    },delay*20)
    const interval = system.runInterval(()=>{
        if(getTimeOfDayForCurrentDay(world.getTimeOfDay()) == 'Day'){
            system.clearRun(jsTimer)
            //console.warn('PRE JUMPSCARE TIMER OFF!!!')
            player.setDynamicProperty('ld_hw:night_js_available', true)
            system.clearRun(interval)
        }
    })
}
function pre_jumpscare2(player) {
    //console.warn('PRE JUMPSCARE IS BEGIN!!!')
    const randomType = Math.floor(Math.random() * (2-0)+0)
    console.warn('YOUR JUMPSCARE WILL BE ' +randomType+ ' VERSION!')
    const isPreJumpscared = Math.floor(Math.random() * (2-0)+0)
    const playerDelay = Math.round(Math.random() * (248 - 60) + 60)
    player.setDynamicProperty('ld_hw:jumpscare_delay',playerDelay)
    const jumpscareDelay = Math.round(Math.random() * (60 - 30) + 30)
    player.runCommand(`playsound ld_hw:horror_ambient @s`)
    system.runTimeout(()=>{
        system.runTimeout(()=>{
            switch (isPreJumpscared){
                case 0:
                break;
                case 1:
                    player.runCommand(`stopsound @s ld_hw:horror_ambient`)
                break;
            }
        },8*20)
        switch (isPreJumpscared){
            case 0:
            break;
            case 1:
                player.runCommand(`playsound ld_hw:rising_tension @s`)
            break;
        }
        system.runTimeout(()=>{
            system.runTimeout(()=>{
                switch (randomType){
                    case 0:
                        jumpscare2(player)
                    break;
                    case 1:
                        jumpscare3(player)
                    break;
                }
            },(jumpscareDelay/12)*20)
        },8.7*20)
    },jumpscareDelay*20)
}
function jumpscare2(player) {
    const isOnlyClingy = Math.floor(Math.random() * (2-0)+0)
    const jumpscareEntity = player.dimension.spawnEntity('ld_hw:player_jumpscare2', player.location)
    const randomRange = Math.round(Math.random() * (6 - 3) + 3);
    jumpscareEntity.teleport(player.location,{rotation:{x:0,y:player.getRotation().y}})
    for (let i=0;i<randomRange;i++){
        jumpscareEntity.runCommand(`tp @s ^^^1 ~~ true`)
    }
    jumpscareEntity.runCommand(`spreadplayers ${jumpscareEntity.location.x} ${jumpscareEntity.location.z} 2 3 @s`)
    jumpscareEntity.triggerEvent('ld_hw:random_js')
    system.runTimeout(()=>{
        jumpscareEntity.triggerEvent('ld_hw:visible')
        const variant = jumpscareEntity.getProperty('ld_hw:jumpscare_type')
        switch (isOnlyClingy){
            case 0:
                player.runCommand(`playsound ld_hw:clingy_jumpscare @s`)
                switch (variant) {
                    case 1:
                        player.runCommand(`playsound ld_hw:jumpscare.ld_hw:the_butcher @s`)
                    break;
                    case 2:
                        player.runCommand(`playsound ld_hw:jumpscare.ld_hw:the_chain_warden @s`)
                    break;
                    case 3:
                        player.runCommand(`playsound ld_hw:jumpscare.ld_hw:the_corruptor @s`)
                    break;
                    case 4:
                        player.runCommand(`playsound ld_hw:jumpscare.ld_hw:the_wraith_keeper @s`)
                    break;
                }
            break;
            case 1:
                player.runCommand(`playsound ld_hw:clingy_jumpscare @s`)
            break;
        }
        const facingLoc = {
            x:jumpscareEntity.location.x,
            y:jumpscareEntity.location.y+2,
            z:jumpscareEntity.location.z
        }
        player.runCommand(`effect @s darkness 20 0 true`)
        system.runTimeout(()=>{player.runCommand(`effect @s night_vision 20 0 true`)},1)
        player.runCommand(`hud @s hide`)
        player.runCommand(`inputpermission set @s camera disabled`)
        player.runCommand(`inputpermission set @s movement disabled`)
        player.teleport(player.location,{facingLocation:facingLoc})
        player.addEffect('slowness', 1*20, {amplifier:3,showParticles:false})
        system.runTimeout(()=>{
            player.runCommand(`effect @s night_vision 0`)
            player.runCommand(`effect @s darkness 0`)
            player.runCommand(`hud @s reset`)
            player.runCommand(`inputpermission set @s camera enabled`)
            player.runCommand(`inputpermission set @s movement enabled`)
            if(!jumpscareEntity.isValid()) return
            jumpscareEntity.remove()
        },1*20)
    },1*20)
}
function jumpscare3(player) {
    const isOnlyClingy = Math.floor(Math.random() * (2-0)+0)
    const duration = 0;
    system.runTimeout(()=>{
        const range = 20
        const speed = 0.3
        const loc = {
            x:player.location.x+player.getViewDirection().x*range,
            y:player.location.y,
            z:player.location.z+player.getViewDirection().z*range
        }
        const jumpscareEntity = player.dimension.spawnEntity('ld_hw:player_jumpscare3',loc)
        let jsLoc = {x:jumpscareEntity.location.x,y:jumpscareEntity.location.y+2,z:jumpscareEntity.location.z}
        jumpscareEntity.triggerEvent('ld_hw:random_js')
        let damn = false
        system.runTimeout(()=>{
            player.runCommand(`effect @s darkness 20 0 true`)
            system.runTimeout(()=>{player.runCommand(`effect @s night_vision 20 0 true`)},1)
            
            player.runCommand(`hud @s hide`)
            player.runCommand(`inputpermission set @s movement disabled`)
            player.runCommand(`inputpermission set @s camera disabled`)
            //player.runCommand(`/camerashake add @s 0.2 2 rotational`)
            player.addEffect('slowness', 2*20, {amplifier:3})
            jumpscareEntity.teleport({
                x:player.location.x+player.getViewDirection().x*2,
                y:player.location.y,
                z:player.location.z+player.getViewDirection().z*2
            })
            jsLoc = {x:jumpscareEntity.location.x,y:jumpscareEntity.location.y+1,z:jumpscareEntity.location.z}
            player.teleport(player.location,{facingLocation:jsLoc})
            const variant = jumpscareEntity.getProperty('ld_hw:jumpscare_type')
            switch (isOnlyClingy){
                case 0:
                    player.runCommand(`playsound ld_hw:clingy_jumpscare @s`)
                    switch (variant) {
                        case 1:
                            player.runCommand(`playsound ld_hw:jumpscare.ld_hw:the_butcher @s`)
                        break;
                        case 2:
                            player.runCommand(`playsound ld_hw:jumpscare.ld_hw:the_chain_warden @s`)
                        break;
                        case 3:
                            player.runCommand(`playsound ld_hw:jumpscare.ld_hw:the_corruptor @s`)
                        break;
                        case 4:
                            player.runCommand(`playsound ld_hw:jumpscare.ld_hw:the_wraith_keeper @s`)
                        break;
                    }
                break;
                case 1:
                    player.runCommand(`playsound ld_hw:clingy_jumpscare @s`)
                break;
            }
        },5*20)
        system.runTimeout(()=>{
            player.runCommand(`effect @s night_vision 0`)
            player.runCommand(`effect @s darkness 0`)
            jumpscareEntity.dimension.spawnParticle('ld_hw:phase_shift_1',jumpscareEntity.location)
            jumpscareEntity.dimension.spawnParticle('ld_hw:phase_shift_2',jumpscareEntity.location)
            jumpscareEntity.remove()
            player.runCommand(`hud @s reset`)
            player.runCommand(`inputpermission set @s movement enabled`)
            player.runCommand(`inputpermission set @s camera enabled`)
        },7*20)
    },(duration)*20)
}
function checkDistance(subject, target) {
    if(!subject.isValid()||!target.isValid()) return
    const deltaX = target.location.x - subject.location.x;
    const deltaY = target.location.y - subject.location.y;
    const deltaZ = target.location.z - subject.location.z;
    const distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
    return distance;
}
world.afterEvents.itemUse.subscribe((event)=>{
    const player = event.source
    const item = event.itemStack
    // if (item.typeId==="minecraft:stone_sword"){
    //     pre_jumpscare2(player)
    // }
})
function getTimeOfDayForCurrentDay(worldTime) {
    const dayCycleLength = 24000;
    const currentDay = Math.floor(worldTime / dayCycleLength);
    
    const morningTime = 1000 + (currentDay * dayCycleLength);
    const nightTime = 13000 + (currentDay * dayCycleLength);
    
    if (worldTime >= morningTime && worldTime < nightTime) {
        return 'Day'; // Siang
    } else {
        return 'Night'; // Malam
    }
}
world.afterEvents.entityHurt.subscribe(event=>{
    const victim = event.hurtEntity
    const source = event.damageSource.damagingEntity

    if(mobs.includes(victim.typeId)&&source.typeId==='minecraft:player') {
        if(victim.getProperty(`ld_hw:has_target`)===false) {
            jumpscareStart(source,victim)
        }
    }
})