'use client'

import DropDownList from '@/app/components/DropDownList';
import { useTranslations } from 'next-intl';
import { ChangeEvent, useState, useActionState, useEffect } from 'react';
import BankCardInput from '@/app/ui/inputs/bank-card-inpit';
import { addPayoutMethod, PayoutMethodFormState, getPayoutMethods, PayoutMethods } from '@/app/actions/referralsActions';
import { bankCardFormSchema } from '@/app/actions/definitions';
import { useQuery, useQueryClient } from '@tanstack/react-query';
import { toast } from 'sonner';
import valid from 'card-validator';

interface cardInfoType {
	cardType: string,
	potentiallyValid: boolean,
	cardValid?: boolean
}

export default function SettingReferralProgram() {
	const [state, formAction, isPending] = useActionState(
		addPayoutMethod,
		undefined,
	);

	const {
		data: payoutMethods,
		error
	} = useQuery({
		queryKey: ['payoutMethods'],
		queryFn: () => {
			return getPayoutMethods();
		},
		select: (data) => {
			if (data?.methods) {
				return data?.methods
			} else {
				return []
			};
		}
	});

	const [formState, setFormState] = useState<PayoutMethodFormState | undefined>(undefined);
	const [paymentsType, setPaymentsType] = useState('bank-card');
	const [defaultCardNumber, setDefaultCardNumber] = useState<PayoutMethods | undefined>(undefined);
	const [isEditing, setIsEditing] = useState(false);
	const [cardInfo, setCardInfo] = useState<null | cardInfoType>(null);
	const [initialCardInfo, setInitialCardInfo] = useState<null | cardInfoType>(null);
	const queryClient = useQueryClient();
	const t = useTranslations('Global');

	useEffect(() => {
		setFormState(state);
		if (state?.success) {
			toast.success('success');
			setIsEditing(false);
			queryClient.invalidateQueries({ queryKey: ['payoutMethods'] });
		}

	}, [state]);

	useEffect(() => {
		if (payoutMethods) {
			payoutMethods.forEach(e => {
				if (e.default) {
					const numberValidation = valid.number(e.cardNumber);
					if (numberValidation.card) {
						setCardInfo({
							cardType: numberValidation.card.type,
							potentiallyValid: numberValidation.isPotentiallyValid
						});
						setInitialCardInfo({
							cardType: numberValidation.card.type,
							potentiallyValid: numberValidation.isPotentiallyValid
						})
					}
					setDefaultCardNumber(e);
				}
			})
		}
	}, [payoutMethods])

	async function validateField(
		fieldName: string,
		value: string,
	) {
		switch (fieldName) {
			case 'bankCard':
				const schema = bankCardFormSchema?.shape[fieldName];
				if (!schema) {
					return { success: true, data: value };
				}

				return schema.safeParse(value);

			default:
				throw new Error(`Unknown field: ${fieldName}`);
		}
	}

	async function onChangeHandler(e: ChangeEvent<HTMLInputElement>): Promise<void> {
		const fieldName = e.target.name;
		const validatedField = await validateField(fieldName, e.target.value);
		const numberValidation = valid.number(e.target.value);

		if (numberValidation.card) {
			setCardInfo({
				cardType: numberValidation.card.type,
				potentiallyValid: numberValidation.isPotentiallyValid,
				cardValid: true
			});
		}

		if (e.target.value.length === 19 && !numberValidation.isValid) {
			setCardInfo((prev) => {
				if (prev) {
					return {
						...prev,
						cardValid: false
					}
				}
				return null;
			})
		}

		if (validatedField.success) {
			setFormState(prevState => {
				if (!prevState?.error || !prevState?.error[fieldName]) {
					return {
						previousState: prevState?.previousState,
						error: {
							server: null
						}
					};
				}

				const { [fieldName]: _, ...newError } = prevState.error;

				return {
					previousState: prevState?.previousState,
					error: {
						...newError,
						server: null
					}
				};
			});
		}
	}

	return (
		<div className="block-wrapper setting-referral-program">

			<div className="section-title">
				{t('referral-program-settings')}
			</div>

			<form
				action={(e) => {
					formAction(e);
				}}
				className="settings-form"
			>
				<div className="settings-form-wrapper">
					<h4>{t('payout-settings')}</h4>

					<div className="form-group">
						<label>{t('preferred-payment-method')}</label>
						<DropDownList
							value={paymentsType}
							translatedValue={
								(() => {
									switch (paymentsType) {
										case 'on-account-balance':
											return t('on-account-balance')
										case 'bank-card':
											return t('bank-card')
										case 'bank-transfer':
											return t('bank-transfer')
									}
								})()
							}
							callBack={setPaymentsType}
						>
							<li value="on-account-balance">
								{t('on-account-balance')}
							</li>
							<li value="bank-card">
								{t('bank-card')}
							</li>
							<li value="bank-transfer">
								{t('bank-transfer')}
							</li>
						</DropDownList>
						<input
							type="hidden"
							id="paymentsType"
							name="paymentsType"
							className={``}
							value={paymentsType}
						/>
					</div>
					{paymentsType === 'bank-card' && (
						<div>
							<h4>
								{t('bank-card-number')}
							</h4>
							<div
								className="relative"
							>
								<BankCardInput
									bankCardState={defaultCardNumber?.cardNumber}
									validateHandler={onChangeHandler}
									disabled={!isEditing}
									isValid={cardInfo?.cardValid}
								/>
								{/*  */}
								{cardInfo && (
									<div
										className="card-type"
									>
										{cardInfo.cardType}
									</div>
								)}
							</div>
							{cardInfo?.cardValid === false && (
								<p className="text-sm text-red-500">
									<span>
										{t('bank-card-not-valid')}
									</span>
								</p>
							)}
							{formState?.error?.bankCard && (
								<p className="text-sm text-red-500">
									{
										formState?.error?.bankCard.split('&').map((e, index) => {
											return (
												<span key={index}>
													{t(e)}
													<br />
												</span>
											)
										})
									}
								</p>
							)}
						</div>
					)}
					{formState?.error?.server && (
						<p className="text-sm text-red-500 mt-4">
							{t(formState?.error?.server)}
						</p>
					)}

					{
						isEditing ? (
							<div
								className='flex gap-4'
							>
								<button
									type="button"
									className="btn-primary"
									disabled={isPending}
									onClick={() => {
										setIsEditing(false);
										setCardInfo(initialCardInfo);
										setFormState(prevState => {
											if (!prevState?.error || !prevState?.error['bankCard']) {
												return {
													previousState: prevState?.previousState,
													error: {
														server: null
													}
												};
											}
										});
									}}
								>
									{t('cancel')}
								</button>

								<button
									type="submit"
									className="btn-primary"
									disabled={isPending || !cardInfo?.cardValid}
								>
									{t("save-changes")}
									{isPending && (
										<div className="loading-animation">
											<div className="global-spinner"></div>
										</div>
									)}
								</button>
							</div>
						) : (
							<button
								type="button"
								className="btn-primary"
								disabled={isPending}
								onClick={() => {
									setIsEditing(true)
								}}
							>
								Изменить
							</button>
						)
					}

				</div>

				<div className="settings-form-wrapper">
					<h4>{t('notifications')}</h4>

					<div className="checkbox-group">
						<input type="checkbox" name="email_notifications" defaultValue="1" />
						<label>{t('email-notifications-about-new-referrals')}</label>
					</div>
				</div>
			</form>

		</div>
	)
}