/* eslint-disable react/destructuring-assignment */
/* eslint-disable @typescript-eslint/no-unused-vars */
import type { ReactNode } from 'react';
import type React from 'react';
import { createContext, useContext, useDeferredValue, useState } from 'react';

import type { PaymentInterface } from '../../Pages/ManageSubscription/ManageSubscription';
import type { GlobalStateModel } from '../global/GlobalState-context';
import { GlobalStateContext } from '../global/GlobalState-context';
import type { PlanModel } from '../User/user-context.helper';

interface ShouldAskForPaymentPropsInterface {
	idPlan: number;
	paymentHistory: PaymentInterface[] | string;
	currentPlan: PlanModel | null;
}

export type ManageSubscriptionContextModel = {
	shouldAskForPayment: (props: ShouldAskForPaymentPropsInterface) => boolean;
	paymentProceed: boolean;
	makeNewPaymentHandler: (payment: boolean) => void;
	askForPayment: boolean;
};

export const ManageSubscriptionContext: React.Context<ManageSubscriptionContextModel> =
	createContext<ManageSubscriptionContextModel>({
		shouldAskForPayment: () => false,
		paymentProceed: false,
		makeNewPaymentHandler(): void {},
		askForPayment: false
	});

const ManageSubscriptionProvider: React.FC<{ children: ReactNode }> = (props: {
	children: ReactNode;
}) => {
	const [paymentProceed, setPaymentProceed] = useState<boolean>(false);
	const makeNewPayment = JSON.parse(localStorage.getItem('makeNewPayment') as string);
	const [paymentsExpireDays, setPaymentsExpireDays] = useState<string[]>([]);
	const globalContext: GlobalStateModel = useContext<GlobalStateModel>(GlobalStateContext);
	const [askForPayment, setAskForPayment] = useState<boolean>(false);

	//
	function calculateRemainingDays(filteredPayment: PaymentInterface[]): number {
		const now = new Date();
		const paymentsExpireDaysArray: string[] = [];
		filteredPayment.forEach((payment: PaymentInterface) => {
			const lastPaymentExpires = new Date(payment.payment_expires);
			const daysLeft = lastPaymentExpires.getTime() - now.getTime();
			const expireDaysLeft = Math.ceil(daysLeft / (1000 * 3600 * 24)).toString();
			paymentsExpireDaysArray.push(expireDaysLeft);
		});
		const remainingDays = paymentsExpireDaysArray.reduce(
			(previousValue, currentValue) => +previousValue + +currentValue,
			0
		);
		return remainingDays;
	}

	const deferredAvailablePlans: PlanModel[] | null = useDeferredValue(
		globalContext.getAvailablePlans()
	);
	const getPrepaidPlanByTitle = (planTitle: string): PlanModel | undefined =>
		deferredAvailablePlans?.filter((plan) => plan.title === planTitle)[0];
	function shouldAskForPayment(el: ShouldAskForPaymentPropsInterface): boolean {
		const now = new Date();
		if (+el.idPlan === 0 || +el.idPlan === -1) {
			setAskForPayment(false);
			return false;
		}

		if (makeNewPayment) {
			setAskForPayment(true);
			return true;
		}
		let remainingDaysFromAllPayments = 0;
		if (Array.isArray(el.paymentHistory) && el.paymentHistory.length > 0) {
			const filteredProPlanPayments = el.paymentHistory.filter(
				(item) => item.payment_details.purchase_units[0].description === 'Pro Plan'
			);
			const filteredGrowPlanPayments = el.paymentHistory.filter(
				(item) => item.payment_details.purchase_units[0].description === 'Grow Plan'
			);
			if (filteredProPlanPayments.length === 0 && filteredGrowPlanPayments.length > 0) {
				remainingDaysFromAllPayments = calculateRemainingDays(filteredGrowPlanPayments);
			} else if (filteredProPlanPayments.length > 0) {
				remainingDaysFromAllPayments = calculateRemainingDays(filteredProPlanPayments);
			}
			// TODO check calculations and put storageSetItem for loggedin here
			const lastPayment: PaymentInterface = el.paymentHistory.at(-1) as PaymentInterface;
			const prepaidPlan: PlanModel | undefined = getPrepaidPlanByTitle(
				lastPayment.payment_details.purchase_units[0].description
			);
			if (
				(prepaidPlan?.title === 'Basic Plan' && el.currentPlan?.title === 'Grow Plan') ||
				(prepaidPlan?.title === 'Grow Plan' && el.currentPlan?.title === 'Pro Plan')
			) {
				setAskForPayment(true);
				return true;
			}

			if (prepaidPlan) {
				const lastPaymentExpires = new Date(lastPayment.payment_expires);
				if (now > lastPaymentExpires) {
					// Payment has expired, return true if current plan id > 0
					// return !(currentPlan?.id === 1);
					setAskForPayment(el.currentPlan?.id === 1);
					return el.currentPlan?.id === 1;
				}

				// payment has not expired
				if (el.currentPlan && (el.currentPlan as PlanModel).id === 1) {
					// don't ask for payment if plan is Basic or
					// the new plan is lower or equal to the paid one
					setAskForPayment(false);
					return false;
				}

				// ask for payment in any other case
				setAskForPayment(true);
				return true;
			}
		}
		setAskForPayment(true);
		return true;
	}

	function makeNewPaymentHandler(payment: boolean): void {
		localStorage.setItem('makeNewPayment', JSON.stringify(false));
	}

	// eslint-disable-next-line react/jsx-no-constructed-context-values
	const contextValue = {
		shouldAskForPayment,
		paymentProceed,
		makeNewPaymentHandler,
		askForPayment
	};
	return (
		<ManageSubscriptionContext.Provider value={contextValue}>
			{props.children}
		</ManageSubscriptionContext.Provider>
	);
};

export default ManageSubscriptionProvider;
