import { useSelector } from 'react-redux';
import { useNavigate } from 'react-router-dom';

import type { FinancialsModel } from '../../../Pages/Financials/Components/FinancialsForm/FinancialsForm.helper';
import { RootState } from '../../../ReduxState/store';

interface SummaryCalculations {
	calculatedGrossMargin: number;
	calculatedDebtorsDays: number;
	calculatedWorkingCapital: number;
	calculatedInvestInWorkingCapital: number;
	calculatedEbitPercentOfRevenue: number;
	calculatedEbitPercentOfGrossMargin: number;
	calculatedStockDays: number;
	calculatedNetProfitBeforeTax: number;
	calculatedCreditorsDays: number;
	calculatedMarginalCashFlow: number;
	calculatedDeferredRevenueDays: number;
	calculatedCashDaysCycle: number;
}

interface ProfitabilityCalculations {
	calculatedRevenueGrowthSecondFinancial: number;
	calculatedRevenueGrowthThirdFinancial: number;
	calculateCogsFirst: number;
	calculatedCogsSecond: number;
	secondFinancialMonthEnding: string;
	secondFinancialYearEnding: string;
	thirdFinancialMonthEnding: string;
	thirdFinancialYearEnding: string;
	SecondRevenue: string;
	ThirdRevenue: string;
	calculatedGrossMarginFirst: number;
	calculatedGrossMarginSecond: number;
	calculatedContributionMarginFirst: number;
	calculatedContributionMarginSecond: number;
	calculatedChangeContributionMargin: number;
	calculatedOverheadsFirst: number;
	calculatedOverheadsSecond: number;
	calculatedEbitPercentOfRevenueFirst: number;
	calculatedEbitPercentOfRevenueSecond: number;
	calculatedEbitdaFirst: number;
	calculatedEbitdaSecond: number;
	calculatedNetProfitBeforeTaxOfRevenueFirst: number;
	calculatedNetProfitBeforeTaxOfRevenueSecond: number;
	calculatedNetProfitBeforeTaxOfGrossMarginFirst: number;
	calculatedNetProfitBeforeTaxOfGrossMarginSecond: number;
	calculatedNetProfitAfterTaxFirst: number;
	calculatedNetProfitAfterTaxSecond: number;
	calculatedChangeRevenue: number;
	calculatedChangeRevenueGrowth: number;
	calculatedChangeCogs: number;
	calculatedChangeGrossMargin: number;
	calculatedChangeEbitOfRevenue: number;
	calculatedChangeEbitda: number;
	calculatedChangeNetProfitOfRevenue: number;
	calculatedChangeNetProfitOfGrossMargin: number;
	calculatedChangeNetProfitAfterTax: number;
	calculatedChangeOverheads: number;
	calculatedCogsGrowthFirst: number;
	calculatedCogsGrowthSecond: number;
	calculatedCogsGrowthThird: number;
	calculatedOverheadsGrowthFirst: number;
	calculatedOverheadsGrowthSecond: number;
	calculatedOverheadsGrowthSum: number;
	calculatedLerFirst: number;
	calculatedLerSecond: number;
}

