// eslint-disable-next-line object-curly-newline
import axios from 'axios';
import { useEffect, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useNavigate } from 'react-router-dom';

import type { CompanyDbModel } from './Pages/Companies/Components/CompaniesComponents.helper';
import type { FinancialsModel } from './Pages/Financials/Components/FinancialsForm/FinancialsForm.helper';
import { fetchAvailablePlans } from './ReduxState/application/applicationSlice';
import { fetchCompanyData } from './ReduxState/companies/companiesSlice';
import { fetchFinancialsData } from './ReduxState/financials/financialsSlice';
import { fetchUserData, login, logout } from './ReduxState/login/loginSlice';
import type { AppDispatch, RootState } from './ReduxState/store';
import RouterComponent from './Router/RouterComponent';
import GlobalStateContextProvider from './Store/global/GlobalState-context';
import { UiProvider } from './Store/UiContext/UiContext';
import type { PlanModel, UserModel } from './Store/User/user-context.helper';
import getCookieValue from './utils/getCookieValue';
import './App.css';
import { fetchPaymentData } from './ReduxState/payment/paymentHistorySlice';
import type { PaymentInterface } from './Pages/ManageSubscription/ManageSubscription';

const App = (): JSX.Element => {
	/** * NEW start */
	const navigate = useNavigate();
	const dispatch = useDispatch<AppDispatch>();
	const availablePlans: PlanModel[] | null = useSelector(
		(state: RootState) => state.applicationGlobal.availablePlans
	);
	const user: UserModel = useSelector((state: RootState) => state.login.user);
	const userLoggedIn: boolean = useSelector((state: RootState) => state.login.isLoggedIn);
	const userFetched: boolean = useSelector((state: RootState) => state.login.fetchingFinished);
	const [branding, setBranding] = useState<CompanyDbModel['branding'] | null>(null);
	const companies: CompanyDbModel[] | null = useSelector(
		(state: RootState) => state.companies.companiesList
	);
	const selectedCompany: CompanyDbModel | null = useSelector(
		(state: RootState) => state.companies.selectedCompany
	);
	const latestPayment: PaymentInterface | null | undefined = useSelector(
		(state: RootState) => state.payment.latestPayment
	);
	const isPaymentExpired: boolean = useSelector((state: RootState) => state.payment.paymentExpired);
	const financials: FinancialsModel[] | null = useSelector(
		(state: RootState) => state.financials.financialsList
	);

	const darkenColor = (hex: string, amount = 10) => {
		// Convert hex to RGB
		let r = parseInt(hex.slice(1, 3), 16);
		let g = parseInt(hex.slice(3, 5), 16);
		let b = parseInt(hex.slice(5, 7), 16);

		// Darken each channel by the specified percentage
		r = Math.floor(r * (1 - amount / 100));
		g = Math.floor(g * (1 - amount / 100));
		b = Math.floor(b * (1 - amount / 100));

		// Convert back to hex
		const toHex = (c: any) => c.toString(16).padStart(2, '0');

		return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
	};

	// const loginStatusChecked = useRef(false);
	// useEffect(() => {
	// 	if (userLoggedIn) {
	// 		if (!user) {
	// 			console.log('IS LOGGED IN but missing user data in Layout I will dispatch fetch');
	// 			console.log('missing user data in APP I will dispatch fetch');
	// 			dispatch(fetchUserData());
	// 		}
	// 	} else if (loginStatusChecked.current) {
	// 		console.log('navigating to / as user is NOT LOGGED IN');
	// 		navigate('/');
	// 	}
	// 	if (!loginStatusChecked.current) {
	// 		loginStatusChecked.current = true;
	// 	}
	// }, [userLoggedIn]);
	// }, [dispatch, userLoggedIn]);

	useEffect(() => {
		if (user) {
			if (!companies) {
				console.log('IS LOGGED IN but missing company data in Layout I will dispatch fetch');
				console.log('> missing companies data in APP I will dispatch fetch');
				dispatch(fetchCompanyData());
			}
		}
	}, [dispatch, user]);

	useEffect(() => {
		if (selectedCompany?.branding) {
			setBranding(selectedCompany.branding);
		} else {
			setBranding(null);
		}

		if (user && companies && selectedCompany) {
			if (!selectedCompany.plan || !selectedCompany.plan.id) {
				navigate('/manageSubscriptions');
			}
			if (!financials) {
				console.log('IS LOGGED IN but missing financials data in Layout I will dispatch fetch');
				console.log('> missing financials data in APP I will dispatch fetch');
				// dispatch(fetchFinancialsData(selectedCompany));
				dispatch(fetchPaymentData({ selectedCompany }));
			}
		}
	}, [dispatch, user, companies, selectedCompany]);

	useEffect(() => {
		if (selectedCompany?.branding) {
			setBranding(selectedCompany.branding);
		} else {
			setBranding(null);
		}

		if (user && companies && selectedCompany && latestPayment !== undefined) {
			if (!selectedCompany.plan || !selectedCompany.plan.id) {
				navigate('/manageSubscriptions');
			}

			dispatch(fetchFinancialsData({ selectedCompany, planExpired: isPaymentExpired }));
		}
		// }, [dispatch, user, companies, selectedCompany, latestPayment]);
	}, [dispatch, user, companies, selectedCompany, latestPayment, isPaymentExpired]);

	useEffect(() => {
		const interval: string | number | undefined = undefined;
		const checkIfAuthenticatedOnCognito = async (t = true) => {
			const cookieValue = await getCookieValue(['accesstoken', 'timestamp']);
			const accesstoken = (cookieValue as any)?.accesstoken;
			const timestamp = (cookieValue as any)?.timestamp;

			if (accesstoken && (accesstoken as string).length > 40) {
				// user has been authenticated on Cognito
				// dispatch async action to log in user:`
				if (t) {
					dispatch(login());
					console.log('IS LOGGED IN but missing user data in Layout I will dispatch fetch');
					console.log('missing user data in APP I will dispatch fetch');
					dispatch(fetchUserData());
				} else if (timestamp - Date.now() < 400000) {
					// 40 seconds to go until token expires
					const response = axios.get('/api/account/refreshtoken', {});
				}
			} else {
				// user is not yet authenticated on Cognito
				dispatch(logout());
				navigate('/');
			}
		};

		if (!userLoggedIn) {
			checkIfAuthenticatedOnCognito();
			const interval = setInterval(() => {
				console.log('checking if logged in!!!');
				checkIfAuthenticatedOnCognito(false);
			}, 20000); // Check every 20s
		} else if (!user) {
			console.log('IS LOGGED IN but missing user data in Layout I will dispatch fetch');
			console.log('missing user data in APP I will dispatch fetch');
			dispatch(fetchUserData());
		}

		return () => clearInterval(interval); // Clear the interval on component unmount
		// eslint-disable-next-line react-hooks/exhaustive-deps
	}, []);

	useEffect(() => {
		console.log('user:', user, 'companies:', companies);
		if (user && companies && !selectedCompany) {
			// no selected company - display add or select company
			navigate('/JoinOrAddCompany');
		}
	}, [user, companies]);

	useEffect(() => {
		console.log('companies:', companies, selectedCompany);
		// if ((!companies || companies.length === 0) && selectedCompany) {
		if (userLoggedIn && (!companies || companies.length === 0)) {
			// trigger fetch current user to make sure the hasPermanentlyDeletedCompanies is updated
			dispatch(fetchUserData());
			// the user deleted last company - redirect to join or add company
			navigate('/JoinOrAddCompany');
		}
	}, [companies]);

	useEffect(() => {
		if (!availablePlans) {
			// no info about available plans on app level - retrieve it
			dispatch(fetchAvailablePlans());
		}
	}, [availablePlans]);

	// document.documentElement.style.setProperty('--primary-color', branding?.colorHexId || '#ca1e66');
	document.documentElement.style.setProperty('--primary-color', branding?.colorHexId || '#90BE04');
	document.documentElement.style.setProperty(
		'--primary-color-dark',
		darkenColor(branding?.colorHexId || '#90BE04', 10)
	);
	document.documentElement.style.setProperty(
		'--current-company-currency',
		`'${
			typeof selectedCompany?.currency_symbol === 'string'
				? selectedCompany?.currency_symbol
				: selectedCompany?.currency_symbol.label
		}'` || '£'
	);

	/** * NEW end */

	return (
		<div className="app">
			<GlobalStateContextProvider>
				<UiProvider>
					<RouterComponent />
				</UiProvider>
			</GlobalStateContextProvider>
		</div>
	);
};

export default App;
