'use strict';

const conf = require('../conf');
const {sleep} = require('../utils');


async function throwSnowballAtEntity(bot, entity) {
	const snowballItem = bot.bot.inventory.items().find(item => item.name === 'snowball');

	if (!snowballItem) {
		console.log("No snowballs in inventory.");
		return;
	}

	// Equip the snowball
	try{
		await bot.bot.equip(snowballItem, 'hand')

		let tossAt = bot.findBlockBySign('bot balls');
		// Simulate throwing a snowball
/*		const nearestHayBlock = bot.bot.findBlock({
			useExtraInfo: true,
			maxDistance: 64,
			matching: (block)=>block.name.includes('hay'),
		});
		if (nearestHayBlock){
		}*/

		await bot.bot.lookAt(tossAt.position.offset(0, -2, 0));
		await sleep(150);
		bot.bot.activateItem(); // This would simulate the throw of the snowball
		await sleep(200);
		bot.bot.activateItem(); // This would simulate the throw of the snowball
		await sleep(300);
		bot.bot.activateItem(); // This would simulate the throw of the snowball

	}catch(error){
		console.log('GoldFarm.throwSnowballAtEntity error', error);
	}
}

function getNearestEntityInDirection(bot, direction, entityType) {
    const entities = Object.values(bot.entities).filter(entity => 
        entity.position && entity !== bot.entity && entity.name === entityType
    );
    let nearestEntity = null;
    let minDistance = Infinity;
    
    for (const entity of entities) {
        const relativePos = entity.position.minus(bot.entity.position);
        const angle = Math.atan2(relativePos.x, relativePos.z);
        const targetAngle = direction * (Math.PI / 180);
        const angleDiff = Math.abs(angle - targetAngle);
        
        if (angleDiff < Math.PI / 8) { 
            const distance = bot.entity.position.distanceTo(entity.position);
            if (distance < minDistance) {
                minDistance = distance;
                nearestEntity = entity;
            }
        }
    }
    return nearestEntity;
}

class GoldFarm{
	location = {};

	constructor(args){
		this.bot = args.bot;
		this.target = args.target;
		this.interval = args.interval;
		this.intervalStop;
	}

	locationsSet(){
		this.location.xpSpotAlone = this.bot.findBlockBySign('xpSpotAlone');
		this.location.xpSpotSecond = this.bot.findBlockBySign('xpSpotSecond');
		this.location.xp = this.location.xpSpotAlone;
		this.location.attack = this.bot.findBlockBySign('bot attack spot');
	}

	async init(){
		this.onReadyListen = this.bot.on('onReady', async ()=>{
			await sleep(1000);
			console.log('GoldFarm.init onReady called');
			try{
			this.locationsSet();

				await this.agroPigs();

			}catch(error){
				console.error('Error in GoldFarm.init:', error);
			}


			await this.gotoXP();
			
			// let count = 1;
			// this.onPhysicTick = this.bot.on('physicsTick', async () => {
			// 	if(this.bot.bot.pathfinder.isMoving()) return;
			// 	if(count++ === 100){
			// 		count = 1;
			// 		for(let playerName in this.bot.bot.players){
			// 			if(this.bot.playerWithinBlock(playerName, this.location.xpSpotAlone, 1.5)){
			// 				this.location.xp = this.location.xpSpotSecond;
			// 			}else{
			// 				this.location.xp = this.location.xpSpotAlone;
			// 			}
			// 			await this.gotoXP();
			// 		}

			// 	}
			// });
		});

		return true;
	}

	unload(){
		console.log('GoldFarm.unload');
		clearInterval(this.intervalStop);
		this.intervalStop = null;
		this.onReadyListen();
		if(this.onPhysicTick) this.onPhysicTick();

		return true;
	}

	async agroPigs(){
		await this.bot.goTo({
			where: this.location.attack,
			range: 2,
		});

		await sleep(1000);
		// let entity = this.bot.bot.nearestEntity(
		// 	entity => entity.name.toLowerCase() === 'zombified_piglin' && this.bot.bot.entity.position.distanceTo(entity.position) >= 10
		// );

		let entity = getNearestEntityInDirection(this.bot.bot, 270, 'zombified_piglin');

		console.log('entity', entity)

		this.bot.bot.setControlState('jump', true);
		await sleep(100);
		await throwSnowballAtEntity(this.bot, entity);

		await sleep(1200);
		this.bot.bot.setControlState('jump', false);
	}

	async gotoXP(){
		await this.bot.bot.equip(this.bot.bot.inventory.items().find(
			item => item.name === 'diamond_sword'
		), 'hand');

		await this.bot.goTo({
			where: this.location.xp,
			range: 1,
		});
	}
}

GoldFarm.getStatus = function(instance) {
	return { active: true };
};

module.exports = GoldFarm;
