/**
 * Cost calculation implementation
 *
 * All function must be implemented graph-agnostic.
 * This allows for:
 * 	- computation of price-previews without the need to modify the graph
 * 	- safe utilization in internal script engine
 * 	- ...
 *
 * Functions must *not* use
 * 	- wsi4.graph
 * 	- wsi4.node
 * 	- ...
 */

import {
	TableType,
} from "qrc:/js/lib/generated/enum";
import {
	assert,
	isNonNegativeNumber,
} from "qrc:/js/lib/utils";

import {
	LaserSheetCuttingCalcParams,
} from "./calc_times_laser_sheet_cutting";
import {
	getTable,
} from "./table_utils";

export class Costs {
	material = 0;
	setup = 0;
	unit = 0;

	constructor(materialCosts: number, setupCosts: number, unitCosts: number) {
		assert(isNonNegativeNumber(materialCosts), "Invalid material costs");
		assert(isNonNegativeNumber(setupCosts), "Invalid setup costs");
		assert(isNonNegativeNumber(unitCosts), "Invalid unit costs");

		/**
		 * Material costs *including* multiplicity
		 */
		this.material = materialCosts;

		/**
		 * Setup costs
		 */
		this.setup = setupCosts;

		/**
		 * Unit costs *including* multiplicity
		 */
		this.unit = unitCosts;
	}
}

export function addCosts(costs: readonly Readonly<Costs|undefined>[]): Costs|undefined {
	return costs.some(c => c === undefined) ? undefined : costs.reduce((acc: Costs, c) => {
		assert(c !== undefined);
		return {
			material: acc.material + c.material,
			setup: acc.setup + c.setup,
			unit: acc.unit + c.unit,
		};
	}, new Costs(0, 0, 0));
}

export function laserSheetCuttingRatePerSecond(params: Readonly<LaserSheetCuttingCalcParams>): number|undefined {
	const table = getTable(TableType.laserSheetCuttingRate);
	const row = table.find(element => element.sheetCuttingMaterialId === params.sheetCuttingMaterialId && element.laserSheetCuttingGasId === params.laserSheetCuttingGasId);
	if (row === undefined) {
		wsi4.util.error("laserSheetCuttingRatePerSecond(): No laser sheet cutting rate available for sheetCuttingMaterialId \"" +
				params.sheetCuttingMaterialId + "\" and cutting gas \"" + params.laserSheetCuttingGasId + "\".");
		return undefined;
	}

	// [Currency/h]
	const tableValue = row.rate;

	// [Currency/s]
	const result = tableValue / 3600;

	return result;
}
