import {
	AdyenCheckout,
	Card,
	Redirect,
	ThreeDS2Challenge,
	ThreeDS2DeviceFingerprint,
} from '@adyen/adyen-web';
import '@adyen/adyen-web/styles/adyen.css';
import './digitalapps-payments-for-adyen-card.css';
import { createAdyenActionLifecycle } from './adyen-action-lifecycle';
import { getAdyenCardStyles } from './adyen-card-styles';

// The tree-shaken Adyen Web package does not auto-register action components.
AdyenCheckout.register( Redirect, ThreeDS2Challenge, ThreeDS2DeviceFingerprint );

async function initializeAdyenActionPage() {
	const config = window.digitalAppsPaymentsForAdyenConfig;
	const container = document.getElementById( 'digitalapps-payments-for-adyen-action-component' );
	const errorContainer = document.getElementById( 'digitalapps-payments-for-adyen-action-error' );
	const lifecycle = createAdyenActionLifecycle( config, { errorContainer } );

	try {
		const checkout = await AdyenCheckout( {
			analytics: { enabled: false },
			clientKey: config.clientKey,
			countryCode: config.countryCode,
			environment: config.environment,
			locale: config.locale,
			onAdditionalDetails: lifecycle.onAdditionalDetails,
			onPaymentCompleted: lifecycle.onPaymentCompleted,
			onPaymentFailed: lifecycle.onPaymentFailed,
			onError: lifecycle.onError,
		} );

		if ( config.redirectResult ) {
			checkout.submitDetails( { details: { redirectResult: config.redirectResult } } );
			return;
		}

		checkout.createFromAction( config.action ).mount( container );
	} catch {
		lifecycle.showActionError( config.messages?.loadFailed );
	}
}

if ( window.digitalAppsPaymentsForAdyenConfig?.actionMode ) {
	initializeAdyenActionPage();
}

( function ( $ ) {
	'use strict';

	let adyenCardComponent = null;
	let initializationToken = 0;

	function getBrowserInfo() {
		return {
			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,
		};
	}

	function showError( message ) {
		const container = document.getElementById( 'digitalapps-payments-for-adyen-card-component' );
		if ( ! container ) {
			return;
		}

		container.replaceChildren();
		const error = document.createElement( 'div' );
		error.className = 'woocommerce-error';
		error.textContent = message;
		container.appendChild( error );
	}

	function cleanupAdyenComponent() {
		initializationToken += 1;
		if ( adyenCardComponent ) {
			try {
				adyenCardComponent.remove();
			} catch {
				// The checkout fragment may already have removed the mount point.
			}
			adyenCardComponent = null;
		}

		const stateField = document.getElementById( 'digitalapps-payments-for-adyen-card-state' );
		if ( stateField ) {
			stateField.value = '';
		}
	}

	async function initializeAdyen() {
		const container = document.getElementById( 'digitalapps-payments-for-adyen-card-component' );
		if ( ! container || adyenCardComponent ) {
			return;
		}

		if ( ! window.digitalAppsPaymentsForAdyenConfig?.clientKey || ! window.digitalAppsPaymentsForAdyenConfig?.countryCode ) {
			showError( window.digitalAppsPaymentsForAdyenConfig?.messages?.missingConfig || 'The card payment form is not configured.' );
			return;
		}

		const token = ++initializationToken;

		try {
			const checkout = await AdyenCheckout( {
				analytics: { enabled: false },
				clientKey: window.digitalAppsPaymentsForAdyenConfig.clientKey,
				countryCode: window.digitalAppsPaymentsForAdyenConfig.countryCode,
				environment: window.digitalAppsPaymentsForAdyenConfig.environment || 'test',
				locale: window.digitalAppsPaymentsForAdyenConfig.locale || 'en-US',
			} );

			const component = new Card( checkout, {
				showPayButton: false,
				hasHolderName: true,
				holderNameRequired: true,
				styles: getAdyenCardStyles( container ),
				onChange: ( state ) => {
					const stateField = document.getElementById( 'digitalapps-payments-for-adyen-card-state' );
					if ( ! stateField ) {
						return;
					}

					stateField.value = state.isValid ? JSON.stringify( { ...state.data, browserInfo: getBrowserInfo() } ) : '';
				},
			} );

			if ( token !== initializationToken || ! container.isConnected ) {
				component.remove();
				return;
			}

			adyenCardComponent = component.mount( container );
		} catch {
			if ( token === initializationToken ) {
				showError( window.digitalAppsPaymentsForAdyenConfig?.messages?.loadFailed || 'The card payment form could not be loaded.' );
			}
		}
	}

	function isAdyenSelected() {
		return $( 'input[name="payment_method"]:checked' ).val() === 'digitalapps_payments_for_adyen_card';
	}

	$( function () {
		if ( window.digitalAppsPaymentsForAdyenConfig?.actionMode ) {
			return;
		}
		if ( document.getElementById( 'digitalapps-payments-for-adyen-card-component' ) ) {
			initializeAdyen();
		}

		$( document.body ).on( 'updated_checkout', function () {
			cleanupAdyenComponent();
			if ( isAdyenSelected() ) {
				initializeAdyen();
			}
		} );

		$( document.body ).on( 'change', 'input[name="payment_method"]', function () {
			cleanupAdyenComponent();
			if ( $( this ).val() === 'digitalapps_payments_for_adyen_card' ) {
				initializeAdyen();
			}
		} );

		$( window ).on( 'beforeunload', cleanupAdyenComponent );
	} );
} )( window.jQuery );
