let animations = require('../config/animations');
let itemGenerator = require('../items/generator');

//const track = {};

module.exports = {
	build: function (mob, blueprint, type, zoneName) {
		mob.instance.eventEmitter.emit('onBeforeBuildMob', zoneName, mob.name.toLowerCase(), blueprint);

		let typeDefinition = blueprint[type] || blueprint;

		if (blueprint.nonSelectable)
			mob.nonSelectable = true;

		mob.addComponent('effects');
		if (type && type !== 'regular') {
			mob.effects.addEffect({
				type: type
			});

			mob['is' + type[0].toUpperCase() + type.substr(1)] = true;

			mob.baseName = mob.name;
			mob.name = typeDefinition.name || mob.baseName;
		}

		if (typeDefinition.sheetName)
			mob.sheetName = typeDefinition.sheetName;

		if (typeDefinition.has('cell'))
			mob.cell = typeDefinition.cell;

		mob.addComponent('stats', {
			values: {
				level: blueprint.level
			}
		});

		let cpnMob = mob.addComponent('mob');
		extend(cpnMob, {
			walkDistance: blueprint.walkDistance,
			hpMult: blueprint.hpMult || typeDefinition.hpMult,
			dmgMult: blueprint.dmgMult || typeDefinition.dmgMult,
			grantRep: blueprint.grantRep,
			deathRep: blueprint.deathRep
		});
		if (blueprint.patrol)
			cpnMob.patrol = blueprint.patrol;

		if (cpnMob.patrol)
			cpnMob.walkDistance = 1;

		let spells = extend([], blueprint.spells);
		spells.forEach(s => {
			if (!s.animation && mob.sheetName === 'mobs' && animations.mobs[mob.cell]) 
				s.animation = 'basic';
		});

		mob.addComponent('spellbook', {
			spells: spells,
			dmgMult: typeDefinition.dmgMult
		});

		if (!blueprint.has('attackable') || blueprint.attackable === true) {
			mob.addComponent('aggro', {
				faction: blueprint.faction
			});

			mob.aggro.calcThreatCeiling(type);
		}

		mob.addComponent('equipment');
		mob.addComponent('inventory', typeDefinition.drops);
		mob.inventory.inventorySize = -1;
		mob.inventory.dailyDrops = blueprint.dailyDrops;

		if (this.zone) {
			let chats = this.zone.chats;
			if (chats && chats[mob.name.toLowerCase()]) {
				mob.addComponent('chatter', {
					chats: chats[mob.name.toLowerCase()]
				});
			}

			let dialogues = this.zone.dialogues;
			if (dialogues && dialogues[mob.name.toLowerCase()]) {
				mob.addComponent('dialogue', {
					config: dialogues[mob.name.toLowerCase()]
				});
			}
		}

		if (blueprint.properties && blueprint.properties.cpnTrade)
			mob.addComponent('trade', blueprint.properties.cpnTrade);

		this.scale(mob, blueprint.level);
	},

	scale: function (mob, level) {
		let drops = mob.inventory.blueprint || {};

		let statValues = mob.stats.values;

		let preferStat = ['str', 'dex', 'int'][~~(Math.random() * 3)];

		mob.equipment.unequipAll();
		mob.inventory.clear();

		let hp = level * 32.7;
		statValues.hpMax = hp;

		statValues.level = level;

		if ((!drops.blueprints) || (drops.alsoRandom)) {
			[
				'head',
				'chest',
				'neck',
				'hands',
				'waist',
				'legs',
				'feet',
				'finger',
				'trinket',
				'twoHanded'
			].forEach(slot => {
				let item = itemGenerator.generate({
					noSpell: true,
					level: level,
					slot: slot,
					quality: 4,
					forceStats: [preferStat]
				});

				delete item.spell;
				mob.inventory.getItem(item);
				mob.equipment.autoEquip(item.id);
			});
		} else {
			//TODO: Don't give the mob these items: he'll drop them anyway
			drops.blueprints.forEach(d => {
				if (d.type === 'key')
					return;

				let drop = extend({}, d);
				drop.level = level;

				mob.inventory.getItem(itemGenerator.generate(drop));
			});
		}

		let spellCount = (mob.isRare ? 1 : 0) + (mob.isChampion ? 2 : 0);

		for (let i = 0; i < spellCount; i++) {
			let rune = itemGenerator.generate({
				spell: true
			});
			rune.eq = true;
			mob.inventory.getItem(rune);
		}

		let dmgMult = 4.5 * mob.mob.dmgMult;
		let hpMult = 1 * mob.mob.hpMult;

		dmgMult *= [0.25, 0.4, 0.575, 0.8, 1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2, 2.1, 2.2, 2.3, 2.4, 2.5][level - 1];

		statValues.hpMax = ~~(statValues.hpMax * [0.1, 0.2, 0.4, 0.7, 0.78, 0.91, 1.16, 1.19, 1.65, 2.36, 3.07, 3.55, 4.1, 4.85, 5.6, 5.9, 6.5, 7.1, 7.9, 12][level - 1]);

		statValues.hpMax *= hpMult;
		statValues.hp = statValues.hpMax;
		statValues.mana = statValues.manaMax;

		mob.spellbook.spells.forEach(s => {
			s.dmgMult = s.name ? dmgMult / 3 : dmgMult;
			s.statType = preferStat;
			s.manaCost = 0;

			/*if (mob.name.toLowerCase().includes('stinktooth')) {
				mob.stats.values.critChance = 0;
				mob.stats.values.attackCritChance = 0;
				mob.stats.values.spellCritChance = 0;

				const n = mob.name + '-' + s.type;
				if (!track[n])
					track[n] = [];

				track[n].push(~~s.getDamage(mob, true).amount);
				track[n].sort((a, b) => a - b);
				console.log(track);
				console.log('');
			}*/
		});

		['hp', 'hpMax', 'mana', 'manaMax', 'level'].forEach(s => mob.syncer.setObject(false, 'stats', 'values', s, statValues[s]));
	}
};
