"use strict";

function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }

require("./blackout");
const playerLib = blackout.playerLib;

/**
 * This file is for testing this library only
 */

exports.handler = (() => {
	var _ref = _asyncToGenerator(function* (event, context, callback) {

		try {

			// Init Blackout
			yield blackout.initAsync(event, callback);

			// -------------------------------------------- Do stuff

			//let startingLevel = 25; // This is now set automatically based on starting skills
			let proximity = 35; // The number of levels to train (this should be 40 if training to max skill level or if training to max trainable level per skill)
			let seasonsToTrainPlayer = 14; // Duh, 18yo to 32yo
			let numTrainableSkills = 15; // 15 positional/general

			let settings = { // Level 5 youth
				// [numSkills,averageLevel,deviationLevels]
				PosCat1: [3, 37, 2],
				PosCat2: [4, 33, 3],
				PosCat3: [7, 26, 5],
				PosCat4: [4, 13, 7]
			};
			/*let settings = { // Level 1 youth
   	// [numSkills,averageLevel,deviationLevels]
   	PosCat1: [3,20,2],
   	PosCat2: [4,15,3],
   	PosCat3: [7,10,5],
   	PosCat4: [4,5,7],
   };*/

			// Build Player
			let player = {};
			for (let key in settings) {

				let [numSkills, averageLevel, deviationLevels] = settings[key];
				for (let s = 1; s <= numSkills; s++) {

					let gap = deviationLevels * 2 / (numSkills - 1);
					let cursor = (numSkills - 1) / 2 - (s - 1);
					let offset = Math.round(gap * cursor);
					let level = averageLevel + offset;
					player[key + '_' + s + '_level'] = level;
					player[key + '_' + s + '_points'] = playerLib.levelToPoints(level);
					player[key + '_' + s + '_olevel'] = level;
				}
			}
			let startingLevel = getPlayerLevel(player, numTrainableSkills);

			//------

			let startingPoints = getPlayerPoints(player, numTrainableSkills);
			let clubPlayerLevel = startingLevel + proximity;
			let clubPlayerPoints = playerLib.levelToPoints(clubPlayerLevel) * numTrainableSkills;
			let pointsNeeded = (clubPlayerPoints - startingPoints) / 0.9; // Includes exponential adjustmentment
			let numDays = seasonsToTrainPlayer * 28;
			let pointsPerDay = Math.round(pointsNeeded / numDays);

			let level = playerLib.pointsToLevel(startingPoints / numTrainableSkills);
			let totalDays = 1;
			let newLevel,
			    currentPoints = startingPoints,
			    tracking = {};
			console.log(`Player starts with ${startingPoints}, level ${level}`);
			do {

				// Do training
				let playerBefore = blackout.cloneObject(player, new Error());
				player = trainPlayer(player, pointsPerDay, numTrainableSkills, proximity);
				let pops = getPops(playerBefore, player);
				//newLevel = playerLib.pointsToLevel(currentPoints/numTrainableSkills); // Divide across 22 skills
				newLevel = getPlayerLevel(player, numTrainableSkills);
				currentPoints = getPlayerPoints(player, numTrainableSkills);

				let season = Math.ceil(totalDays / 28);
				let day = totalDays - (season - 1) * 28;
				console.log(`Season ${season} Day ${day}, New total points ${currentPoints}, Level ${newLevel}, Pops: ${pops}`);
				if (!('level_' + newLevel in tracking)) {
					tracking['level_' + newLevel] = 0;
				}
				tracking['level_' + newLevel]++;
				totalDays++;
			} while (newLevel < clubPlayerLevel);

			console.log('---------Tracking Summary---------');

			for (let levelStr in tracking) {

				let days = tracking[levelStr];
				let [, level] = levelStr.split('_');
				if (level > 30 && days == 1) {
					console.log(`Reached level ${level}`);
				} else {
					console.log(`Took ${days} days on level ${level}`);
				}
			}

			console.log('---------Level Points progression ---------');

			playerLib.levels(100, null, true);

			console.log('--------- End ---------');

			console.log('Final player', player);

			// -------------------------------------------- End stuff

			console.log('Done');
			blackout.complete();
		} catch (err) {
			blackout.complete(err);
		}
	});

	return function (_x, _x2, _x3) {
		return _ref.apply(this, arguments);
	};
})();

function getPlayerPoints(player, numTrainableSkills) {
	let points = 0;
	let i = 0;
	for (let key in player) {
		if (key.indexOf('_points') >= 0) {
			points += player[key];
			i++;
			if (i >= numTrainableSkills) break;
		}
	}
	return points;
}