function cashFlowAnalysisCalculations(thirdFinancial: FinancialsModel): SummaryCalculations {
	const calculatedGrossMargin =
		(+thirdFinancial.input['Gross Profit'] / +thirdFinancial.input.Revenue) * 100;
	const calculatedDebtorsDays =
		(+thirdFinancial.input['Trade Debtors'] / +thirdFinancial.input.Revenue) * 365;
	const calculatedWorkingCapital =
		+thirdFinancial.input['Trade Debtors'] +
		+thirdFinancial.input.Stock -
		+thirdFinancial.input['Trade Creditors'] +
		+thirdFinancial.input['Deferred Revenue'];
	const calculatedInvestInWorkingCapital =
		(calculatedWorkingCapital / +thirdFinancial.input.Revenue) * 100;
	const calculatedEbitPercentOfRevenue =
		(+thirdFinancial.input.EBIT / +thirdFinancial.input.Revenue) * 100;
	const calculatedEbitPercentOfGrossMargin =
		((+thirdFinancial.input.EBIT -
			+thirdFinancial.input['Interest Paid'] +
			+thirdFinancial.input['Other Income']) /
			+thirdFinancial.input['Gross Profit']) *
		100;

	// const calculatedStockDays = (+thirdFinancial.input.Stock / +thirdFinancial.input.Revenue) * 365;
	const calculatedStockDays = (+thirdFinancial.input.Stock / +thirdFinancial.input.COGS) * 365;
	const calculatedNetProfitBeforeTax =
		((+thirdFinancial.input.EBIT -
			+thirdFinancial.input['Interest Paid'] +
			+thirdFinancial.input['Other Income']) /
			+thirdFinancial.input.Revenue) *
		100;
	const calculatedCreditorsDays =
		(+thirdFinancial.input['Trade Creditors'] / +thirdFinancial.input.COGS) * 365;
	const calculatedMarginalCashFlow =
		+thirdFinancial.input['Gross Profit'] / +thirdFinancial.input.Revenue -
		(+thirdFinancial.input['Trade Debtors'] +
			+thirdFinancial.input.Stock -
			+thirdFinancial.input['Trade Creditors'] -
			+thirdFinancial.input['Deferred Revenue']) /
			+thirdFinancial.input.Revenue;
	const calculatedDeferredRevenueDays =
		(+thirdFinancial.input['Deferred Revenue'] / +thirdFinancial.input.Revenue) * 365;
	const calculatedCashDaysCycle =
		calculatedDebtorsDays +
		calculatedStockDays -
		calculatedCreditorsDays -
		calculatedDeferredRevenueDays;
	return {
		calculatedGrossMargin,
		calculatedDebtorsDays,
		calculatedWorkingCapital,
		calculatedInvestInWorkingCapital,
		calculatedEbitPercentOfRevenue,
		calculatedEbitPercentOfGrossMargin,
		calculatedStockDays,
		calculatedNetProfitBeforeTax,
		calculatedCreditorsDays,
		calculatedMarginalCashFlow,
		calculatedDeferredRevenueDays,
		calculatedCashDaysCycle
	};
}

