/* eslint-disable react/destructuring-assignment */
import type { ReactNode } from 'react';
import type React from 'react';
import { createContext, useEffect, useState } from 'react';
import { useSelector } from 'react-redux';

import type { RootState } from '../../../ReduxState/store';
import type { CompanyDbModel } from '../../../Pages/Companies/Components/CompaniesComponents.helper';
import type { FinancialsModel } from '../../../Pages/Financials/Components/FinancialsForm/FinancialsForm.helper';
import getCompanyType from '../../../utils/getCompanyType';

export type CashFlowMetricModel = {
	debtorsDay: string;
	debtorsDaySecond: string;
	debtorsDayChange: string;
	creditorsDay: string;
	creditorsDaySecond: string;
	creditorsDayChange: string;
	workingCapitalDays: string;
	workingCapitalDaysSecond: string;
	workingCapitalDaysChange: string;
	changeInWorkingCapital: string;
	workingCapitalPercent: string;
	workingCapitalPercentSecond: string;
	workingCapitalPercentChange: string;
	marginalCashFlow: string;
	marginalCashFlowSecond: string;
	marginalCashFlowChange: string;
	currentRatio: string;
	currentRatioSecond: string;
	currentRatioChange: string;
	grossMarginForNextPoundSale: string;
	grossMarginForNextPoundSaleSecond: string;
	yourGap: string;
	yourGapSecond: string;
	wipDaysFirst: string;
	wipDaysSecond: string;
	wipDaysChange: string;
	deferredRevenueDays: string;
	deferredRevenueDaysSecond: string;
	deferredRevenueDaysChange: string;
	workingCapital: string;
	workingCapitalSecond: string;
	workingCapitalChange: string;
	firstYear: string;
	secondYear: string;
	thirdYear: string;
	firstMonth: string;
	secondMonth: string;
	thirdMonth: string;
	assignFinancialsHandler: (f1: FinancialsModel, f2: FinancialsModel, f3: FinancialsModel) => void;
};

export const CashFlowMetricContext: React.Context<CashFlowMetricModel> =
	createContext<CashFlowMetricModel>({
		debtorsDay: '',
		debtorsDaySecond: '',
		debtorsDayChange: '',
		creditorsDay: '',
		creditorsDaySecond: '',
		creditorsDayChange: '',
		workingCapitalDays: '',
		workingCapitalDaysSecond: '',
		workingCapitalDaysChange: '',
		changeInWorkingCapital: '',
		workingCapitalPercent: '',
		workingCapitalPercentSecond: '',
		workingCapitalPercentChange: '',
		marginalCashFlow: '',
		marginalCashFlowSecond: '',
		marginalCashFlowChange: '',
		currentRatio: '',
		currentRatioSecond: '',
		currentRatioChange: '',
		grossMarginForNextPoundSale: '',
		grossMarginForNextPoundSaleSecond: '',
		yourGap: '',
		yourGapSecond: '',
		wipDaysFirst: '',
		wipDaysSecond: '',
		wipDaysChange: '',
		deferredRevenueDays: '',
		deferredRevenueDaysSecond: '',
		deferredRevenueDaysChange: '',
		workingCapital: '',
		workingCapitalSecond: '',
		workingCapitalChange: '',
		firstYear: '',
		secondYear: '',
		thirdYear: '',
		firstMonth: '',
		secondMonth: '',
		thirdMonth: '',
		assignFinancialsHandler: (): void => {}
	});

