import { Block, Dimension, Entity, Player, system } from "@minecraft/server"
import { randomInteger, testing } from "../../utils/systemHelper"
import { DUMMY } from "../../entities/specific/dummy"
import { BlockStateNames } from "../utils/blockConstants"
import { EntityTypeIds } from "../../entities/utils/entityTypesIds"
import { EntityProperites } from "../../entities/utils/entityProperties"

export const CUSTOM_TORCHES = {
    _customTorchesBlockTag: "piki_beyondsurvival:custom_torch",
    _permutationLocations: {
        north: [0, 0.9, 0.25],
        south: [0, 0.9, -0.25],
        east: [-0.25, 0.9, 0],
        west: [0.25, 0.9, 0],
        up: [0, 0.7, 0]
    },
    _smokeParticleDistance: 10,
    _smokeParticleRandomDelay: [20, 90],
    _smokeParticleBaseDelay: 100,
    _smokeParticleIds: [
        "minecraft:basic_flame_particle",
        "minecraft:basic_smoke_particle"
    ],
    _dummyDynamicPropertyType: "custom_torch",

    // Entry Points
    /**
     * 
     * @returns {boolean}
     */
    shouldLightUp() {
        return system.currentTick % this._smokeParticleBaseDelay == 0
    },

    /**
     * 
     * @param {Block|Entity} value 
     * @returns 
     */
    isCustomTorch(value) {
        try {
            if (value instanceof Block) {
                return value.hasTag(this._customTorchesBlockTag)
            }
            else if (value instanceof Entity) {
                if (DUMMY.getType(value) == this._dummyDynamicPropertyType) return true
    
                // Old Implementation
                if (!value.hasTag("torch")) return false
                value.removeTag("lit")
                value.removeTag("torch")
                value.setDynamicProperty(EntityProperites.dummyType, this._dummyDynamicPropertyType)
                // testing.success("Converted an old torch tag to dynamic property")
                return true
            }
        } catch {
            return false
        }
        
    },

    // Helper Methods
    /**
     * 
     * @param {Player} player 
     */
    lightUp(player) {
		const torchEntities = player.dimension.getEntities({
            location: player.location, 
            maxDistance: this._smokeParticleDistance, 
            type: EntityTypeIds.dummy
        })

        let litTorches = 0
		torchEntities.forEach(torchEntity => {
            const dummyType = DUMMY.getType(torchEntity) 
            const isLit = torchEntity.getDynamicProperty(EntityProperites.isCustomTorchLit)
            
            if (!this.isCustomTorch(torchEntity) || isLit) return;

			torchEntity.setDynamicProperty(EntityProperites.isCustomTorchLit, true)

			const exactLocation = torchEntity.location;
			const block = player.dimension.getBlock(exactLocation)
			const blockState = block.permutation.getState(BlockStateNames.blockFace)

			if (!blockState) return
            
            litTorches++

			const particleLocation = {
				x: exactLocation.x + this._permutationLocations[blockState][0],
				y: exactLocation.y + this._permutationLocations[blockState][1],
				z: exactLocation.z + this._permutationLocations[blockState][2]
			}

			system.runTimeout(() => {
                if (!block) return
                if (!torchEntity.isValid()) return;
				if (!this.isCustomTorch(block)) return DUMMY.kill(torchEntity)
                this._smokeParticleIds.forEach(x => torchEntity.dimension.spawnParticle(x, particleLocation))
                torchEntity.setDynamicProperty(EntityProperites.isCustomTorchLit, false)
			}, randomInteger(this._smokeParticleRandomDelay[1], this._smokeParticleRandomDelay[0]))
		})
        // if (litTorches) testing.info(player.name, "lit up", litTorches, "torches")
    },

    /**
     * @param {Block} block
     * @returns 
     */
    wasPlaced(block) {
        system.run(() => {
            const {dimension, location} = block 
            DUMMY.summon(dimension, location, this._dummyDynamicPropertyType)
        })
    },
    
    /**
     * 
     * @param {Dimension} dimension 
     * @param {*} location 
     */
    wasDestroyed(dimension, location) {
        // testing.info("Destroyed torch at", location.x, location.y, location.z)
        const torchEntity = dimension.getEntities({
            location: location, 
            type: EntityTypeIds.dummy,
        })?.[0]

	    if (torchEntity && this.isCustomTorch(torchEntity)) DUMMY.kill(torchEntity);
    },


}