/* eslint-disable react/destructuring-assignment */
import type { SelectChangeEvent } from '@mui/material/Select';
import axios from 'axios';
import { createContext, useCallback, useDeferredValue, useReducer, useState } from 'react';
import type React from 'react';
import type { ChangeEvent, ChangeEventHandler, FormEvent, ReactNode } from 'react';
import { useDispatch, useSelector } from 'react-redux';

import environment from '../../Environments/environment';
import type { CompanyDbModel } from '../../Pages/Companies/Components/CompaniesComponents.helper';
import type { FinancialsModel } from '../../Pages/Financials/Components/FinancialsForm/FinancialsForm.helper';
import styles from '../../Pages/Financials/Components/FinancialsForm/FinancialsForm.module.scss';
// import { GlobalStateContext } from '../global/GlobalState-context';
// import type { GlobalStateModel } from '../global/GlobalState-context';
import {
	insertFinancialsData,
	patchFinancialsData
} from '../../ReduxState/financials/financialsSlice';
import type { AppDispatch, RootState } from '../../ReduxState/store';
import financialsFormContextHelper, {
	emptyErrorMessageObject,
	FinancialsFormDefault,
	FinancialsFormDefaultValues
} from './financials-form-context-helper';
import type {
	Action,
	ErrorMessageInterface,
	FinancialsFormInterface,
	FinancialsTypeContextModel
} from './financials-form-context-helper';
import StateManagedSelect from 'react-select';

export const FinancialsFormContext: React.Context<FinancialsTypeContextModel> =
	createContext<FinancialsTypeContextModel>(FinancialsFormDefaultValues);

