import { createReduxStore, dispatch, register } from '@wordpress/data'
import { MOUNT, SETTINGS_KEY } from '../data/constants'
import { SettingsActions, SettingsState } from '../data/redux/settings.redux'

const DEFAULT_STATE: SettingsState = { settings: null }

const CHECKOUT_BLOCK_SELECTORS = '.wp-block-woocommerce-checkout, .wc-block-checkout'

const isBlockCheckoutContext = (): boolean =>
	!document.getElementById(MOUNT) && document.querySelector(CHECKOUT_BLOCK_SELECTORS) !== null

const tryGetBlocksSettings = async (): Promise<SettingsState['settings']> => {
	try {
		const { getSetting } = await import('@woocommerce/settings')
		return getSetting(SETTINGS_KEY) ?? null
	} catch {
		return null
	}
}

const settingsStore = createReduxStore<SettingsState, SettingsActions, any>('green-pay/settings', {
	reducer(state = DEFAULT_STATE, action): SettingsState {
		switch (action.type) {
			case 'SET_SETTINGS':
				return { ...state, settings: action.payload }
			default:
				return state
		}
	},
	actions: {
		setSettings(payload) {
			return { type: 'SET_SETTINGS', payload }
		},
		loadSettings: async (): Promise<void> => {
			const storeDispatch = dispatch('green-pay/settings') as SettingsActions
			const isClassicCheckout = document.getElementById(MOUNT) !== null

			if (isClassicCheckout) {
				if (window.greenmoney_wpApiSettings) {
					storeDispatch.setSettings(window.greenmoney_wpApiSettings)
					return
				}

				// Localized settings print in the footer — poll briefly before falling back.
				for (let attempt = 0; attempt < 20; attempt++) {
					await new Promise((res) => setTimeout(res, 50))
					if (window.greenmoney_wpApiSettings) {
						storeDispatch.setSettings(window.greenmoney_wpApiSettings)
						return
					}
				}

				const blocksSettings = await tryGetBlocksSettings()
				if (blocksSettings) {
					storeDispatch.setSettings({ ...blocksSettings, context: 'classic' })
				}
				return
			}

			const blocksSettings = await tryGetBlocksSettings()
			if (blocksSettings) {
				storeDispatch.setSettings(blocksSettings)
				return
			}

			if (window.greenmoney_wpApiSettings) {
				storeDispatch.setSettings(window.greenmoney_wpApiSettings)
				return
			}

			if (isBlockCheckoutContext()) {
				// Block checkout: settings come from wcSettings — poll briefly, no fixed delay.
				for (let attempt = 0; attempt < 20; attempt++) {
					await new Promise((res) => setTimeout(res, 50))
					const settings = await tryGetBlocksSettings()
					if (settings) {
						storeDispatch.setSettings(settings)
						return
					}
					if (window.greenmoney_wpApiSettings) {
						storeDispatch.setSettings(window.greenmoney_wpApiSettings)
						return
					}
				}
			}
		},
	},
	selectors: {
		getSettings(state: SettingsState) {
			return state.settings
		},
	},
})

register(settingsStore)
