import { AdyenCheckout, Card } from '@adyen/adyen-web';
import '@adyen/adyen-web/styles/adyen.css';
import '../../../assets/js/digitalapps-payments-for-adyen-card.css';
import { getAdyenCardStyles } from '../../../assets/js/adyen-card-styles';

const { createElement, useEffect, useRef, useState } = window.wp.element;
const { __ } = window.wp.i18n;
const { decodeEntities } = window.wp.htmlEntities;

// Get the registration function and settings from WooCommerce Blocks
const { registerPaymentMethod } = window.wc.wcBlocksRegistry;
const settings = window.wc.wcSettings.getSetting( 'digitalapps_payments_for_adyen_card_data', {} );

const getBrowserInfo = () => ( {
	acceptHeader: '*/*',
	colorDepth: window.screen.colorDepth,
	javaEnabled: navigator.javaEnabled ? navigator.javaEnabled() : false,
	javaScriptEnabled: true,
	language: navigator.language || 'en-US',
	screenHeight: window.screen.height,
	screenWidth: window.screen.width,
	timeZoneOffset: new Date().getTimezoneOffset(),
	userAgent: navigator.userAgent,
} );

/**
 * Payment method label component
 *
 * @param {Object} props Component properties.
 * @return {Element} Payment method label.
 */
const Label = ( props ) => {
	const { PaymentMethodLabel } = props.components;
	return createElement( PaymentMethodLabel, {
		text: decodeEntities( settings?.title || __( 'Credit/Debit Card (Adyen)', 'digital-apps-payments-for-adyen' ) ),
	} );
};

/**
 * Payment method content component
 *
 * @param {Object} props Component properties.
 * @return {Element} Payment method content.
 */
const Content = ( props ) => {
	const containerRef = useRef( null );
	const [ isLoading, setIsLoading ] = useState( true );
	const [ error, setError ] = useState( null );
	const { eventRegistration, emitResponse } = props || {};
	const { onPaymentSetup, onPaymentProcessing } = eventRegistration || {};
	const errorResponseType = emitResponse?.responseTypes?.ERROR;
	const successResponseType = emitResponse?.responseTypes?.SUCCESS;

	const cardComponentRef = useRef( null );
	const cardStateRef = useRef( null );

	// Register payment processing callbacks
	useEffect( () => {
		if ( ! onPaymentProcessing && ! onPaymentSetup ) {
			return undefined;
		}

		const preparePaymentData = async () => {
			if ( ! cardComponentRef.current ) {
				return {
					type: errorResponseType,
					message: __( 'Payment form not initialized', 'digital-apps-payments-for-adyen' ),
				};
			}

			try {
				const state = cardStateRef.current;
				if ( ! state?.isValid || ! state?.data?.paymentMethod ) {
					cardComponentRef.current.showValidation();
					return {
						type: errorResponseType,
						message: __( 'Please complete your card details.', 'digital-apps-payments-for-adyen' ),
					};
				}

				const paymentData = {
					...state.data,
					browserInfo: getBrowserInfo(),
				};

				return {
					type: successResponseType,
					meta: {
						paymentMethodData: {
							digitalapps_payments_for_adyen_card_state: JSON.stringify( paymentData ),
						},
					},
				};
			} catch {
				return {
					type: errorResponseType,
					message: __( 'Payment processing failed', 'digital-apps-payments-for-adyen' ),
				};
			}
		};

		// Register payment processing callback
		const unsubscribeProcessing =
			onPaymentProcessing &&
			onPaymentProcessing( preparePaymentData );

		// WooCommerce versions differ on which checkout event supplies payment data.
		const unsubscribeSetup =
			onPaymentSetup &&
			onPaymentSetup( preparePaymentData );

		// Cleanup subscriptions
		return () => {
			if ( unsubscribeProcessing ) {
				unsubscribeProcessing();
			}
			if ( unsubscribeSetup ) {
				unsubscribeSetup();
			}
		};
	// WooCommerce may recreate these wrapper objects and functions during checkout
	// renders. Register once per mounted payment-method instance to avoid a
	// registration-triggered render loop.
	// eslint-disable-next-line react-hooks/exhaustive-deps
	}, [] );

	useEffect( () => {
		( async function initialize() {
			if ( ! settings.clientKey ) {
				setError( __( 'Adyen configuration error: missing client key', 'digital-apps-payments-for-adyen' ) );
				setIsLoading( false );
				return;
			}
			try {
				const checkout = await AdyenCheckout( {
					clientKey: settings.clientKey,
					countryCode: settings.countryCode || 'US',
					environment: settings.environment || 'test',
					locale: settings.locale || 'en-US',
					analytics: { enabled: settings.analyticsEnabled || false },
					onError: () => {
						setError( __( 'Payment processing failed. Please try again.', 'digital-apps-payments-for-adyen' ) );
					},
				} );

				const cardComponent = new Card( checkout, {
					showPayButton: false,
					enableStoreDetails: false,
					hasHolderName: true,
					holderNameRequired: true,
					billingAddressRequired: false,
					styles: getAdyenCardStyles( containerRef.current ),
					onChange: ( state ) => {
						cardStateRef.current = state;
					},
				} );

				cardComponent.mount( containerRef.current );
				cardComponentRef.current = cardComponent;
			} catch {
				setError( __( 'Failed to initialize Adyen Checkout.', 'digital-apps-payments-for-adyen' ) );
			} finally {
				setIsLoading( false );
			}
		} )();

		// Cleanup
		return () => {
			if ( cardComponentRef.current ) {
				try {
					cardComponentRef.current.remove();
				} catch {
					// Ignore unmount errors
				}
				cardComponentRef.current = null;
				cardStateRef.current = null;
			}
		};
	}, [] );

	if ( error ) {
		return createElement( 'div', { className: 'digitalapps-payments-for-adyen-error digitalAppsAdyenCard__error' }, error );
	}

	return createElement( 'div', { className: 'digitalapps-payments-for-adyen-card-payment-method digitalAppsAdyenCard__paymentMethod' }, [
		isLoading
			? createElement(
					'div',
					{
						key: 'loading',
						className: 'digitalapps-payments-for-adyen-loading digitalAppsAdyenCard__loading',
					},
					__( 'Loading payment form…', 'digital-apps-payments-for-adyen' )
			  )
			: null,
		createElement( 'div', {
			key: 'card-container',
			id: 'digitalapps-payments-for-adyen-card-component',
			className: 'digitalAppsAdyenCard',
			ref: containerRef,
		} ),
	] );
};

/**
 * Register the payment method with WooCommerce Blocks
 */
const adyenCardPaymentMethod = {
	name: 'digitalapps_payments_for_adyen_card',
	label: createElement( Label ),
	content: createElement( Content ),
	edit: createElement( Content ),
	canMakePayment: () => Boolean( settings?.clientKey ),
	ariaLabel: __( 'Adyen Card Payment', 'digital-apps-payments-for-adyen' ),
	supports: {
		features: settings?.supports?.features || [ 'products', 'refunds' ],
		showSavedCards: settings?.supports?.showSavedCards ?? false,
		showSaveOption: settings?.supports?.showSaveOption ?? false,
	},
};

registerPaymentMethod( adyenCardPaymentMethod );
