import { PrismaService } from 'nestjs-prisma';

const prisma = new PrismaService();

export async function calculateTotal(jobId: number, lineItemFormat = false, objectFormat = false) {
	const availableJob = await prisma.job.findUnique({
		where: { id: jobId },
		include: {
			client: true,
			contacts: {
				select: {
					id: true,
					name: true,
					email: true,
					role: true,
				},
			},
			fees: {
				include: {
					fee: true,
				},
			},
		},
	});

	if (!availableJob) {
		throw new Error('Job not found');
	}
	// gather designs

	const availableDesigns = await prisma.design.findMany({
		where: {
			jobId: availableJob.id,
		},
		include: {
			lineItems: {
				include: {
					product: true,
				},
			},
			imprints: {
				include: {
					inks: true,
				},
			},
		},
	});

	// get design price add to lineItems
	var lineItems: any[] = [];

	for (const design of availableDesigns) {
		// get imprint pricetype

		const priceTypeArray = design.imprints.map((imprint) => imprint.pricingType);

		// get inkTotal

		const inkTotalArray = design.imprints.map((imprint) => imprint.inks.length);

		var combinedTotal = 0;
		design.lineItems.forEach((lineItem: any) => {
			combinedTotal += lineItem.total;
		});

		// console.log('combinedTotal', combinedTotal);

		var printPrice: number = 0;

		for (const [index, priceType] of priceTypeArray.entries()) {
			if (priceType === 'Primary') {
				const matrix = await prisma.pricingmatrix.findFirst({
					orderBy: {
						quantity: 'desc',
					},
					where: {
						quantity: {
							lte: combinedTotal,
						},
						columnName: `colour${inkTotalArray[index]}`,
						tableName: 'primary',
						type: 'screen printing',
					},
				});
				if (matrix) {
					printPrice += matrix.amount as number;
				}
			} else if (priceType === 'Secondary') {
				const matrix = await prisma.pricingmatrix.findFirst({
					orderBy: {
						quantity: 'desc',
					},
					where: {
						quantity: {
							lte: combinedTotal,
						},
						columnName: `colour${inkTotalArray[index]}`,
						tableName: 'secondary',
						type: 'screen printing',
					},
				});
				if (matrix) {
					printPrice += matrix.amount as number;
				}
			} else if (priceType === 'Tertiary') {
				const matrix = await prisma.pricingmatrix.findFirst({
					orderBy: {
						quantity: 'desc',
					},
					where: {
						quantity: {
							lte: combinedTotal,
						},
						columnName: `colour${inkTotalArray[index]}`,
						tableName: 'tertiary',
						type: 'screen printing',
					},
				});
				if (matrix) {
					printPrice += matrix.amount as number;
				}
			} else {
				throw new Error('Invalid price type');
			}
		}

		design.lineItems.forEach((lineItem: any) => {
			var finalPrice = 0;

			if (lineItem.calculatedPrice) {
				finalPrice = lineItem.calculatedPrice;
			} else if (lineItem.price) {
				finalPrice = lineItem.price + printPrice;
			} else {
				finalPrice = lineItem.product.price + printPrice;
			}
			var invoiceLineItem = {
				description: lineItem.product.description,
				quantity: lineItem.total,
				unitAmount: finalPrice,
			};
			lineItems.push(invoiceLineItem);
		});
	}
	var feeCount = 0;
	availableJob.fees.forEach((fee: any) => {
		var lineItem = {
			description: fee.fee.description,
			quantity: fee.quantity,
			unitAmount: fee.fee.amount,
		};
		lineItems.push(lineItem);
		feeCount += fee.quantity;
	});

	// console.log('availableJob.fees', availableJob.fees);

	// console.log('lineItems', lineItems);

	if (lineItemFormat) {
		// console.log('lineItems', lineItems);
		return lineItems;
	} else if (objectFormat) {
		var total = 0;
		var quantity = 0;
		lineItems?.forEach((lineItem: any) => {
			total += lineItem.unitAmount * lineItem.quantity;
			quantity += lineItem.quantity;
		});

		// console.log('total', total);

		return {
			totalAmount: total,
			totalItems: quantity - feeCount,
		};
	} else {
		var total = 0;
		lineItems?.forEach((lineItem: any) => {
			total += lineItem.unitAmount * lineItem.quantity;
		});

		// console.log('total', total);

		return total;
	}
}