export function cashFlowProfitabilityCalculator(
	firstFinancial: FinancialsModel,
	secondFinancial: FinancialsModel,
	thirdFinancial: FinancialsModel
): ProfitabilityCalculations {
	const calculatedRevenueGrowthSecondFinancial = secondFinancial
		? ((+secondFinancial.input.Revenue - +firstFinancial.input.Revenue) /
				+firstFinancial.input.Revenue) *
		  100
		: 0;
	const calculatedRevenueGrowthThirdFinancial = thirdFinancial
		? ((+thirdFinancial.input.Revenue - +secondFinancial.input.Revenue) /
				+secondFinancial.input.Revenue) *
		  100
		: 0;
	const calculateCogsFirst = secondFinancial
		? (+secondFinancial.input.COGS / +secondFinancial.input.Revenue) * 100
		: 0;
	const calculatedCogsSecond = thirdFinancial
		? (+thirdFinancial.input.COGS / +thirdFinancial.input.Revenue) * 100
		: 0;
	const secondFinancialMonthEnding = secondFinancial
		? secondFinancial.input['Month Ending']
		: 'January';
	const calculatedGrossMarginFirst = secondFinancial
		? (+secondFinancial.input['Gross Profit'] / +secondFinancial.input.Revenue) * 100
		: 0;
	const calculatedGrossMarginSecond = thirdFinancial
		? (+thirdFinancial.input['Gross Profit'] / +thirdFinancial.input.Revenue) * 100
		: 0;
	console.log(
		'Contribution margin',
		+secondFinancial.input['Gross Profit'],
		+secondFinancial.input['Direct Labour'],
		+secondFinancial.input.Revenue
	);
	const calculatedContributionMarginFirst =
		secondFinancial && +secondFinancial.input.Revenue > 0
			? ((+secondFinancial.input['Gross Profit'] - +secondFinancial.input['Direct Labour']) /
					+secondFinancial.input.Revenue) *
			  100
			: 0;
	const calculatedContributionMarginSecond =
		thirdFinancial && +thirdFinancial.input.Revenue > 0
			? ((+thirdFinancial.input['Gross Profit'] - +thirdFinancial.input['Direct Labour']) /
					+thirdFinancial.input.Revenue) *
			  100
			: 0;
	const calculatedChangeContributionMargin =
		calculatedContributionMarginFirst > 0 && calculatedContributionMarginSecond > 0
			? ((calculatedContributionMarginSecond - calculatedContributionMarginFirst) /
					calculatedContributionMarginFirst) *
			  100
			: 0;
	const calculatedOverheadsFirst = secondFinancial
		? ((+secondFinancial.input['Gross Profit'] - +secondFinancial.input.EBIT) /
				+secondFinancial.input.Revenue) *
		  100
		: 0;
	const calculatedOverheadsSecond = thirdFinancial
		? ((+thirdFinancial.input['Gross Profit'] - +thirdFinancial.input.EBIT) /
				+thirdFinancial.input.Revenue) *
		  100
		: 0;

	const calculatedEbitPercentOfRevenueFirst = secondFinancial
		? (+secondFinancial.input.EBIT / +secondFinancial.input.Revenue) * 100
		: 0;
	const calculatedEbitPercentOfRevenueSecond = thirdFinancial
		? (+thirdFinancial.input.EBIT / +thirdFinancial.input.Revenue) * 100
		: 0;

	const calculatedEbitdaFirst = secondFinancial
		? +secondFinancial.input.EBIT + +secondFinancial.input.Depreciation
		: 0;
	const calculatedEbitdaSecond = thirdFinancial
		? +thirdFinancial.input.EBIT + +thirdFinancial.input.Depreciation
		: 0;
	const calculatedNetProfitAfterTaxFirst = secondFinancial
		? (+secondFinancial.input['Net Profit'] / +secondFinancial.input.Revenue) * 100
		: 0;
	const calculatedNetProfitAfterTaxSecond = thirdFinancial
		? (+thirdFinancial.input['Net Profit'] / +thirdFinancial.input.Revenue) * 100
		: 0;
	const calculatedNetProfitBeforeTaxOfGrossMarginFirst = secondFinancial
		? ((+secondFinancial.input.EBIT -
				+secondFinancial.input['Interest Paid'] +
				+secondFinancial.input['Other Income']) /
				+secondFinancial.input['Gross Profit']) *
		  100
		: 0;
	const calculatedNetProfitBeforeTaxOfGrossMarginSecond = thirdFinancial
		? ((+thirdFinancial.input.EBIT -
				+thirdFinancial.input['Interest Paid'] +
				+thirdFinancial.input['Other Income']) /
				+thirdFinancial.input['Gross Profit']) *
		  100
		: 0;
	const calculatedNetProfitBeforeTaxOfRevenueFirst = secondFinancial
		? ((+secondFinancial.input.EBIT -
				+secondFinancial.input['Interest Paid'] +
				+secondFinancial.input['Other Income']) /
				+secondFinancial.input.Revenue) *
		  100
		: 0;
	const calculatedNetProfitBeforeTaxOfRevenueSecond = thirdFinancial
		? ((+thirdFinancial.input.EBIT -
				+thirdFinancial.input['Interest Paid'] +
				+thirdFinancial.input['Other Income']) /
				+thirdFinancial.input.Revenue) *
		  100
		: 0;
	const calculatedChangeRevenue = thirdFinancial
		? ((+thirdFinancial.input.Revenue - +secondFinancial.input.Revenue) /
				+secondFinancial.input.Revenue) *
		  100
		: 0;

	const calculatedChangeRevenueGrowth =
		((calculatedRevenueGrowthThirdFinancial - calculatedRevenueGrowthSecondFinancial) /
			calculatedRevenueGrowthSecondFinancial) *
		100;

	const calculatedChangeCogs =
		((calculatedCogsSecond - calculateCogsFirst) / calculateCogsFirst) * 100;

	const calculatedChangeGrossMargin =
		((calculatedGrossMarginSecond - calculatedGrossMarginFirst) / calculatedGrossMarginFirst) * 100;

	const calculatedChangeEbitOfRevenue =
		((calculatedEbitPercentOfRevenueSecond - calculatedEbitPercentOfRevenueFirst) /
			calculatedEbitPercentOfRevenueFirst) *
		100;

	const calculatedChangeEbitda =
		((calculatedEbitdaSecond - calculatedEbitdaFirst) / calculatedEbitdaFirst) * 100;

	const calculatedChangeNetProfitOfRevenue =
		((calculatedNetProfitBeforeTaxOfRevenueSecond - calculatedNetProfitBeforeTaxOfRevenueFirst) /
			calculatedNetProfitBeforeTaxOfRevenueFirst) *
		100;

	const calculatedChangeNetProfitOfGrossMargin =
		((calculatedNetProfitBeforeTaxOfGrossMarginSecond -
			calculatedNetProfitBeforeTaxOfGrossMarginFirst) /
			calculatedNetProfitBeforeTaxOfGrossMarginFirst) *
		100;

	const calculatedChangeNetProfitAfterTax =
		((calculatedNetProfitAfterTaxSecond - calculatedNetProfitAfterTaxFirst) /
			calculatedNetProfitAfterTaxFirst) *
		100;

	const calculatedChangeOverheads =
		calculatedOverheadsFirst === 0
			? 0
			: ((calculatedOverheadsSecond - calculatedOverheadsFirst) / calculatedOverheadsFirst) * 100;

	const calculatedCogsGrowthFirst = secondFinancial
		? ((+secondFinancial.input.COGS - +firstFinancial.input.COGS) / +firstFinancial.input.COGS) *
		  100
		: 0;
	const calculatedCogsGrowthSecond = thirdFinancial
		? ((+thirdFinancial.input.COGS - +secondFinancial.input.COGS) / +secondFinancial.input.COGS) *
		  100
		: 0;
	const calculatedCogsGrowthThird =
		((calculatedCogsGrowthSecond - calculatedCogsGrowthFirst) / calculatedCogsGrowthFirst) * 100;

	const calculatedUnknownOverheadsGrowth = firstFinancial
		? ((+firstFinancial.input['Gross Profit'] - +firstFinancial.input.EBIT) /
				+firstFinancial.input.Revenue) *
		  100
		: 0;

	const calculatedOverheadsGrowthFirst =
		((calculatedOverheadsFirst - calculatedUnknownOverheadsGrowth) /
			calculatedUnknownOverheadsGrowth) *
		100;

	const calculatedOverheadsGrowthSecond =
		((calculatedOverheadsSecond - calculatedOverheadsFirst) / calculatedOverheadsSecond) * 100;
	const calculatedOverheadsGrowthSum =
		((calculatedOverheadsGrowthSecond - calculatedOverheadsGrowthFirst) /
			calculatedOverheadsGrowthFirst) *
		100;

	const thirdFinancialMonthEnding = thirdFinancial
		? thirdFinancial.input['Month Ending']
		: 'January';
	const secondFinancialYearEnding = secondFinancial
		? secondFinancial.input['Year Ending']
		: 'January';
	const thirdFinancialYearEnding = thirdFinancial ? thirdFinancial.input['Year Ending'] : 'January';
	const SecondRevenue = secondFinancial ? secondFinancial.input.Revenue : '0';
	const ThirdRevenue = thirdFinancial ? thirdFinancial.input.Revenue : '0';
	const calculatedLerFirst = secondFinancial
		? +secondFinancial.input['Gross Profit'] / +secondFinancial.input['Direct Labour']
		: 0;
	const calculatedLerSecond = thirdFinancial
		? +thirdFinancial.input['Gross Profit'] / +thirdFinancial.input['Direct Labour']
		: 0;
	return {
		calculatedRevenueGrowthSecondFinancial,
		calculatedRevenueGrowthThirdFinancial,
		calculateCogsFirst,
		calculatedCogsSecond,
		secondFinancialMonthEnding,
		secondFinancialYearEnding,
		thirdFinancialYearEnding,
		thirdFinancialMonthEnding,
		SecondRevenue,
		ThirdRevenue,
		calculatedGrossMarginFirst,
		calculatedGrossMarginSecond,
		calculatedContributionMarginFirst,
		calculatedContributionMarginSecond,
		calculatedChangeContributionMargin,
		calculatedOverheadsFirst,
		calculatedOverheadsSecond,
		calculatedEbitPercentOfRevenueFirst,
		calculatedEbitPercentOfRevenueSecond,
		calculatedEbitdaFirst,
		calculatedEbitdaSecond,
		calculatedNetProfitAfterTaxFirst,
		calculatedNetProfitAfterTaxSecond,
		calculatedNetProfitBeforeTaxOfGrossMarginFirst,
		calculatedNetProfitBeforeTaxOfGrossMarginSecond,
		calculatedNetProfitBeforeTaxOfRevenueSecond,
		calculatedNetProfitBeforeTaxOfRevenueFirst,
		calculatedChangeRevenue,
		calculatedChangeRevenueGrowth,
		calculatedChangeCogs,
		calculatedChangeGrossMargin,
		calculatedChangeEbitOfRevenue,
		calculatedChangeEbitda,
		calculatedChangeNetProfitOfRevenue,
		calculatedChangeNetProfitOfGrossMargin,
		calculatedChangeNetProfitAfterTax,
		calculatedChangeOverheads,
		calculatedCogsGrowthFirst,
		calculatedCogsGrowthSecond,
		calculatedCogsGrowthThird,
		calculatedOverheadsGrowthFirst,
		calculatedOverheadsGrowthSecond,
		calculatedOverheadsGrowthSum,
		calculatedLerFirst,
		calculatedLerSecond
	};
}

export default cashFlowAnalysisCalculations;
