import * as React from 'react'

import {
	useMemo,
} from '@wordpress/element'

import {
	withFilters,
} from '@wordpress/components'

import {
	applyFilters,
} from '@wordpress/hooks'

import {
	useStyleOverride,
} from '@ska/utils'

import {
	usePluginOptionsEdit,
} from '../options'

import {
	useTailwind4Options,
} from '../tailwind4'

import {
	PresetsStylesLoader,
	usePresets,
	useRecompilePresets,
} from '../../supports/presets'

const useFontStyles = () => {

	const {
		fontFamily,
	} = useTailwind4Options()

	return useMemo(() => {
		return Object.keys(fontFamily)
			.map(id => {
				const value = fontFamily[id]
				const [externalFontJson] = (value.indexOf('[&]') === -1 ? `{}[&]${value}` : value).split('[&]')
				const conf = JSON.parse(externalFontJson)
				const {source} = conf
				if(!source) {
					return ''
				}
				return applyFilters('ska.blocks.getFontUrl', '', id, conf) as string
			})
			.filter(v => v)
			.map(url => `@import url('${url}');`)
			.join('\n')
	}, [fontFamily])
}

export const useTailwindStyles = () => {

	const [select] = usePluginOptionsEdit()
	const components = (select.getOption('tailwindGlobalStyles') || []) as any as string[]

	const {
		compiledTheme,
		compiledPreflight,
		compiledProperties,
		compiledCompat,
	} = useTailwind4Options()

	return useMemo(
		() => {
			return `
				@layer ska-properties, ska-reset, ska-base;
				${components.includes('theme') ? compiledTheme : ''}
				@layer ska-reset {
					${components.includes('preflight') ? compiledPreflight : ''}
					${components.includes('properties') ? compiledProperties : ''}
					${components.includes('compat') ? compiledCompat : ''}
				}
				${components.includes('properties') ? compiledProperties : ''}
			`.replaceAll('\n', '').replaceAll('\t', '').trim()
		},
		// eslint-disable-next-line react-compiler/react-compiler
		// eslint-disable-next-line react-hooks/exhaustive-deps
		[JSON.stringify(components), compiledTheme, compiledPreflight, compiledProperties, compiledCompat]
	)
}

/** Allows using Tailwind theme variables in the block editor context. */
const BlockEditorTailwindThemeLoader: React.FC<{theme: string}> = ({theme}) => {

	const css = useMemo(() => {
		return theme
			.replace(':root,:host', '.ska-blocks--use-global-theme') // New selector
			.replace(':root', '.ska-blocks--use-global-theme') // Old selector
	}, [theme])

	return <style id='ska-blocks--block-editor--tailwind-theme'>{css}</style>
}

/** Always rendered, does global things. */
const GlobalPlugin: React.FC = () => {

	const options = useTailwind4Options()
	const presets = usePresets()

	useRecompilePresets(presets)

	useStyleOverride('ska-blocks-fonts', useFontStyles())
	useStyleOverride('ska-blocks-tailwind4', useTailwindStyles())

	return <>
		<PresetsStylesLoader presets={presets} />
		<BlockEditorTailwindThemeLoader theme={options.compiledTheme} />
	</>
}

export default {
	name: 'ska-blocks-global',
	render: withFilters('ska.blocks.globalPlugin')(GlobalPlugin),
}
