/* eslint-disable react-hooks/exhaustive-deps */
/* eslint-disable @typescript-eslint/no-unused-vars */
import type { AxiosResponse } from 'axios';
import axios from 'axios';
import { createContext, useContext, useEffect, useState } from 'react';
import type React from 'react';
import type { ReactNode } from 'react';

import environment from '../../Environments/environment';
import companyDropdownPredefinedValues from '../../Pages/Companies/Companies.helper';
import type { CompanyDbModel } from '../../Pages/Companies/Components/CompaniesComponents.helper';
import type { FinancialsModel } from '../../Pages/Financials/Components/FinancialsForm/FinancialsForm.helper';
import {
	demoFinancialFirst,
	demoFinancialSecond,
	demoFinancialThird
} from '../../Pages/Financials/Components/UI/demo-user.helper';
import styles from '../../Pages/Financials/Financials.module.scss';
import type { PaymentInterface } from '../../Pages/ManageSubscription/ManageSubscription';
import getCookieValue from '../../utils/getCookieValue';
import type { CashFlowMetricModel } from '../CashFlowAnalysis/CashFlowMetric/CashFlowMetric-context';
import { CashFlowMetricContext } from '../CashFlowAnalysis/CashFlowMetric/CashFlowMetric-context';
import { ebitdaMapValues, helperMonths } from '../Financials/financialsContext.helper';
import type { IndustryModel } from '../Financials/financialsContext.helper';
import { demoCompanyId } from '../User/user-context.helper';
import type { PlanModel, UserModel } from '../User/user-context.helper';
import getCompanyType from '../../utils/getCompanyType';

export type GlobalStateModel = {
	setIsAuthenticated: (data: boolean) => void;
	companies: CompanyDbModel[] | string;
	getCompaniesHandler: (data?: CompanyDbModel) => void;
	signInHandler: () => void;
	updatePlan: (plan: PlanModel) => void;
	getAvailablePlans: () => PlanModel[] | null;
	loggedInUser: UserModel | null;
	isCorrectUser: boolean;
	getDemoUserData: () => void;
	closeNavBarHandler: (element: boolean) => void;
	isNavbarOpen: boolean;
	getFinancialsFromSelectedCompany: (event: string) => void;
	financials: FinancialsModel[] | string;
	getSelectedFinancials: () => void;
	selectedFinancials: string[];
	payload: { company_id: string };
	recordUpdated: string;
	financialsId: string;
	isCompanySelected: boolean;
	companyType: string;
	selectedIndustryForEbitda: {
		id: number;
		sixToTen: number;
		twoToFive: number;
		name: string;
		zeroToOne: number;
	};
	checkedFinancials: any;
	selectedCommonFinancials: FinancialsModel[];
	selectedCompany: CompanyDbModel;
	selectedCharts: string[];
	saveSelectedDashboardCharts: (event: string[]) => void;
	getSelectedDashboardCharts: () => void;
	fetchAccount: () => void;
	account: UserModel | null;
	setLoggedInUser: React.Dispatch<React.SetStateAction<UserModel | null>>;
	setCompanies: React.Dispatch<React.SetStateAction<CompanyDbModel[] | string>>;
	payments: string | PaymentInterface[];
	activateUserHandler: (event: string) => void;
	companyPlan: number;
	setCheckedFinancialsHandler: (event: FinancialsModel[] | string) => void;
	whatIsChecked: number;
	classForPopup: string;
	nextButtonHandler: () => void;
	isCheckedCardHandler: (first: string | undefined) => void;
	popupClass: string;
	selectedItems: string[];
	loadedSelectedItemsHandler: (event: string[]) => void;
	selectedItemsHandler: (event: string) => void;
	unselectedItemHandler: (event: string) => void;
};