const FinancialsFormProvider: React.FC<{ children: ReactNode }> = (props: {
	children: ReactNode;
}) => {
	const initialState: FinancialsFormInterface = FinancialsFormDefault;
	const [formSendSuccessfully, setFormSendSuccessfully] = useState<boolean>(false);
	/** NEW */
	const dispatch = useDispatch<AppDispatch>();
	const selectedCompany = useSelector(
		(state: RootState): CompanyDbModel | null => state.companies.selectedCompany
	);
	const editFinancialtemId = useSelector(
		(state: RootState): FinancialsModel[] | null => state.financials.editFinancialtemId
	);
	/** NEW end */

	function reducerHandler(state: FinancialsFormInterface, action: Action) {
		return financialsFormContextHelper(state, action, initialState);
	}

	const [formInputs, dispatchFinancialsInputs] = useReducer(reducerHandler, initialState);
	const {
		bankLoansCurrent,
		bankLoansNonCurrent,
		fixedAssets,
		totalAssets,
		totalCurrentAssets,
		totalCurrentLiabilities,
		totalLiabilities,
		BanksLendEBITDAMultiplierMax,
		BanksLendEBITDAMultiplierMin,
		COGS,
		CashAtBank,
		Depreciation,
		Dividends,
		EBIT,
		GrossProfit,
		DirectLabour,
		IncreaseRevenueBy,
		InterestPaid,
		MonthEnding,
		MonthStart,
		NetProfit,
		OtherIncome,
		Revenue,
		Stock,
		TradeCreditors,
		TradeDebtors,
		YearEnding,
		YearStart,
		companyId,
		financialsId,
		deferredRevenue
	} = formInputs;
	const [generateNewFinancialId, setGenerateNewFinancialId] = useState<boolean>(false);
	// const globalContext: GlobalStateModel = useContext<GlobalStateModel>(GlobalStateContext);
	const [switchToForm, setSwitchToForm] = useState<boolean>(false);
	const deferredSelectedCompany: CompanyDbModel = useDeferredValue(
		JSON.parse(localStorage.getItem('selected-company') as string)
	);

	const months = [
		'January',
		'February',
		'March',
		'April',
		'May',
		'June',
		'July',
		'August',
		'September',
		'October',
		'November',
		'December'
	];

	function getFirstMonthHandler(event: SelectChangeEvent): void {
		dispatchFinancialsInputs({
			type: 'FIRST_MONTH',
			value: event.target.value
		});

		setErrorMessage((prevState) => ({
			...prevState,
			errorMonthStart: ''
		}));

		// make sure the month is always one month behind
		const currentIndex = months.indexOf(event.target.value);
		dispatchFinancialsInputs({
			type: 'LAST_MONTH',
			value: currentIndex > 0 ? months[currentIndex - 1] : 'December'
		});
	}

	function getFirstYearHandler(event: SelectChangeEvent): void {
		dispatchFinancialsInputs({
			type: 'FIRST_YEAR',
			value: event.target.value
		});

		setErrorMessage((prevState) => ({
			...prevState,
			errorYearStart: ''
		}));

		// make sure the year is always exactly 1 year apart
		const firstMonth = document.getElementById('firstMonth')?.textContent;
		const secondYear = firstMonth === 'January' ? +event.target.value : +event.target.value + 1;
		dispatchFinancialsInputs({
			type: 'LAST_YEAR',
			value: secondYear
		});
	}

	function getLastYearHandler(event: SelectChangeEvent): void {
		dispatchFinancialsInputs({
			type: 'LAST_YEAR',
			value: event.target.value
		});

		setErrorMessage((prevState) => ({
			...prevState,
			errorYearEnding: ''
		}));

		// make sure the year is always exactly 1 year apart
		const secondMonth = document.getElementById('firstMonth')?.textContent;
		const firstYear = secondMonth === 'Decembar' ? +event.target.value : +event.target.value - 1;
		dispatchFinancialsInputs({
			type: 'FIRST_YEAR',
			value: +event.target.value - 1
		});
	}

	function getLastMonthHandler(event: SelectChangeEvent): void {
		dispatchFinancialsInputs({
			type: 'LAST_MONTH',
			value: event.target.value
		});

		setErrorMessage((prevState) => ({
			...prevState,
			errorMonthEnding: ''
		}));

		// make sure the month is always one month ahead
		const currentIndex = months.indexOf(event.target.value);
		dispatchFinancialsInputs({
			type: 'FIRST_MONTH',
			value: currentIndex > 11 ? months[currentIndex + 1] : 'January'
		});
	}

	function getRevenueHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'REVENUE',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorRevenue: '' }));
	}

	// Sanitization function
	const sanitizeNumberInput = (value: string) => {
		// Remove all characters except digits, minus sign, and decimal point
		const sanitized = value.replace(/[^-0-9]/g, '');

		console.log('sanitized inside', sanitized);
		// // Handle multiple decimals or minus signs
		// const parts = sanitized.split('.');
		// // Keep only the first decimal point
		// const integerPart = parts.shift();
		// const decimalPart = parts.join('');
		// const cleanedDecimal = decimalPart.replace(/\./g, '');

		// // For minus sign, only allow at the beginning
		// const minusSign = integerPart?.startsWith('-') ? '-' : '';

		// // Remove minus sign from number part
		// const numberPart = integerPart?.replace(/-/g, '');

		// // Reassemble
		// return `${minusSign}${numberPart}${cleanedDecimal ? '.' + cleanedDecimal : ''}`;
		return sanitized;
	};

	// Handler wrapper
	const handleSanitizedChange = (
		originalHandler: (event: ChangeEvent<HTMLInputElement>) => void
	): ChangeEventHandler<HTMLInputElement> | undefined => {
		console.log('HERE WE ARE');
		return (event: any) => {
			const rawValue = event.target.value;
			const sanitizedValue = sanitizeNumberInput(rawValue);
			console.log('sanitizedValue', sanitizedValue);
			// Optionally, format as currency here if needed
			originalHandler({ ...event, target: { ...event.target, value: sanitizedValue } });
		};
	};

	function getCogsHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'COGS',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorCogs: '' }));
	}

	function getGrossProfitHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'GROSS_PROFIT',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorGrossProfit: '' }));
	}

	function getDirectLabourHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'DIRECT_LABOUR',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorDirectLabour: '' }));
	}

	function getEbitHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'EBIT',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorEbit: '' }));
	}

	function getNetProfitHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'NET_PROFIT',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorNetProfit: '' }));
	}

	function getDepreciationAmortisationHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'DEPRECIATION',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorDepreciation: '' }));
	}

	function getInterestPaidHandler(event: ChangeEvent<HTMLInputElement>): void {
		console.log('interest paid ', event.target.value);
		dispatchFinancialsInputs({
			type: 'INTEREST_PAID',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorInterestPaid: '' }));
	}

	function getOtherIncomeHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'OTHER_INCOME',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorOtherIncome: '' }));
	}

	function getDividendsHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'DIVIDENDS',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorDividends: '' }));
	}

	function getCashInBankHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'CASH_IN_BANK',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorCashAtBank: '' }));
	}

	function getTradeDebtorsHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'TRADE_DEBTORS',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorTradeDebtors: '' }));
	}

	function getStockDaysWIPHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'STOCK_DAYS_WIP',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorStock: '' }));
	}

	function getTotalCurrentAssetsHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'TOTAL_CURRENT_ASSETS',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorTotalCurrentAssets: '' }));
	}

	function getFixedAssetsHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'FIXED_ASSETS',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorFixedAssets: '' }));
	}

	function getTotalAssetsHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'TOTAL_ASSETS',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorTotalAssets: '' }));
	}

	function getTradeCreditorsHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'TRADE_CREDITORS',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorTradeCreditors: '' }));
	}

	function getDeferredRevenueHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'DEFERRED_REVENUE',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorDeferredRevenue: '' }));
	}

	function getTotalCurrentLiabilitiesHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'TOTAL_CURRENT_LIABILITIES',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorTotalCurrentLiabilities: '' }));
	}

	function getTotalLiabilitiesHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'TOTAL_LIABILITIES',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorTotalLiabilities: '' }));
	}

	function getBankLoansCurrentHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'BANK_LOANS_CURRENT',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorBankLoansCurrent: '' }));
	}

	function getBankLoansNonCurrentHandler(event: ChangeEvent<HTMLInputElement>): void {
		dispatchFinancialsInputs({
			type: 'BANK_LOANS_NON_CURRENT',
			value: event.target.value === '-' || event.target.value === '0-' ? '-' : +event.target.value
		});
		setErrorMessage((prevState) => ({ ...prevState, errorBankLoansNonCurrent: '' }));
	}

	function getIncreaseRevenueByHandler(event: ChangeEvent<HTMLInputElement>): void {
		console.log(event.target.value);
		if (event) {
			dispatchFinancialsInputs({
				type: 'INCREASE_REVENUE',
				value: +event.target.value
			});
		} else {
			dispatchFinancialsInputs({
				type: 'INCREASE_REVENUE',
				value: 100
			});
		}
		setErrorMessage((prevState) => ({ ...prevState, errorIncreaseRevenueBy: '' }));
	}

	function getCompanyIdHandler(event: string): void {
		dispatchFinancialsInputs({
			type: 'COMPANY_ID_FINANCIALS',
			value: event
		});
	}

	// original method that would allow for negative numbers, has issue when you add minus it turns instantly into NaN
	// function handleInputData(event: ChangeEvent<HTMLInputElement>): void {
	// 	console.log('event', event, 'event value', event.target.value);
	// 	if (event.type === 'focus') {
	// 		const cleanedValue = event.target.value.toString().replace(/[^0-9.-]+/g, '');
	// 		event.target.value = parseFloat(cleanedValue) ? parseFloat(cleanedValue).toString() : '';
	// 	} else if (event.type === 'blur') {
	// 		setTimeout(() => {
	// 			event.target.value = new Intl.NumberFormat('en-GB', {
	// 				style: 'currency',
	// 				currency:
	// 					typeof selectedCompany?.currency_symbol === 'string'
	// 						? selectedCompany?.currency_symbol
	// 						: selectedCompany?.currency_symbol.value
	// 			}).format(+event.target.value);
	// 		}, 20);
	// 	}
	// }

	function handleInputData(event: ChangeEvent<HTMLInputElement>): void {
		console.log('event', event, 'event value', event.target.value);
		if (event.type === 'focus') {
			console.log('original value', event.target.value.toString());
			const cleanedValue = event.target.value.toString().replace(/[^0-9.-]+/g, '');
			console.log('cleanedValue', cleanedValue);
			if (cleanedValue === '-') {
				event.target.value = '-';
			} else {
				event.target.value = parseFloat(cleanedValue) ? parseFloat(cleanedValue).toString() : '';
			}
		} else if (event.type === 'blur') {
			setTimeout(() => {
				event.target.value = new Intl.NumberFormat('en-GB', {
					style: 'currency',
					currency:
						typeof selectedCompany?.currency_symbol === 'string'
							? selectedCompany?.currency_symbol
							: selectedCompany?.currency_symbol.value,
					minimumFractionDigits: 0,
					maximumFractionDigits: 0
				}).format(event.target.value === '-' ? 0 : +event.target.value);
			}, 20);
		}
	}

	function incrementHandler(event: FormEvent<Element>): void {
		const elementInput = event.currentTarget.parentElement?.children
			.item(2)
			?.children.item(0) as HTMLInputElement;
		console.log('elementInput', elementInput);
		switch (elementInput?.id) {
			case 'Revenue':
				return dispatchFinancialsInputs({
					type: 'REVENUE',
					value: Math.ceil(+Revenue + 0.01)
				});
			case 'COGS':
				return dispatchFinancialsInputs({
					type: 'COGS',
					value: Math.ceil(+COGS + 0.01)
				});
			case 'GROSS_PROFIT':
				return dispatchFinancialsInputs({
					type: 'GROSS_PROFIT',
					value: Math.ceil(+GrossProfit + 0.1)
				});
			case 'DIRECT_LABOUR':
				return dispatchFinancialsInputs({
					type: 'DIRECT_LABOUR',
					value: Math.ceil(+DirectLabour + 0.1)
				});
			case 'EBIT':
				return dispatchFinancialsInputs({
					type: 'EBIT',
					value: Math.ceil(+EBIT + 0.1)
				});
			case 'NET_PROFIT':
				return dispatchFinancialsInputs({
					type: 'NET_PROFIT',
					value: Math.ceil(+NetProfit + 0.1)
				});
			case 'DEPRECIATION':
				return dispatchFinancialsInputs({
					type: 'DEPRECIATION',
					value: Math.ceil(+Depreciation + 0.1)
				});
			case 'INTEREST_PAID':
				return dispatchFinancialsInputs({
					type: 'INTEREST_PAID',
					value: Math.ceil(+InterestPaid + 0.1)
				});
			case 'OTHER_INCOME':
				return dispatchFinancialsInputs({
					type: 'OTHER_INCOME',
					value: Math.ceil(+OtherIncome + 0.1)
				});
			case 'DIVIDENDS':
				return dispatchFinancialsInputs({
					type: 'DIVIDENDS',
					value: Math.ceil(+Dividends + 0.1)
				});
			case 'CASH_IN_BANK':
				return dispatchFinancialsInputs({
					type: 'CASH_IN_BANK',
					value: Math.ceil(+CashAtBank + 0.1)
				});
			case 'TRADE_DEBTORS':
				return dispatchFinancialsInputs({
					type: 'TRADE_DEBTORS',
					value: Math.ceil(+TradeDebtors + 0.1)
				});
			case 'STOCK_DAYS_WIP':
				return dispatchFinancialsInputs({
					type: 'STOCK_DAYS_WIP',
					value: Math.ceil(+Stock + 0.1)
				});
			case 'DEFERRED_REVENUE':
				return dispatchFinancialsInputs({
					type: 'DEFERRED_REVENUE',
					value: Math.ceil(+deferredRevenue + 0.1)
				});
			case 'TOTAL_CURRENT_ASSETS':
				return dispatchFinancialsInputs({
					type: 'TOTAL_CURRENT_ASSETS',
					value: Math.ceil(+totalCurrentAssets + 0.1)
				});
			case 'FIXED_ASSETS':
				return dispatchFinancialsInputs({
					type: 'FIXED_ASSETS',
					value: Math.ceil(+fixedAssets + 0.1)
				});
			case 'TOTAL_ASSETS':
				return dispatchFinancialsInputs({
					type: 'TOTAL_ASSETS',
					value: Math.ceil(+totalAssets + 0.1)
				});
			case 'TRADE_CREDITORS':
				return dispatchFinancialsInputs({
					type: 'TRADE_CREDITORS',
					value: Math.ceil(+TradeCreditors + 0.1)
				});
			case 'TOTAL_CURRENT_LIABILITIES':
				return dispatchFinancialsInputs({
					type: 'TOTAL_CURRENT_LIABILITIES',
					value: Math.ceil(+totalCurrentLiabilities + 0.1)
				});
			case 'TOTAL_LIABILITIES':
				return dispatchFinancialsInputs({
					type: 'TOTAL_LIABILITIES',
					value: Math.ceil(+totalLiabilities + 0.1)
				});
			case 'BANK_LOANS_CURRENT':
				return dispatchFinancialsInputs({
					type: 'BANK_LOANS_CURRENT',
					value: Math.ceil(+bankLoansCurrent + 0.1)
				});
			case 'BANK_LOANS_NON_CURRENT':
				return dispatchFinancialsInputs({
					type: 'BANK_LOANS_NON_CURRENT',
					value: Math.ceil(+bankLoansNonCurrent + 0.1)
				});
			case 'INCREASE_REVENUE':
				return dispatchFinancialsInputs({
					type: 'INCREASE_REVENUE',
					value: Math.ceil(+IncreaseRevenueBy + 0.1)
				});
			default:
				return dispatchFinancialsInputs({
					type: 'CLEAR',
					value: ''
				});
		}
	}

	function decrementHandler(event: FormEvent<Element>): void {
		const elementInput = event.currentTarget.parentElement?.children
			.item(2)
			?.children.item(0) as HTMLInputElement;

		const {
			bankLoansCurrent,
			bankLoansNonCurrent,
			fixedAssets,
			totalAssets,
			totalCurrentAssets,
			totalCurrentLiabilities,
			totalLiabilities,
			COGS,
			CashAtBank,
			Depreciation,
			Dividends,
			EBIT,
			GrossProfit,
			DirectLabour,
			IncreaseRevenueBy,
			InterestPaid,
			NetProfit,
			OtherIncome,
			Revenue,
			Stock,
			TradeCreditors,
			TradeDebtors
		} = formInputs;
		switch (elementInput?.id) {
			case 'Revenue':
				return dispatchFinancialsInputs({
					type: 'REVENUE',
					value: +Revenue >= 1 ? Math.floor(+Revenue - 0.1) : 0
				});
			case 'COGS':
				return dispatchFinancialsInputs({
					type: 'COGS',
					value: +COGS >= 1 ? Math.floor(+COGS - 0.1) : 0
				});
			case 'GROSS_PROFIT':
				return dispatchFinancialsInputs({
					type: 'GROSS_PROFIT',
					value: +GrossProfit >= 1 ? Math.floor(+GrossProfit - 0.1) : 0
				});
			case 'DIRECT_LABOUR':
				return dispatchFinancialsInputs({
					type: 'DIRECT_LABOUR',
					value: +DirectLabour >= 1 ? Math.floor(+DirectLabour - 0.1) : 0
				});
			case 'EBIT':
				return dispatchFinancialsInputs({
					type: 'EBIT',
					value: +EBIT >= 1 ? Math.floor(+EBIT - 0.1) : 0
				});
			case 'NET_PROFIT':
				return dispatchFinancialsInputs({
					type: 'NET_PROFIT',
					value: +NetProfit >= 1 ? Math.floor(+NetProfit - 0.1) : 0
				});
			case 'DEPRECIATION':
				return dispatchFinancialsInputs({
					type: 'DEPRECIATION',
					value: +Depreciation >= 1 ? Math.floor(+Depreciation - 0.1) : 0
				});
			case 'INTEREST_PAID':
				return dispatchFinancialsInputs({
					type: 'INTEREST_PAID',
					value: Math.floor(+InterestPaid - 0.1)
				});
			case 'OTHER_INCOME':
				return dispatchFinancialsInputs({
					type: 'OTHER_INCOME',
					value: +OtherIncome >= 1 ? Math.floor(+OtherIncome - 0.1) : 0
				});
			case 'DIVIDENDS':
				return dispatchFinancialsInputs({
					type: 'DIVIDENDS',
					value: +Dividends >= 1 ? Math.floor(+Dividends - 0.1) : 0
				});
			case 'CASH_IN_BANK':
				return dispatchFinancialsInputs({
					type: 'CASH_IN_BANK',
					value: +CashAtBank >= 1 ? Math.floor(+CashAtBank - 0.1) : 0
				});
			case 'TRADE_DEBTORS':
				return dispatchFinancialsInputs({
					type: 'TRADE_DEBTORS',
					value: +TradeDebtors >= 1 ? Math.floor(+TradeDebtors - 0.1) : 0
				});
			case 'STOCK_DAYS_WIP':
				return dispatchFinancialsInputs({
					type: 'STOCK_DAYS_WIP',
					value: +Stock >= 1 ? Math.floor(+Stock - 0.1) : 0
				});
			case 'DEFERRED_REVENUE':
				return dispatchFinancialsInputs({
					type: 'DEFERRED_REVENUE',
					value: +deferredRevenue >= 1 ? Math.floor(+deferredRevenue - 0.1) : 0
				});

			case 'TOTAL_CURRENT_ASSETS':
				return dispatchFinancialsInputs({
					type: 'TOTAL_CURRENT_ASSETS',
					value: +totalCurrentAssets >= 1 ? Math.floor(+totalCurrentAssets - 0.1) : 0
				});
			case 'FIXED_ASSETS':
				return dispatchFinancialsInputs({
					type: 'FIXED_ASSETS',
					value: +fixedAssets >= 1 ? Math.floor(+fixedAssets - 0.1) : 0
				});
			case 'TOTAL_ASSETS':
				return dispatchFinancialsInputs({
					type: 'TOTAL_ASSETS',
					value: +totalAssets >= 1 ? Math.floor(+totalAssets - 0.1) : 0
				});
			case 'TRADE_CREDITORS':
				return dispatchFinancialsInputs({
					type: 'TRADE_CREDITORS',
					value: +TradeCreditors >= 1 ? Math.floor(+TradeCreditors - 0.1) : 0
				});
			case 'TOTAL_CURRENT_LIABILITIES':
				return dispatchFinancialsInputs({
					type: 'TOTAL_CURRENT_LIABILITIES',
					value: +totalCurrentLiabilities >= 1 ? +totalCurrentLiabilities - 0.1 : 0
				});
			case 'TOTAL_LIABILITIES':
				return dispatchFinancialsInputs({
					type: 'TOTAL_LIABILITIES',
					value: +totalLiabilities >= 1 ? Math.floor(+totalLiabilities - 0.1) : 0
				});
			case 'BANK_LOANS_CURRENT':
				return dispatchFinancialsInputs({
					type: 'BANK_LOANS_CURRENT',
					value: +bankLoansCurrent >= 1 ? Math.floor(+bankLoansCurrent - 0.1) : 0
				});
			case 'BANK_LOANS_NON_CURRENT':
				return dispatchFinancialsInputs({
					type: 'BANK_LOANS_NON_CURRENT',
					value: +bankLoansNonCurrent >= 1 ? Math.floor(+bankLoansNonCurrent - 0.1) : 0
				});
			case 'INCREASE_REVENUE':
				return dispatchFinancialsInputs({
					type: 'INCREASE_REVENUE',
					value: +IncreaseRevenueBy >= 1 ? Math.floor(+IncreaseRevenueBy - 0.1) : 0
				});
			default:
				return dispatchFinancialsInputs({
					type: 'CLEAR',
					value: ''
				});
		}
	}

	function setFinancialsIdHandler(): void {
		setGenerateNewFinancialId(!generateNewFinancialId);
		dispatchFinancialsInputs({
			type: 'FINANCIALS_ID',
			value: Math.random() * Math.random()
		});
	}

	const [errorMessage, setErrorMessage] = useState<ErrorMessageInterface>(emptyErrorMessageObject);

	function checkForErrorsHandler(): boolean {
		let errorsFound = false;
		if (!COGS) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorCogs: styles.errorCogs
			}));
		}
		if (!DirectLabour) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorCogs: styles.errorDirectLabour
			}));
		}
		if (!bankLoansCurrent) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorBankLoansCurrent: styles.errorBankLoansCurrent
			}));
		}
		if (!bankLoansNonCurrent) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorBankLoansNonCurrent: styles.errorBankLoansNonCurrent
			}));
		}
		if (!MonthEnding) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorMonthEnding: styles.errorMonthEnding
			}));
		}
		if (!MonthStart) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorMonthStart: styles.errorMonthStart
			}));
		}
		if (!BanksLendEBITDAMultiplierMax) {
			// errorsFound = true; // this field doesn't exist in form, possibly a legacy field
			setErrorMessage((prevState) => ({
				...prevState,
				errorBanksLendEBITDAMultiplierMax: styles.errorBanksLendEBITDAMultiplierMax
			}));
		}
		if (!YearStart) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorYearStart: styles.errorYearStart
			}));
		}
		if (!YearEnding) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorYearEnding: styles.errorYearEnding
			}));
		}
		if (!TradeDebtors) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorTradeDebtors: styles.errorTradeDebtors
			}));
		}
		if (!TradeCreditors) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorTradeCreditors: styles.errorTradeCreditors
			}));
		}
		if (!Stock) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorStock: styles.errorStock
			}));
		}
		if (!Revenue) {
			errorsFound = true;
			// setErrorRevenue(styles.errorRevenue);
			setErrorMessage((prevState) => ({
				...prevState,
				errorRevenue: styles.errorRevenue
			}));
		}
		if (!OtherIncome) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorOtherIncome: styles.errorOtherIncome
			}));
		}
		if (!NetProfit) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorNetProfit: styles.errorNetProfit
			}));
		}
		if (!InterestPaid) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorInterestPaid: styles.errorInterestPaid
			}));
		}
		if (!IncreaseRevenueBy) {
			// errorsFound = true; // this field doesn't exist in form, possibly a legacy field
			setErrorMessage((prevState) => ({
				...prevState,
				errorIncreaseRevenueBy: styles.errorIncreaseRevenueBy
			}));
		}
		if (!GrossProfit) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorGrossProfit: styles.errorGrossProfit
			}));
		}
		if (!DirectLabour) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorDirectLabour: styles.errorDirectLabour
			}));
		}
		if (!EBIT) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorEbit: styles.errorEBIT
			}));
		}
		if (!Dividends) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorDividends: styles.errorDividends
			}));
		}
		if (!Depreciation) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorDepreciation: styles.errorDepreciation
			}));
		}
		if (!deferredRevenue) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorDeferredRevenue: styles.errorDeferredRevenue
			}));
		}
		if (!CashAtBank) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorCashAtBank: styles.errorCashAtBank
			}));
		}
		if (!totalLiabilities) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorTotalLiabilities: styles.errorTotalLiabilities
			}));
		}
		if (!totalCurrentAssets) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorTotalCurrentAssets: styles.errorTotalCurrentAssets
			}));
		}
		if (!totalCurrentLiabilities) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorTotalCurrentLiabilities: styles.errorTotalCurrentLiabilities
			}));
		}
		if (!totalAssets) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorTotalAssets: styles.errorTotalAssets
			}));
		}
		if (!fixedAssets) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorFixedAssets: styles.errorFixedAssets
			}));
		}
		if (!totalCurrentLiabilities) {
			errorsFound = true;
			setErrorMessage((prevState) => ({
				...prevState,
				errorTotalCurrentLiabilities: styles.errorTotalCurrentLiabilities
			}));
		}
		return errorsFound;
	}

	function onBlurHandler(): void {
		setErrorMessage(emptyErrorMessageObject);
		// checkForErrorsHandler();
	}

	function switchToFormHandler(element: boolean) {
		setSwitchToForm(element);
	}

	function cancelHandler() {
		// reset the form submissions status:
		setFormSendSuccessfully(false);
		dispatchFinancialsInputs({
			type: 'DEFERRED_REVENUE',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'FIRST_MONTH',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'FIRST_YEAR',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'LAST_YEAR',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'LAST_MONTH',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'REVENUE',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'COGS',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'DIRECT_LABOUR',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'GROSS_PROFIT',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'EBIT',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'NET_PROFIT',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'DEPRECIATION',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'INTEREST_PAID',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'OTHER_INCOME',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'DIVIDENDS',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'CASH_IN_BANK',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'TRADE_DEBTORS',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'STOCK_DAYS_WIP',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'TOTAL_CURRENT_ASSETS',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'FIXED_ASSETS',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'TOTAL_ASSETS',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'TRADE_CREDITORS',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'TOTAL_CURRENT_LIABILITIES',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'TOTAL_LIABILITIES',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'BANK_LOANS_CURRENT',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'BANK_LOANS_NON_CURRENT',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'INCREASE_REVENUE',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'COMPANY_ID_FINANCIALS',
			value: ''
		});
		dispatchFinancialsInputs({
			type: 'FINANCIALS_ID',
			value: ''
		});
	}

	const submitFinancialFormHandler = useCallback(async (): Promise<boolean> => {
		const hasErrors = checkForErrorsHandler();
		console.log('hasErrors', hasErrors, 'errorMessage', errorMessage);
		if (hasErrors) {
			return false;
		}

		const canSubmit =
			COGS &&
			bankLoansCurrent &&
			bankLoansNonCurrent &&
			MonthEnding &&
			MonthStart &&
			YearStart &&
			YearEnding &&
			TradeDebtors &&
			TradeCreditors &&
			Stock &&
			Revenue &&
			OtherIncome &&
			NetProfit &&
			InterestPaid &&
			GrossProfit &&
			DirectLabour &&
			EBIT &&
			Dividends &&
			Depreciation &&
			deferredRevenue &&
			CashAtBank &&
			totalLiabilities &&
			totalCurrentAssets &&
			totalCurrentLiabilities &&
			totalAssets &&
			fixedAssets;

		if (!canSubmit || !selectedCompany) return false;

		const payload = {
			company_id: selectedCompany?.company_id,
			financials_id: formInputs.financialsId.toString(),
			input: {
				'Additional Bank Loans - Current': formInputs.bankLoansCurrent,
				'Additional Bank Loans - Non Current': formInputs.bankLoansNonCurrent,
				'Additional Fixed Assets': formInputs.fixedAssets,
				'Additional Total Assets': formInputs.totalAssets,
				'Additional Total Current Assets': formInputs.totalCurrentAssets,
				'Additional Total Current Liabilities': formInputs.totalCurrentLiabilities,
				'Additional Total Liabilities': formInputs.totalLiabilities,
				'Banks Lend EBITDA Multiplier Max': 100,
				'Banks Lend EBITDA Multiplier Min': 100,
				COGS: formInputs.COGS,
				'Cash at Bank': formInputs.CashAtBank,
				Depreciation: formInputs.Depreciation,
				Dividends: formInputs.Dividends,
				EBIT: formInputs.EBIT,
				'Gross Profit': formInputs.GrossProfit,
				'Direct Labour': formInputs.DirectLabour,
				'Increase Revenue By': +formInputs.IncreaseRevenueBy,
				'Interest Paid': formInputs.InterestPaid,
				'Month Ending': formInputs.MonthEnding,
				'Month Start': formInputs.MonthStart,
				'Net Profit': formInputs.NetProfit,
				'Other Income': formInputs.OtherIncome,
				Revenue: formInputs.Revenue,
				Stock: formInputs.Stock,
				'Trade Creditors': formInputs.TradeCreditors,
				'Trade Debtors': formInputs.TradeDebtors,
				'Year Ending': formInputs.YearEnding,
				'Year Start': formInputs.YearStart,
				'Deferred Revenue': formInputs.deferredRevenue
			}
		};

		const action = editFinancialtemId
			? patchFinancialsData(payload)
			: insertFinancialsData(payload);
		await dispatch(action);
		setFormSendSuccessfully(true);
		return true;
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [formInputs]);

	function editHandler(itemForEdit: FinancialsModel | undefined) {
		console.log('item for edit', itemForEdit);
		setFormSendSuccessfully(false);
		const { input } = itemForEdit as FinancialsModel;
		dispatchFinancialsInputs({
			type: 'FIRST_MONTH',
			value: input['Month Start']
		});
		dispatchFinancialsInputs({
			type: 'FIRST_YEAR',
			value: input['Year Start']
		});
		dispatchFinancialsInputs({
			type: 'LAST_YEAR',
			value: input['Year Ending']
		});
		dispatchFinancialsInputs({
			type: 'LAST_MONTH',
			value: input['Month Ending']
		});
		dispatchFinancialsInputs({
			type: 'REVENUE',
			value: input.Revenue
		});
		dispatchFinancialsInputs({
			type: 'COGS',
			value: input.COGS
		});
		dispatchFinancialsInputs({
			type: 'GROSS_PROFIT',
			value: input['Gross Profit']
		});
		dispatchFinancialsInputs({
			type: 'DIRECT_LABOUR',
			value: input['Direct Labour']
		});
		dispatchFinancialsInputs({
			type: 'EBIT',
			value: input.EBIT
		});
		dispatchFinancialsInputs({
			type: 'NET_PROFIT',
			value: input['Net Profit']
		});
		dispatchFinancialsInputs({
			type: 'DEPRECIATION',
			value: input.Depreciation
		});
		dispatchFinancialsInputs({
			type: 'INTEREST_PAID',
			value: input['Interest Paid']
		});
		dispatchFinancialsInputs({
			type: 'OTHER_INCOME',
			value: input['Other Income']
		});
		dispatchFinancialsInputs({
			type: 'DIVIDENDS',
			value: input.Dividends
		});
		dispatchFinancialsInputs({
			type: 'CASH_IN_BANK',
			value: input['Cash at Bank']
		});
		dispatchFinancialsInputs({
			type: 'TRADE_DEBTORS',
			value: input['Trade Debtors']
		});
		dispatchFinancialsInputs({
			type: 'STOCK_DAYS_WIP',
			value: input.Stock
		});
		dispatchFinancialsInputs({
			type: 'TOTAL_CURRENT_ASSETS',
			value: input['Additional Total Current Assets']
		});
		dispatchFinancialsInputs({
			type: 'FIXED_ASSETS',
			value: input['Additional Fixed Assets']
		});
		dispatchFinancialsInputs({
			type: 'TOTAL_ASSETS',
			value: input['Additional Total Assets']
		});
		dispatchFinancialsInputs({
			type: 'TRADE_CREDITORS',
			value: input['Trade Creditors']
		});
		dispatchFinancialsInputs({
			type: 'TOTAL_CURRENT_LIABILITIES',
			value: input['Additional Total Current Liabilities']
		});
		dispatchFinancialsInputs({
			type: 'TOTAL_LIABILITIES',
			value: input['Additional Total Liabilities']
		});
		dispatchFinancialsInputs({
			type: 'BANK_LOANS_CURRENT',
			value: input['Additional Bank Loans - Current']
		});
		dispatchFinancialsInputs({
			type: 'BANK_LOANS_NON_CURRENT',
			value: input['Additional Bank Loans - Non Current']
		});
		dispatchFinancialsInputs({
			type: 'INCREASE_REVENUE',
			value: input['Increase Revenue By']
		});
		dispatchFinancialsInputs({
			type: 'COMPANY_ID_FINANCIALS',
			value: itemForEdit?.company_id as string
		});
		dispatchFinancialsInputs({
			type: 'FINANCIALS_ID',
			value: itemForEdit?.financials_id as string
		});
		dispatchFinancialsInputs({
			type: 'DEFERRED_REVENUE',
			value: itemForEdit?.input['Deferred Revenue'] as string
		});
	}

	// eslint-disable-next-line react/jsx-no-constructed-context-values
	const contextValue = {
		getFirstMonthHandler,
		getFirstYearHandler,
		getLastYearHandler,
		getLastMonthHandler,
		getRevenueHandler,
		getCogsHandler,
		getGrossProfitHandler,
		getDirectLabourHandler,
		getEbitHandler,
		getNetProfitHandler,
		getDepreciationAmortisationHandler,
		getInterestPaidHandler,
		getOtherIncomeHandler,
		getDividendsHandler,
		getCashInBankHandler,
		getTradeDebtorsHandler,
		getStockDaysWIPHandler,
		getTotalCurrentAssetsHandler,
		getFixedAssetsHandler,
		getTotalAssetsHandler,
		getTradeCreditorsHandler,
		getTotalCurrentLiabilitiesHandler,
		getTotalLiabilitiesHandler,
		getBankLoansCurrentHandler,
		getBankLoansNonCurrentHandler,
		getIncreaseRevenueByHandler,
		handleSanitizedChange,
		handleInputData,
		bankLoansCurrent,
		bankLoansNonCurrent,
		fixedAssets,
		totalAssets,
		totalCurrentAssets,
		totalCurrentLiabilities,
		totalLiabilities,
		BanksLendEBITDAMultiplierMax,
		BanksLendEBITDAMultiplierMin,
		COGS,
		CashAtBank,
		Depreciation,
		Dividends,
		EBIT,
		GrossProfit,
		DirectLabour,
		IncreaseRevenueBy,
		InterestPaid,
		MonthEnding,
		MonthStart,
		NetProfit,
		OtherIncome,
		Revenue,
		Stock,
		TradeCreditors,
		TradeDebtors,
		YearEnding,
		YearStart,
		incrementHandler,
		decrementHandler,
		editHandler,
		cancelHandler,
		submitFinancialFormHandler,
		companyId,
		getCompanyIdHandler,
		financialsId,
		setFinancialsIdHandler,
		deferredRevenue,
		getDeferredRevenueHandler,
		errorMessage,
		onBlurHandler,
		formSendSuccessfully,
		switchToFormHandler,
		switchToForm
	};
	return (
		<FinancialsFormContext.Provider value={contextValue}>
			{props.children}
		</FinancialsFormContext.Provider>
	);
};

export default FinancialsFormProvider;