function getPops(playerBefore, playerAfter) {
	let pops = [];
	for (let key in playerAfter) {
		if (key.indexOf('_level') >= 0 && playerBefore[key] < playerAfter[key]) {
			let [skillType, skillIndex] = key.split('_');
			pops.push(skillType + '_' + skillIndex + ' (+' + (playerAfter[key] - playerBefore[key]) + ')');
		}
	}
	return pops;
}

function trainPlayer(player, totalPoints, numTrainableSkills, proximity) {

	// ------------ Settings

	let sporadic = true; // Trains some skills a lot, and others not much, sometimes

	// ------------ End settings


	// ------------ Check for maxed skills

	let maxedSkills = 0;
	for (let key in player) {
		if (key.indexOf('_maxed') >= 0) {
			maxedSkills++;
		}
	}
	let unmaxedTrainableSkills = numTrainableSkills - maxedSkills;

	// ------------ Sporadic

	let randomExtraSkills = [];
	let randomNoneSkills = [];
	let boost;
	if (sporadic) {
		// Decide if going to double, triple, or quadruple on this training
		boost = blackout.rand(2, 4);
		// Pick a random number of skills to train a lot
		let numExtraSkills = blackout.rand(0, Math.round(unmaxedTrainableSkills / boost) - 1);

		// Get extra skills
		do {
			let newSkill = blackout.rand(1, unmaxedTrainableSkills);
			if (randomExtraSkills.indexOf(newSkill) < 0) {
				randomExtraSkills.push(newSkill);
			}
		} while (randomExtraSkills.length < numExtraSkills);

		// Get nulled skills (Need boost -1 x extra skills)
		do {
			let newSkill = blackout.rand(1, unmaxedTrainableSkills);
			if (randomNoneSkills.indexOf(newSkill) < 0 && randomExtraSkills.indexOf(newSkill) < 0) {
				randomNoneSkills.push(newSkill);
			}
		} while (randomNoneSkills.length < numExtraSkills * (boost - 1));
	}

	// ------------ End Sporadic

	// Train trainable skills
	let pointsPerSkill = Math.round(totalPoints / unmaxedTrainableSkills);
	let skillsTrained = 0;
	for (let key in player) {

		if (key.indexOf('_points') >= 0) {

			let [skillType, skillIndex] = key.split('_');

			// Make sure skill isn't maxed
			if (!(skillType + '_' + skillIndex + '_maxed' in player)) {

				// Don't train skills we're ignoring if sporadic trainin is on
				if (randomNoneSkills.indexOf(skillsTrained) < 0) {

					let pointsApplied = Math.min(pointsPerSkill, totalPoints);

					if (randomExtraSkills.indexOf(skillsTrained) >= 0) {
						pointsApplied *= boost;
					}

					player[key] += pointsApplied;
					totalPoints -= pointsApplied;
					player[skillType + '_' + skillIndex + '_level'] = playerLib.pointsToLevel(player[key]);

					// Check for max level
					let currentLevel = player[skillType + '_' + skillIndex + '_level'];
					let maxLevel = player[skillType + '_' + skillIndex + '_olevel'] + proximity;
					if (currentLevel >= maxLevel) {

						// Get points for next level
						let nextLevelPoints = playerLib.levelToPoints(maxLevel + 1);

						if (currentLevel > maxLevel || player[key] >= nextLevelPoints - pointsPerSkill) {
							// Mark this skill as maxed
							player[key] = nextLevelPoints - 1;
							player[skillType + '_' + skillIndex + '_level'] = maxLevel;
							player[skillType + '_' + skillIndex + '_maxed'] = true;
						}
					}
				}

				skillsTrained++;
				if (skillsTrained >= unmaxedTrainableSkills) break;
			}
		}
	}

	return player;
}

function getPlayerLevel(player, numTrainableSkills) {
	let total = 0;
	let num = 0;
	let levels = [];
	for (let key in player) {

		if (key.indexOf('_level') >= 0) {
			levels.push(player[key]);
		}
	}

	// Sort levels
	levels.sort(function (a, b) {
		return a - b;
	});
	levels.reverse();

	// Average the top 15
	let i = 0;
	for (let level of levels) {

		total += level;
		num++;

		i++;
		if (i >= numTrainableSkills) break;
	}

	return Math.round(total / num);
}
//# sourceMappingURL=player-progression.js.map