export const GlobalStateContext: React.Context<GlobalStateModel> = createContext<GlobalStateModel>({
	setIsAuthenticated: (data: boolean) => {},
	companies: [],
	getCompaniesHandler: (data?: CompanyDbModel) => {},
	signInHandler: () => {},
	updatePlan: () => {},
	getAvailablePlans: (): PlanModel[] | null => null,
	loggedInUser: null,
	isCorrectUser: false,
	getDemoUserData: (): void => {},
	closeNavBarHandler: (): void => {},
	isNavbarOpen: true,
	getFinancialsFromSelectedCompany: () => {},
	financials: [],
	getSelectedFinancials: (): void => {},
	selectedFinancials: [],
	payload: {
		company_id: ''
	},
	recordUpdated: '',
	financialsId: '',
	isCompanySelected: false,
	companyType: '',
	selectedIndustryForEbitda: {
		id: 0,
		sixToTen: 0,
		twoToFive: 0,
		name: '',
		zeroToOne: 0
	},
	checkedFinancials: {},
	selectedCommonFinancials: [],
	selectedCompany: {
		company_id: '',
		cognito_username: '',
		industry_id: 0,
		industry_type: '',
		currency_symbol: '',
		gdpr: true,
		_id: '',
		company_name: '',
		record_updated: '',
		record_created: '',
		company_reg_number: '',
		plan: {
			cost: 0,
			description: '',
			title: '',
			id: 0
		}
	},
	selectedCharts: [],
	saveSelectedDashboardCharts: (): void => {},
	getSelectedDashboardCharts: (): void => {},
	fetchAccount: (): void => {},
	account: null,
	setLoggedInUser: (prevState) => prevState,
	setCompanies: (prevState) => prevState,
	payments: [],
	activateUserHandler: (): void => {},
	companyPlan: 0,
	setCheckedFinancialsHandler: (): void => {},
	whatIsChecked: 0,
	classForPopup: styles.collapseContainer,
	nextButtonHandler: (): void => {},
	isCheckedCardHandler: (): void => {},
	popupClass: '',
	selectedItems: [],
	selectedItemsHandler: (): void => {},
	loadedSelectedItemsHandler: (): void => {},
	unselectedItemHandler: (): void => {}
});
const GlobalStateContextProvider: React.FC<{ children: ReactNode }> = (props: {
	children: ReactNode;
}) => {
	const { apiUrl, backendRoutes } = environment;
	const [isAuthenticated, setIsAuthenticated] = useState<boolean>(false);
	const [companies, setCompanies] = useState<CompanyDbModel[] | string>(
		JSON.parse(localStorage.getItem('companies') as string)
			? JSON.parse(localStorage.getItem('companies') as string)
			: 'no companies found'
	);
	const [payments, setPayments] = useState<PaymentInterface[] | string>('');
	const [paymentHistory, setPaymentHistory] = useState<PaymentInterface[] | string>([]);
	const [availablePlans, setAvailablePlans] = useState<PlanModel[]>();
	const [isCorrectUser, setIsCorrectUser] = useState<boolean>(false);
	const [loggedInUser, setLoggedInUser] = useState<UserModel>(null);
	const [isNavbarOpen, setIsNavbarOpen] = useState(false);
	const [financials, setFinancials] = useState<FinancialsModel[] | string>([]);
	const [selectedCompany, setSelectedCompany] = useState<CompanyDbModel>({
		company_id: '',
		cognito_username: '',
		industry_id: 0,
		industry_type: '',
		currency_symbol: '',
		gdpr: true,
		_id: '',
		company_name: '',
		record_updated: '',
		record_created: '',
		company_reg_number: '',
		plan: {
			id: 0,
			cost: 0,
			title: '',
			description: ''
		}
	});
	const [selectedIndustryForEbitda, setSelectedIndustryForEbitda] = useState<IndustryModel>({
		id: 0,
		sixToTen: 0,
		twoToFive: 0,
		name: '',
		zeroToOne: 0
	});
	const [selectedFinancials, setSelectedFinancials] = useState<string[]>([]);
	const [payload, setPayload] = useState<{ company_id: string }>({
		company_id: ''
	});
	const [recordUpdated, setRecordUpdated] = useState<string>('');
	const [financialsId, setFinancialsId] = useState<string>('');
	const [isCompanySelected, setIsCompanySelected] = useState<boolean>(false);
	const [companyType, setCompanyType] = useState<string>('');
	const [checkedFinancials, setCheckedFinancials] = useState<any>({});
	const [selectedCommonFinancials, setSelectedCommonFinancials] = useState<FinancialsModel[]>([]);
	const [selectedCharts, setSelectedCharts] = useState<string[]>([]);
	const [account, setAccount] = useState<UserModel>(null);
	const [companyPlan, setCompanyPlan] = useState(0);
	const [classForPopup, setClassForPopup] = useState<string>('');
	const [whatIsChecked, setWhatIsChecked] = useState<number>(0);
	const [popupClass, setPopupClass] = useState<string>('');
	const [selectedItems, setSelectedItems] = useState<string[]>([]);
	const [selectedFinancialsId, setSelectedFinancialsId] = useState<string[]>([]);
	const [checkedSelectedFinancials, setCheckedSelectedFinancials] = useState<string[]>([]);
	const cashFlowMetricContext: CashFlowMetricModel = useContext(CashFlowMetricContext);
	const [isError, setIsError] = useState<boolean>(false);

	async function fetchAccount() {
		await axios
			.get(apiUrl + backendRoutes.getAccount)
			.then((results: AxiosResponse<UserModel>) => {
				setAccount(results.data);
			})
			.catch((error) => {
				console.error(error.message);
			});
	}

	async function loadPlans() {
		// get the list of available plans on the platform
		await axios
			.get(`${apiUrl}/plans/get-available-plans`)
			.then((response) => {
				if (response.status === 200) {
					setAvailablePlans(response.data);
				} else {
					// eslint-disable-next-line no-alert
					alert('an error occurred while sending your invite');
				}
			})
			.catch((e) => {
				if (e.message) {
					setIsError(true);
				}
				console.error(e);
			});
	}

	function setCheckedFinancialsHandler(event: FinancialsModel[] | string) {
		const demoFinancials = [demoFinancialFirst, demoFinancialSecond, demoFinancialThird];
		let fin: FinancialsModel[] | string;
		if (event === 'no financials found') {
			fin = demoFinancials;
		} else {
			fin = event;
		}
		const allFinId = (fin as FinancialsModel[]).map((item) => item.financials_id);

		if (
			!selectedFinancials ||
			!Array.isArray(selectedFinancials) ||
			selectedFinancials.length === 0
		) {
			return;
		}
		const commonElements = selectedFinancials.filter((element) => allFinId.includes(element));
		const preCheckedFinancials = allFinId.map((elem) =>
			commonElements.includes(elem)
				? {
						[elem]: true
						// eslint-disable-next-line no-mixed-spaces-and-tabs
				  }
				: {
						[elem]: false
						// eslint-disable-next-line no-mixed-spaces-and-tabs
				  }
		);

		setCheckedFinancials(Object.assign({}, ...preCheckedFinancials));
		// localStorage.setItem('selected-financials', JSON.stringify(commonElements));
		const newFinancials = (fin as FinancialsModel[]).filter((e) =>
			commonElements.includes(e.financials_id)
		);
		setSelectedCommonFinancials(newFinancials);
	}

	function getSelectedFinancials() {
		// if (selectedCompany) {
		axios
			.get(
				// `${apiUrl}${backendRoutes.getSelectedFinancials}?company_id=${selectedCompany.company_id}`
				`${apiUrl}${backendRoutes.getSelectedFinancials}`
			)
			.then((result) => {
				setCheckedSelectedFinancials(result.data);
				const checked = (financials as FinancialsModel[]).filter((item) =>
					result.data.includes(item.financials_id)
				);

				if (checked && checked.length > 0) {
					setCheckedFinancialsHandler(checked);
				}

				localStorage.setItem('selected-financials-from-charts', JSON.stringify(result.data));
				return setSelectedFinancials(result.data);
			});
		// }
	}

	function changeCompanyFromHeaderHandler(event: string): void {
		if (event !== '') {
			setIsCompanySelected(true);
		}
		setPayload({
			company_id: event
		});
		const randomNumber: number = Math.random() * Math.random();
		setFinancialsId(JSON.stringify(randomNumber));
		if (typeof companies !== 'string') {
			const selectedCompanyFromFinancial: CompanyDbModel[] = (companies as CompanyDbModel[]).filter(
				(item) => item.company_id === event
			);
			if (selectedCompanyFromFinancial[0]) {
				if (
					selectedCompanyFromFinancial[0].record_updated &&
					selectedCompanyFromFinancial[0].industry_type &&
					selectedCompanyFromFinancial[0].currency_symbol
				) {
					setRecordUpdated(selectedCompanyFromFinancial[0].record_updated);
					const industryType = getCompanyType(selectedCompanyFromFinancial[0]) as string;
					setCompanyType(industryType);
					localStorage.setItem('companyType', JSON.stringify(industryType));
					const currency = companyDropdownPredefinedValues.currency.find((item) =>
						item.value === selectedCompanyFromFinancial[0].currency_symbol ? item.label : null
					);
					if (currency) {
						localStorage.setItem('currency', currency.label);
					}
					const selectedIndustry = ebitdaMapValues.find(
						(item) => item.id === selectedCompanyFromFinancial[0].industry_id
					);
					if (selectedIndustry) {
						setSelectedIndustryForEbitda(selectedIndustry as IndustryModel);
					}
				}
			}
		}
	}

	async function updatePlanHandler(event: PaymentInterface[] | string) {
		if (typeof event === 'string' || !event || !selectedCompany.company_id) {
			// TODO: throw an error, do not update the plan for the selected company
			// as we can reach this code only if there is an error with
			// extracting data for selected company
			// await axios
			// 	.post(
			// 		apiUrl + backendRoutes.account.updatePlan,
			// 		{ planId: 1, companyId: selectedCompany.company_id });
			// setCompanyPlan(1);
			return;
		}
		// don't go through all payments, just the last one:
		const payment = event[event.length - 1];
		// event.filter((payment) => {
		const now = new Date();
		const expiresOn = payment.payment_expires;
		const lastPaymentExpires = new Date(expiresOn);
		const daysLeft = Math.ceil(lastPaymentExpires.getTime() - now.getTime() / (1000 * 3600 * 24));

		if (now.getTime() > lastPaymentExpires.getTime()) {
			// the account has expired, set the plan for the selected company to basic
			if (payment.company_id === selectedCompany.company_id) {
				axios.post(apiUrl + backendRoutes.account.updatePlan, {
					planId: 1,
					companyId: selectedCompany.company_id
				});
				setCompanyPlan(1);
				localStorage.setItem('isDemoActive', JSON.stringify(true));
			}
			return;
		}

		if (payment.payment_details.purchase_units[0].description === 'Pro Plan') {
			// no need to update, the company should already have these details
			// axios
			// 	.post(apiUrl + backendRoutes.account.updatePlan,
			// 		{ planId: 3, companyId: selectedCompany.company_id });
			setCompanyPlan(3);
			localStorage.setItem('isDemoActive', JSON.stringify(false));
			return;
		}

		if (payment.payment_details.purchase_units[0].description === 'Grow Plan') {
			// no need to update, the company should already have these details
			// axios
			// 	.post(apiUrl + backendRoutes.account.updatePlan,
			// 		{ planId: 2, companyId: selectedCompany.company_id });
			setCompanyPlan(2);
			localStorage.setItem('isDemoActive', JSON.stringify(false));
			return;
		}

		// no need to update, the company should already have these details
		// axios
		// 	.post(apiUrl + backendRoutes.account.updatePlan,
		// 		{ planId: 1, companyId: selectedCompany.company_id });
		setCompanyPlan(1);
		localStorage.setItem('isDemoActive', JSON.stringify(true));
		// });
		await fetchAccount();
	}

	function compare(a: { year: number; month: string }, b: { year: number; month: string }) {
		if (a.year < b.year) {
			return -1;
		}
		if (a.year > b.year) {
			return 1;
		}
		return 0;
	}

	function getInOrderFinancials(selectedFinancialsItems: FinancialsModel[]): void {
		const objectItem: { year: number; month: string }[] = [];
		selectedFinancialsItems.filter(({ input }) =>
			helperMonths.find((month) => {
				if (input['Month Ending'] === month.month) {
					objectItem.push({
						year: +input['Year Ending'],
						month: month.index.toString()
					});
				}
				return input['Month Ending'] === month.month;
			})
		);
		const ordered = objectItem.sort(compare);
		const getOrdered: { year: number; month: string }[] = [];
		ordered.map((item) =>
			helperMonths.filter((month) => {
				if (month.index === +item.month) {
					getOrdered.push({
						year: item.year,
						month: month.month
					});
				}
				return month.index === +item.month;
			})
		);
		selectedFinancialsItems.filter((financialItem) => {
			if (
				+financialItem.input['Year Ending'] === getOrdered[0]?.year &&
				financialItem.input['Month Ending'] === getOrdered[0]?.month
			) {
				localStorage.setItem('first-financial', JSON.stringify(financialItem));
			} else if (
				+financialItem.input['Year Ending'] === getOrdered[1]?.year &&
				financialItem.input['Month Ending'] === getOrdered[1]?.month
			) {
				localStorage.setItem('second-financial', JSON.stringify(financialItem));
			} else if (
				+financialItem.input['Year Ending'] === getOrdered[2]?.year &&
				financialItem.input['Month Ending'] === getOrdered[2]?.month
			) {
				localStorage.setItem('third-financial', JSON.stringify(financialItem));
			}
			return financialItem;
		});
	}

	function findSelectedFinancials(selected: string[]): void {
		const getSelected = (financials as FinancialsModel[]).filter((item) =>
			selected.includes(item.financials_id)
		);
		getInOrderFinancials(getSelected);
		setSelectedCommonFinancials(getSelected);
		setSelectedFinancialsId(selected);
		if (selected.length === 0) {
			localStorage.removeItem('first-financial');
			localStorage.removeItem('second-financial');
			localStorage.removeItem('third-financial');
		} else if (selected.length === 1) {
			localStorage.removeItem('second-financial');
			localStorage.removeItem('third-financial');
		} else if (selected.length === 2) {
			localStorage.removeItem('third-financial');
		}
	}

	function loadedSelectedItemsHandler(event: string[]): void {
		setSelectedItems(() => {
			findSelectedFinancials(event);
			return event;
		});
	}

	function setSelectedFinancialsHandler(financ: FinancialsModel[]) {
		let csf = checkedSelectedFinancials;
		// in some instances such as page reload the checkedSelectedFinancials
		// is still not updated as it is updating through a react setter which is async
		// so use the values from localStorage instead
		// TODO: improve below instances by passing method params insted of
		// relaying on async variables and localStorage
		if (!checkedSelectedFinancials || checkedSelectedFinancials.length === 0) {
			csf = localStorage.getItem('selected-financials-from-charts')
				? JSON.parse(localStorage.getItem('selected-financials-from-charts') as string)
				: [];
		}

		const checked = (financ as FinancialsModel[]).filter((item) =>
			csf.includes(item.financials_id)
		);

		if (checked) {
			if (checked.length > 0 && checked.length !== 0) {
				loadedSelectedItemsHandler(csf);
			} else {
				loadedSelectedItemsHandler([]);
			}
		}
	}

	async function getPaymentHistoryHandler(event: string) {
		if (!event) {
			return;
		}
		await axios(`${apiUrl}/account/add-payment-history?companyId=${event}`).then((response) => {
			if (response.status === 200) {
				updatePlanHandler(response.data);
				setPayments(response.data);
				// activateUserHandler(response.data?.plan.title as string);
			} else {
				updatePlanHandler('something wrong');
			}
			return setPaymentHistory(response.data);
		});
	}

	function getFinancialsFromSelectedCompany(event: string, companyData?: CompanyDbModel[]) {
		const demoFinancials = [demoFinancialFirst, demoFinancialSecond, demoFinancialThird];
		if (!event) {
			return;
		}
		// TOREVIEW:
		// what is first, second, third-financial?
		// Are we pepared to handle more than three financials?
		// If the properties refer to selected financials this needs
		// to be reflected in property name to avoid confision
		localStorage.removeItem('first-financial');
		localStorage.removeItem('second-financial');
		localStorage.removeItem('third-financial');
		localStorage.removeItem('selected-financials');
		const c = companyData || companies;
		if (typeof c !== 'string') {
			const selectedCompanyFromDropdown = (c as CompanyDbModel[]).find(
				(company) => company.company_id === event
			);
			setSelectedCompany(selectedCompanyFromDropdown as CompanyDbModel);
			getPaymentHistoryHandler(selectedCompanyFromDropdown?.company_id as string);
			localStorage.setItem('selected-company', JSON.stringify(selectedCompanyFromDropdown));

			// moved and logic rewritten
			// call BE to fetch company's financials only if the plan is set and is !== 1
			if (selectedCompanyFromDropdown) {
				if (selectedCompanyFromDropdown.plan.id === 1) {
					setSelectedFinancialsHandler(demoFinancials);
					setFinancials(demoFinancials);
					setCheckedFinancialsHandler(demoFinancials);
					localStorage.setItem('pre-loaded-financials', JSON.stringify(demoFinancials));
					localStorage.setItem('financials', JSON.stringify(demoFinancials));
					localStorage.setItem('first-financial', JSON.stringify(demoFinancials[0]));
					localStorage.setItem('second-financial', JSON.stringify(demoFinancials[1]));
					localStorage.setItem('third-financial', JSON.stringify(demoFinancials[2]));
					localStorage.setItem(
						'selected-financials',
						JSON.stringify([
							demoFinancials[0].financials_id,
							demoFinancials[1].financials_id,
							demoFinancials[2].financials_id
						])
					);
				} else {
					axios
						.post(apiUrl + backendRoutes.financials.get, {
							company_id: event
						})
						.then((response) => {
							if (response.status !== 200) {
								return;
							}
							if (typeof response.data !== 'string') {
								const retreivedFinancials = response.data;
								const selectedFinancials: any[] = JSON.parse(
									localStorage.getItem('selected-financials-from-charts') as string
								);
								setCheckedFinancialsHandler(retreivedFinancials);

								// set globalContext.financials
								setFinancials(retreivedFinancials);
								setSelectedFinancialsHandler(retreivedFinancials);

								localStorage.setItem('pre-loaded-financials', JSON.stringify(retreivedFinancials));
								localStorage.setItem('financials', JSON.stringify(retreivedFinancials));
								if (selectedFinancials) {
									retreivedFinancials.forEach((f: any, i: number) => {
										const exists = selectedFinancials.filter((sf) => f.financials_id === sf);
										if (exists) {
											switch (i) {
												case 1:
													localStorage.setItem('first-financial', JSON.stringify(f));
													break;
												case 2:
													localStorage.setItem('second-financial', JSON.stringify(f));
													break;
												case 3:
													localStorage.setItem('third-financial', JSON.stringify(f));
													break;

												default:
													break;
											}
										}
									});
								}
								// const findIfThereChecked = (response.data as FinancialsModel[]).map((item) =>
								// item.financials_id);
								// findSelectedFinancials(retreivedFinancials);
							} else if (typeof response.data === 'string') {
								if (selectedCompanyFromDropdown) {
									// TOREVIEW:
									// redundant: if id > 1 then in the same time it is not equal to one
									// was there another intended usecase?
									if (
										selectedCompanyFromDropdown.plan.id !== 1 &&
										selectedCompanyFromDropdown.plan.id > 1
									) {
										setFinancials([]);
										localStorage.setItem('selected-financials', JSON.stringify([]));
									}
								}
							}
						});
				}
			}
		} else {
			// no companies associated with the account set demo data:
			setFinancials([demoFinancialFirst, demoFinancialSecond, demoFinancialThird]);
			localStorage.setItem(
				'selected-financials',
				JSON.stringify([demoFinancialFirst, demoFinancialSecond, demoFinancialThird])
			);
			setCheckedFinancialsHandler(demoFinancials);
			localStorage.setItem('pre-loaded-financials', JSON.stringify(demoFinancials));
			localStorage.setItem('financials', JSON.stringify(demoFinancials));
			localStorage.setItem('first-financial', JSON.stringify(demoFinancials[0]));
			localStorage.setItem('second-financial', JSON.stringify(demoFinancials[1]));
			localStorage.setItem('third-financial', JSON.stringify(demoFinancials[2]));
			localStorage.setItem(
				'selected-financials',
				JSON.stringify([
					demoFinancials[0].financials_id,
					demoFinancials[1].financials_id,
					demoFinancials[2].financials_id
				])
			);
		}

		// moving (and rewriting) this as it only needs to execute if company_id is selected
		// and company_id can only be selected/exist if companies exists
		// axios.post(apiUrl + backendRoutes.financials.get, {
		// 	company_id:
		// 	event
		// }).then((response) => {
		// 	if (response.status !== 200) {
		// 		return;
		// 	}
		// 	if (typeof response.data !== 'string') {
		// 		setCheckedFinancialsHandler(response.data);
		// 		localStorage.setItem('pre-loaded-financials', JSON.stringify(response.data));
		// 		localStorage.setItem('financials', JSON.stringify(response.data));
		// 		setFinancials(response.data);
		// 		setSelectedFinancialsHandler(response.data);
		// 		// const findIfThereChecked = (response.data as FinancialsModel[]).map((item) =>
		// 		// item.financials_id);
		// 		findSelectedFinancials(response.data);
		// 	} else if (typeof response.data === 'string') {
		// 		if (loggedInUser) {
		// 			// TOREVIEW:
		// 			// redundant: if id > 1 then in the same time it is not equal to one
		// 			// was there another intended usecase?
		// 			if (loggedInUser.plan.id !== 1 && loggedInUser.plan.id > 1) {
		// 				setFinancials([]);
		// 				localStorage.setItem('selected-financials', JSON.stringify([]));
		// 			} else if (loggedInUser.plan.id === 1) {
		// 				setSelectedFinancialsHandler(demoFinancials);
		// 				setFinancials(demoFinancials);
		// 				setCheckedFinancialsHandler(demoFinancials);
		// 				localStorage.setItem('pre-loaded-financials', JSON.stringify(demoFinancials));
		// 				localStorage.setItem('financials', JSON.stringify(demoFinancials));
		// 				localStorage.setItem('first-financial', JSON.stringify(demoFinancials[0]));
		// 				localStorage.setItem('second-financial', JSON.stringify(demoFinancials[1]));
		// 				localStorage.setItem('third-financial', JSON.stringify(demoFinancials[2]));
		// 				localStorage.setItem('selected-financials', JSON.stringify([
		// 					demoFinancials[0].financials_id,
		// 					demoFinancials[1].financials_id,
		// 					demoFinancials[2].financials_id
		// 				]));
		// 			}
		// 		}
		// 	}
		// });

		changeCompanyFromHeaderHandler(event);
	}

	async function getCompaniesHandler(setCompany?: CompanyDbModel) {
		await axios
			.get(apiUrl + backendRoutes.companies)
			.then(({ data }) => {
				// TOREVIEW: setCompanies will set the data async, wich means
				// it will not be ready for getFinancialsFromSeledctedCompany to properly parse
				// the updated company data, either move the logic to setCompanies
				// or provide the company data as alternative parameter
				// I will use the second approach
				setCompanies(data);
				if (data.length === 1) {
					getFinancialsFromSelectedCompany((data[0] as CompanyDbModel).company_id);
					localStorage.setItem('selected-company', JSON.stringify(data[0]));
					getPaymentHistoryHandler(data[0].company_id);
				} else if (data.length > 1) {
					localStorage.setItem('companies', JSON.stringify(data));
					localStorage.setItem('pre-loaded-financials', JSON.stringify(''));
					const getSelectedCompany: CompanyDbModel =
						setCompany || JSON.parse(localStorage.getItem('selected-company') as string);
					if (getSelectedCompany) {
						getFinancialsFromSelectedCompany(getSelectedCompany.company_id, data);
					}
				}
				if (data === 'no companies found') {
					localStorage.removeItem('selected-company');
				}
				return data;
			})
			.catch((error) => console.error(error.message));
	}

	function getSelectedDashboardCharts() {
		axios
			.get(apiUrl + backendRoutes.getDashboardSelectedCharts)
			.then((result) => setSelectedCharts(result.data));
	}

	function saveSelectedDashboardCharts(event: string[]) {
		axios.post(apiUrl + backendRoutes.updateSelectedCharts, {
			selectedDashboardCharts: event
		});
	}

	useEffect(() => {
		if (!isAuthenticated) return;
		getCompaniesHandler();
		getSelectedDashboardCharts();
		getSelectedFinancials();
		loadPlans();
		if (JSON.parse(localStorage.getItem('selected-company') as string)) {
			setSelectedCompany(JSON.parse(localStorage.getItem('selected-company') as string));
		}
		if (JSON.parse(localStorage.getItem('financials') as string)) {
			setFinancials(JSON.parse(localStorage.getItem('financials') as string));
		}
		if (JSON.parse(localStorage.getItem('companies') as string)) {
			setCompanies(JSON.parse(localStorage.getItem('companies') as string));
		}
		if (JSON.parse(localStorage.getItem('selected-financials') as string)) {
			setSelectedFinancials(
				JSON.parse(localStorage.getItem('selected-financials-from-charts') as string)
			);
		}
	}, [isAuthenticated]);

	function activateUserHandler(planName: string): void {
		console.log(planName);
	}

	async function signInHandler() {
		// fetch the user info from BE
		if (getCookieValue('accesstoken')) {
			// get the logged-in user
			await axios
				.get(`${apiUrl}/account/get`)
				.then((response) => {
					if (response.status === 200) {
						setLoggedInUser(response.data);
						activateUserHandler(loggedInUser?.plan.title as string);
					} else {
						// eslint-disable-next-line no-alert
						alert('an error occurred while sending your invite');
					}
				})
				.catch((e) => {
					// eslint-disable-next-line no-console
					console.error(e);
				});
		}
	}

	// function setCorrectUserHandler(user : UserModel) {
	// 	setIsCorrectUser(true);
	// 	localStorage.setItem('plan', JSON.stringify(user?.plan));
	// 	if (user && user.plan.id === 1) {
	// 		// 1 === "Basic Plan"
	// 		localStorage.setItem('isDemoActive', JSON.stringify(true));
	// 	} else {
	// 		localStorage.setItem('isDemoActive', JSON.stringify(false));
	// 	}
	// }

	function updatePlan(plan: PlanModel) {
		// TOREVIEW: we no longer use users to determine the plan
		// the plans are now associated with companies, so update the
		// plan for selectedCompany
		// if (loggedInUser) {
		// 	loggedInUser.plan = plan;
		// 	setCorrectUserHandler(loggedInUser);
		// }

		// direct assignement of properties should be avoided
		// better to use reducer, but let's leave this for future improvement
		selectedCompany.plan = plan;
	}

	function getAvailablePlans(): PlanModel[] | null {
		if (availablePlans) {
			return availablePlans;
		}
		return null;
	}

	async function updatePlanHandlerDepercated(event: PaymentInterface[] | string) {
		if (typeof event === 'string' || !event) {
			await axios.post(apiUrl + backendRoutes.account.updatePlan, {
				planId: 1,
				companyId: selectedCompany.company_id
			});
			setCompanyPlan(1);
			return;
		}
		event.forEach((item) => {
			const now = new Date();
			const expiresOn = item.payment_expires;
			const lastPaymentExpires = new Date(expiresOn);
			const daysLeft = lastPaymentExpires.getTime() - now.getTime();
			let expireDaysLeft: number | undefined | string;

			if (now.getTime() < lastPaymentExpires.getTime()) {
				expireDaysLeft = Math.ceil(daysLeft / (1000 * 3600 * 24)).toString();
			}
			if (!expireDaysLeft) {
				return;
			}
			if (expireDaysLeft === 0) {
				axios.post(apiUrl + backendRoutes.account.updatePlan, {
					planId: 1,
					companyId: selectedCompany.company_id
				});
				setCompanyPlan(1);
				localStorage.setItem('isDemoActive', JSON.stringify(true));
				return;
			}
			if (item.payment_details.purchase_units[0].description === 'Pro Plan') {
				axios.post(apiUrl + backendRoutes.account.updatePlan, {
					planId: 3,
					companyId: selectedCompany.company_id
				});
				setCompanyPlan(3);
				localStorage.setItem('isDemoActive', JSON.stringify(false));
				return;
			}
			if (item.payment_details.purchase_units[0].description === 'Grow Plan') {
				axios.post(apiUrl + backendRoutes.account.updatePlan, {
					planId: 2,
					companyId: selectedCompany.company_id
				});
				setCompanyPlan(2);
				localStorage.setItem('isDemoActive', JSON.stringify(false));
			} else {
				axios.post(apiUrl + backendRoutes.account.updatePlan, {
					planId: 1,
					companyId: selectedCompany.company_id
				});
				setCompanyPlan(1);
				localStorage.setItem('isDemoActive', JSON.stringify(true));
			}
		});
		await fetchAccount();
	}

	function getDemoUserData(): void {
		axios.post(apiUrl + backendRoutes.financials.get, demoCompanyId).then((response) => {
			localStorage.setItem(
				'selected-financials',
				JSON.stringify([response.data[0].financials_id, response.data[1].financials_id])
			);
			localStorage.setItem('financials', JSON.stringify(response.data));
		});
	}

	function closeNavBarHandler(element: boolean): void {
		setIsNavbarOpen(element);
	}

	function selectedItemsHandler(event: string): void {
		setSelectedItems((prevState) => {
			findSelectedFinancials([...prevState, event]);
			return [...prevState, event];
		});
	}

	function unselectedItemHandler(event: string): void {
		setSelectedItems((prevState) => {
			const deselected = prevState.filter((item) => item !== event);
			findSelectedFinancials(deselected);
			return deselected;
		});
	}
	useEffect(() => {
		if (selectedCommonFinancials.length === 1) {
			localStorage.removeItem('second-financial');
			localStorage.removeItem('third-financial');
		}

		if (whatIsChecked === 0 && selectedItems?.length === 2) {
			localStorage.removeItem('third-financial');
			setClassForPopup(styles.collapseContainerGreen);
		} else if (whatIsChecked === 0 && selectedItems?.length !== 2) {
			setClassForPopup(styles.collapseContainer);
		} else if (whatIsChecked === 1 && selectedItems?.length === 1) {
			setClassForPopup(styles.collapseContainerGreen);
		} else if (whatIsChecked === 1 && selectedItems?.length !== 1) {
			setClassForPopup(styles.collapseContainer);
		} else if (whatIsChecked === 2 && selectedItems?.length !== 3) {
			setClassForPopup(styles.collapseContainer);
		} else if (whatIsChecked === 2 && selectedItems?.length === 3) {
			setClassForPopup(styles.collapseContainerGreen);
		}
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [whatIsChecked, selectedItems.length]);

	function nextButtonHandler() {
		axios
			.post(apiUrl + backendRoutes.updateSelectedFinancials, {
				selectedFinancials: selectedFinancialsId
			})
			.then((result) => console.log(result));
		setPopupClass(styles.scalePopup);
		setTimeout(() => {
			setPopupClass('');
		}, 1000);
		const financialsSelected = (financials as FinancialsModel[]).filter((item) =>
			selectedFinancials.includes(item.financials_id)
		);
		getSelectedFinancials();
		setCheckedFinancialsHandler(financialsSelected);
	}

	function isCheckedCardHandler(id: string | undefined): void {
		if (id === 'moneyMultiplier') {
			setWhatIsChecked(0);
		} else if (id === 'moneyForGrowth') {
			setWhatIsChecked(1);
		} else if (id === 'cashFlowAnalysis') {
			setWhatIsChecked(2);
		}
	}

	useEffect(() => {
		const route: string = window.location.href.split('/')[3];

		if (route === 'cash-flow-picture') {
			setWhatIsChecked(2);
		} else if (route === 'money-for-growth') {
			setWhatIsChecked(1);
		} else if (route === 'financials-context.tsx:154 money-for-ceos') {
			setWhatIsChecked(0);
		}
	}, []);

	// eslint-disable-next-line react/jsx-no-constructed-context-values
	const contextValue = {
		setIsAuthenticated,
		companies,
		getCompaniesHandler,
		signInHandler,
		updatePlan,
		getAvailablePlans,
		loggedInUser,
		isCorrectUser,
		getDemoUserData,
		closeNavBarHandler,
		isNavbarOpen,
		getFinancialsFromSelectedCompany,
		financials,
		getSelectedFinancials,
		selectedFinancials,
		payload,
		recordUpdated,
		financialsId,
		isCompanySelected,
		companyType,
		selectedIndustryForEbitda,
		checkedFinancials,
		selectedCommonFinancials,
		selectedCompany,
		selectedCharts,
		saveSelectedDashboardCharts,
		getSelectedDashboardCharts,
		fetchAccount,
		account,
		setLoggedInUser,
		setCompanies,
		payments,
		activateUserHandler,
		companyPlan,
		setCheckedFinancialsHandler,
		whatIsChecked,
		classForPopup,
		nextButtonHandler,
		isCheckedCardHandler,
		popupClass,
		selectedItems,
		selectedItemsHandler,
		loadedSelectedItemsHandler,
		unselectedItemHandler
	};
	const { children } = props;
	return <GlobalStateContext.Provider value={contextValue}>{children}</GlobalStateContext.Provider>;
};

export default GlobalStateContextProvider;