const CashFlowMetricContextProvider: React.FC<{ children: ReactNode }> = (props: {
	children: ReactNode;
}) => {
	/** NEW start */
	const selectedCompany = useSelector(
		(state: RootState): CompanyDbModel | null => state.companies.selectedCompany
	);
	const selectedFinancials = useSelector(
		(state: RootState): FinancialsModel[] | null => state.financials.selectedFinancials
	);
	const companyType = getCompanyType(selectedCompany);
	/** NEW end */
	const [debtorsDay, setDebtorsDay] = useState<string>('');
	const [debtorsDaySecond, setDebtorsDaySecond] = useState<string>('');
	const [debtorsDayChange, setDebtorsDayChange] = useState<string>('');
	const [creditorsDay, setCreditorsDay] = useState<string>('');
	const [creditorsDaySecond, setCreditorsDaySecond] = useState<string>('');
	const [creditorsDayChange, setCreditorsDayChange] = useState<string>('');
	const [workingCapitalDays, setWorkingCapitalDays] = useState<string>('');
	const [workingCapitalDaysSecond, setWorkingCapitalDaysSecond] = useState<string>('');
	const [workingCapitalDaysChange, setWorkingCapitalDaysChange] = useState<string>('');
	const [changeInWorkingCapital, setChangeInWorkingCapital] = useState<string>('');
	const [workingCapital, setWorkingCapital] = useState<string>('');
	const [workingCapitalSecond, setWorkingCapitalSecond] = useState<string>('');
	const [workingCapitalChange, setWorkingCapitalChange] = useState<string>('');
	const [workingCapitalPercent, setWorkingCapitalPercent] = useState<string>('');
	const [workingCapitalPercentSecond, setWorkingCapitalPercentSecond] = useState<string>('');
	const [workingCapitalPercentChange, setWorkingCapitalPercentChange] = useState<string>('');
	const [marginalCashFlow, setMarginalCashFlow] = useState<string>('');
	const [marginalCashFlowSecond, setMarginalCashFlowSecond] = useState<string>('');
	const [marginalCashFlowChange, setMarginalCashFlowChange] = useState<string>('');
	const [currentRatio, setCurrentRatio] = useState<string>('');
	const [currentRatioSecond, setCurrentRatioSecond] = useState<string>('');
	const [currentRatioChange, setCurrentRatioChange] = useState<string>('');
	const [grossMarginForNextPoundSale, setGrossMarginForNextPoundSale] = useState<string>('');
	const [grossMarginForNextPoundSaleSecond, setGrossMarginForNextPoundSaleSecond] =
		useState<string>('');
	const [yourGap, setYourGap] = useState<string>('');
	const [yourGapSecond, setYourGapSecond] = useState<string>('');
	const [wipDaysFirst, setWipDaysFirst] = useState<string>('');
	const [wipDaysSecond, setWipDaysSecond] = useState<string>('');
	const [wipDaysChange, setWipDaysChange] = useState<string>('');
	const [deferredRevenueDays, setDeferredRevenueDays] = useState<string>('');
	const [deferredRevenueDaysSecond, setDeferredRevenueDaysSecond] = useState<string>('');
	const [deferredRevenueDaysChange, setDeferredRevenueDaysChange] = useState<string>('');
	const [firstYear, setFirstYear] = useState<string>('');
	const [secondYear, setSecondYear] = useState<string>('');
	const [thirdYear, setThirdYear] = useState<string>('');
	const [firstMonth, setFirstMonth] = useState<string>('');
	const [secondMonth, setSecondMonth] = useState<string>('');
	const [thirdMonth, setThirdMonth] = useState<string>('');

	function cashFlowMetricCalculations(): void {
		// if (!selectedFinancials || selectedFinancials.length < 3) {
		if (!selectedFinancials) {
			return;
		}

		// const firstFinancial: FinancialsModel = JSON.parse(
		// 	localStorage.getItem('first-financial') as string
		// );
		// const secondFinancial: FinancialsModel = JSON.parse(
		// 	localStorage.getItem('second-financial') as string
		// );
		// const thirdFinancial: FinancialsModel = JSON.parse(
		// 	localStorage.getItem('third-financial') as string
		// );
		const firstFinancial: FinancialsModel = selectedFinancials[0];
		const secondFinancial: FinancialsModel | null = selectedFinancials[1];
		// const thirdFinancial: FinancialsModel | null = selectedFinancials[2] ? selectedFinancials[2] : null;
		const thirdFinancial: FinancialsModel | null = selectedFinancials[2];
		console.log('FIN', firstFinancial, secondFinancial, thirdFinancial);
		const calculatedDebtorsDay =
			(+secondFinancial.input['Trade Debtors'] / +secondFinancial.input.Revenue) * 365;
		const calculatedDebtorsDaySecond =
			(+thirdFinancial.input['Trade Debtors'] / +thirdFinancial.input.Revenue) * 365;
		const calculatedDebtorsDayChange =
			calculatedDebtorsDay === 0
				? 0
				: ((calculatedDebtorsDaySecond - calculatedDebtorsDay) / calculatedDebtorsDay) * 100;

		const calculatedWipDaysFirst =
			companyType === 'All Other'
				? (+secondFinancial.input.Stock / +secondFinancial.input.COGS) * 365
				: (+secondFinancial.input.Stock / +secondFinancial.input.Revenue) * 365;

		const calculatedWipDaysSecond =
			companyType === 'All Other'
				? (+thirdFinancial.input.Stock / +thirdFinancial.input.COGS) * 365
				: (+thirdFinancial.input.Stock / +thirdFinancial.input.Revenue) * 365;
		console.log('Debtors', calculatedWipDaysSecond, calculatedWipDaysFirst, calculatedWipDaysFirst);
		const calculatedWipDaysChange =
			calculatedWipDaysSecond === 0 || calculatedWipDaysFirst === 0
				? 0
				: ((calculatedWipDaysSecond - calculatedWipDaysFirst) / calculatedWipDaysFirst) * 100;

		const calculatedCreditorsDay =
			(+secondFinancial.input['Trade Creditors'] / +secondFinancial.input.COGS) * 365;
		const calculatedCreditorsDaySecond =
			(+thirdFinancial.input['Trade Creditors'] / +thirdFinancial.input.COGS) * 365;
		const calculatedCreditorsDayChange =
			((calculatedCreditorsDaySecond - calculatedCreditorsDay) / calculatedCreditorsDay) * 100;

		const calculatedDeferredRevenueDays =
			(+secondFinancial.input['Deferred Revenue'] / +secondFinancial.input.Revenue) * 365;
		const calculatedDeferredRevenueDaysSecond =
			(+thirdFinancial.input['Deferred Revenue'] / +thirdFinancial.input.Revenue) * 365;

		const calculatedDeferredRevenueDaysChange =
			((calculatedDeferredRevenueDaysSecond - calculatedDeferredRevenueDays) /
				calculatedDeferredRevenueDays) *
			100;

		// =B6+B7-B8-B9
		const calculatedWorkingCapitalDays =
			calculatedDebtorsDay +
			calculatedWipDaysFirst -
			calculatedCreditorsDay -
			calculatedDeferredRevenueDays;

		const calculatedWorkingCapitalDaysSecond =
			calculatedDebtorsDaySecond +
			calculatedWipDaysSecond -
			calculatedCreditorsDaySecond +
			calculatedDeferredRevenueDaysSecond;

		const calculatedWorkingCapitalDaysChange =
			((calculatedWorkingCapitalDaysSecond - calculatedWorkingCapitalDays) /
				calculatedWorkingCapitalDays) *
			100;

		const calculatedWorkingCapital =
			+secondFinancial.input['Trade Debtors'] +
			+secondFinancial.input.Stock -
			+secondFinancial.input['Trade Creditors'] -
			+secondFinancial.input['Deferred Revenue'];

		const calculatedWorkingCapitalSecond =
			+thirdFinancial.input['Trade Debtors'] +
			+thirdFinancial.input.Stock -
			+thirdFinancial.input['Trade Creditors'] -
			+thirdFinancial.input['Deferred Revenue'];

		const calculatedWorkingCapitalSecondPrc =
			(+thirdFinancial.input['Trade Debtors'] +
				+thirdFinancial.input.Stock -
				+thirdFinancial.input['Trade Creditors'] -
				+thirdFinancial.input['Deferred Revenue']) /
			+thirdFinancial.input.Revenue;

		console.log('Working Capital second percentage', calculatedWorkingCapitalSecondPrc);

		const calculatedWorkingCapitalChange =
			((calculatedWorkingCapitalSecond - calculatedWorkingCapital) / calculatedWorkingCapital) *
			100;

		const calculatedWorkingCapitalPercent =
			(+calculatedWorkingCapital / +secondFinancial.input.Revenue) * 100;

		const calculatedWorkingCapitalPercentSecond =
			(+calculatedWorkingCapitalSecond / +thirdFinancial.input.Revenue) * 100;

		const calculatedWorkingCapitalPercentChange =
			((+calculatedWorkingCapitalPercentSecond - +calculatedWorkingCapitalPercent) /
				+calculatedWorkingCapitalPercent) *
			100;

		const calculatedMarginalCashFlow =
			+secondFinancial.input['Gross Profit'] / +secondFinancial.input.Revenue -
			(+secondFinancial.input['Trade Debtors'] +
				+secondFinancial.input.Stock -
				+secondFinancial.input['Trade Creditors'] -
				+secondFinancial.input['Deferred Revenue']) /
				+secondFinancial.input.Revenue;
		const calculatedMarginalCashFlowSecond =
			+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 calculatedMarginalCashFlowChange =
			((calculatedMarginalCashFlowSecond - calculatedMarginalCashFlow) /
				calculatedMarginalCashFlow) *
			100;

		const calculatedCurrentRatio =
			+secondFinancial.input['Additional Total Current Assets'] /
			+secondFinancial.input['Additional Total Current Liabilities'];
		const calculatedCurrentRatioSecond =
			+thirdFinancial.input['Additional Total Current Assets'] /
			+thirdFinancial.input['Additional Total Current Liabilities'];
		const calculatedCurrentRatioChange =
			((calculatedCurrentRatioSecond - calculatedCurrentRatio) / calculatedCurrentRatio) * 100;

		const calculatedGrossMarginForNextPoundSale =
			(+secondFinancial.input['Gross Profit'] / +secondFinancial.input.Revenue) * 100;
		const calculatedGrossMarginForNextPoundSaleSecond =
			(+thirdFinancial.input['Gross Profit'] / +thirdFinancial.input.Revenue) * 100;

		const calculatedYourGap =
			calculatedWorkingCapitalPercent - calculatedGrossMarginForNextPoundSale;
		const calculatedYourGapSecond =
			calculatedWorkingCapitalPercentSecond - calculatedGrossMarginForNextPoundSaleSecond;

		const calculatedChangeInWorkingCapital =
			(calculatedWorkingCapitalSecond / calculatedWorkingCapitalDaysSecond) *
			calculatedWorkingCapitalDays;

		console.log(
			'calculatedChangeInWorkingCapital',
			calculatedChangeInWorkingCapital,
			'calculatedWorkingCapitalDaysSecond',
			calculatedWorkingCapitalDaysSecond,
			'calculatedWorkingCapitalDaysSecond',
			calculatedWorkingCapitalDaysSecond
		);

		setDebtorsDay(calculatedDebtorsDay.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,'));
		setDebtorsDaySecond(
			calculatedDebtorsDaySecond.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
		);
		setDebtorsDayChange(
			calculatedDebtorsDayChange.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
		);
		setCreditorsDay(calculatedCreditorsDay.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,'));
		setCreditorsDaySecond(
			calculatedCreditorsDaySecond.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
		);
		setCreditorsDayChange(
			calculatedCreditorsDayChange.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
		);
		setWorkingCapitalDays(calculatedWorkingCapitalDays.toFixed(2));
		setWorkingCapitalDaysSecond(
			calculatedWorkingCapitalDaysSecond.toFixed(0).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
		);
		setWorkingCapitalDaysChange(calculatedWorkingCapitalDaysChange.toFixed(2));
		setChangeInWorkingCapital(
			calculatedChangeInWorkingCapital.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
		);
		setWorkingCapital(calculatedWorkingCapital.toFixed(0));
		setWorkingCapitalSecond(
			// calculatedWorkingCapitalSecond.toFixed(0).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
			calculatedWorkingCapitalSecond.toFixed(0)
		);
		setWorkingCapitalChange(
			calculatedWorkingCapitalChange.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
		);

		setWorkingCapitalPercent(
			calculatedWorkingCapitalPercent.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
		);
		setWorkingCapitalPercentSecond(
			calculatedWorkingCapitalPercentSecond.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
		);
		setWorkingCapitalPercentChange(
			calculatedWorkingCapitalPercentChange.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
		);
		setMarginalCashFlow(
			calculatedMarginalCashFlow.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
		);
		setMarginalCashFlowSecond(
			calculatedMarginalCashFlowSecond.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
		);
		setMarginalCashFlowChange(
			calculatedMarginalCashFlowChange.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
		);
		setCurrentRatio(calculatedCurrentRatio.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,'));
		setCurrentRatioSecond(
			calculatedCurrentRatioSecond.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
		);
		setCurrentRatioChange(
			calculatedCurrentRatioChange.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
		);
		setGrossMarginForNextPoundSale(calculatedGrossMarginForNextPoundSale.toFixed(2).toString());
		setGrossMarginForNextPoundSaleSecond(
			calculatedGrossMarginForNextPoundSaleSecond.toFixed(2).toString()
		);
		setYourGap(calculatedYourGap.toFixed(2).toString());
		setYourGapSecond(calculatedYourGapSecond.toFixed(2).toString());
		setWipDaysFirst(calculatedWipDaysFirst.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,'));
		setWipDaysSecond(calculatedWipDaysSecond.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,'));
		setWipDaysChange(calculatedWipDaysChange.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,'));
		setDeferredRevenueDays(
			calculatedDeferredRevenueDays.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
		);
		setDeferredRevenueDaysSecond(
			calculatedDeferredRevenueDaysSecond.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
		);
		setDeferredRevenueDaysChange(
			calculatedDeferredRevenueDaysChange.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,')
		);
		setFirstYear(firstFinancial.input['Year Ending']);
		setSecondYear(secondFinancial.input['Year Ending']);
		setThirdYear(thirdFinancial.input['Year Ending']);
		setFirstMonth(firstFinancial.input['Month Ending']);
		setSecondMonth(secondFinancial.input['Month Ending']);
		setThirdMonth(thirdFinancial.input['Month Ending']);
	}

	function assignFinancialsHandler(
		firstFinancial: FinancialsModel,
		secondFinancial: FinancialsModel,
		thirdFinancial: FinancialsModel
	) {
		console.log('ENTERED', firstFinancial, secondFinancial, thirdFinancial);
		if (
			firstFinancial &&
			secondFinancial &&
			thirdFinancial &&
			firstFinancial.input !== undefined &&
			secondFinancial.input !== undefined &&
			thirdFinancial.input !== undefined
		) {
			cashFlowMetricCalculations();
		}
	}

	useEffect(() => {
		// const firstFinancial: FinancialsModel = JSON.parse(
		// 	localStorage.getItem('first-financial') as string
		// );
		// const secondFinancial: FinancialsModel = JSON.parse(
		// 	localStorage.getItem('second-financial') as string
		// );
		// const thirdFinancial: FinancialsModel = JSON.parse(
		// 	localStorage.getItem('third-financial') as string
		// );
		// if (!selectedFinancials || selectedFinancials.length < 3) {
		if (!selectedFinancials) {
			return;
		}
		const firstFinancial: FinancialsModel = selectedFinancials[0];
		const secondFinancial: FinancialsModel = selectedFinancials[1];
		const thirdFinancial: FinancialsModel = selectedFinancials[2];

		assignFinancialsHandler(firstFinancial, secondFinancial, thirdFinancial);
		window.scrollTo(0, 0);
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [selectedFinancials]);

	// eslint-disable-next-line react/jsx-no-constructed-context-values
	const contextValue = {
		debtorsDay,
		debtorsDaySecond,
		debtorsDayChange,
		creditorsDay,
		creditorsDaySecond,
		creditorsDayChange,
		workingCapitalDays,
		workingCapitalDaysSecond,
		workingCapitalDaysChange,
		workingCapitalPercent,
		workingCapitalPercentSecond,
		workingCapitalPercentChange,
		marginalCashFlow,
		marginalCashFlowSecond,
		marginalCashFlowChange,
		currentRatio,
		currentRatioSecond,
		currentRatioChange,
		grossMarginForNextPoundSale,
		grossMarginForNextPoundSaleSecond,
		yourGap,
		yourGapSecond,
		wipDaysFirst,
		wipDaysSecond,
		wipDaysChange,
		deferredRevenueDays,
		deferredRevenueDaysSecond,
		deferredRevenueDaysChange,
		workingCapital,
		workingCapitalSecond,
		workingCapitalChange,
		firstYear,
		secondYear,
		thirdYear,
		firstMonth,
		secondMonth,
		thirdMonth,
		changeInWorkingCapital,
		assignFinancialsHandler
	};
	// if (!selectedFinancials || selectedFinancials.length < 3) {
	// 	return <div>Please selected minimum of 3 financial periods</div>;
	// }
	return (
		<CashFlowMetricContext.Provider value={contextValue}>
			{props.children}
		</CashFlowMetricContext.Provider>
	);
};

export default CashFlowMetricContextProvider;
