/**
 * PrepayPayment: fetches PrePay balance, shows insufficient-balance warning or
 * "Pay with PrePay" button.
 */
import { useState, useCallback, useEffect } from '@wordpress/element';
import { __, sprintf } from '@wordpress/i18n';
import { Button, Flex, Notice } from '@wordpress/components';
import { Spinner } from '@woocommerce/components';
import type { GenericPaymentResponse, PrePayBalance } from '../../../types';
import { PaymentOrderResponse } from '../../../types/payment';
import { formatCurrency } from '../../utils';
import { useParcel2goAuth, usePrepay } from '../../hooks';

interface PrePayPaymentProps {
	paymentOrder: PaymentOrderResponse;
	total: number;
	onSuccess: (response: GenericPaymentResponse, paymentOrder: PaymentOrderResponse) => void;
}

export default function PrePayPayment({
	paymentOrder,
	total,
	onSuccess,
}: PrePayPaymentProps) {
	const { isLinked } = useParcel2goAuth();
	const { fetchBalance, makePrepayPayment, isPrepayLoading, prepayError } =
		usePrepay();
	const [prepayBalance, setPrepayBalance] = useState<PrePayBalance | null>(
		null
	);
	const [paying, setPaying] = useState(false);

	const { orderId, hash } = paymentOrder.orderResult;

	useEffect(() => {
		if (isLinked) {
			fetchBalance().then(setPrepayBalance);
		}
	}, [fetchBalance, isLinked]);

	const handleSubmit = useCallback(async () => {
		setPaying(true);
		const response = await makePrepayPayment(orderId, hash);
		if (response) {
			onSuccess(response, paymentOrder);
		}
		setPaying(false);
	}, [orderId, hash, onSuccess]);

	if (isPrepayLoading) {
		return (
			<Flex align="center" justify="center" style={{ padding: 16 }}>
				<Spinner />
			</Flex>
		);
	}

	if (prepayError && !prepayBalance) {
		return (
			<Notice status="error" isDismissible={false}>
				{prepayError}
			</Notice>
		);
	}

	if (
		!prepayBalance ||
		!prepayBalance.balance ||
		prepayBalance.balance === 0
	) {
		return null;
	}

	if (prepayBalance.balance < total) {
		return (
			<Notice status="warning" isDismissible={false}>
				{sprintf(
					__(
						'Your current PrePay balance is %s.',
						'parcel2go-shipping'
					),
					formatCurrency(
						prepayBalance.balance,
						prepayBalance.currency
					)
				)}{' '}
				{sprintf(
					__(
						"To complete this order, you'll need to add %s.",
						'parcel2go-shipping'
					),
					formatCurrency(
						total - prepayBalance.balance,
						prepayBalance.currency
					)
				)}
			</Notice>
		);
	}

	return (
		<Flex direction="column" gap={3}>
			{prepayError && (
				<Notice status="error" isDismissible={false}>
					{prepayError}
				</Notice>
			)}
			<strong>
				{sprintf(
					__('Use your PrePay balance of %s', 'parcel2go-shipping'),
					formatCurrency(
						prepayBalance.balance,
						prepayBalance.currency
					)
				)}
			</strong>
			<Button
				variant="primary"
				onClick={handleSubmit}
				isBusy={paying}
				disabled={paying}
			>
				{__('Pay with PrePay', 'parcel2go-shipping')}
			</Button>
		</Flex>
	);
}
