import * as React from 'react'

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

import {
	__experimentalHStack as HStack,
	__experimentalVStack as VStack,
	__experimentalView as View,
	Modal,
	Placeholder,
	Spinner,
} from '@wordpress/components'

import {
	download,
} from '@wordpress/icons'

import {
	Button,
	JsonView,
	ImportExportStringsContext,
} from '@ska/components'

import {
	debugLog,
	IS_WOOCOMMERCE,
} from '@ska/utils'

import PostTypeLabel from './PostTypeLabel'

import {
	useExportSelect,
	useSiteExportValues,
	useOnExport,
	type SiteExportValuesOptions,
} from './hooks'

import {
	SLUG,
} from './util'

/** Options to not include in demo exports. */
const OPTION_FILTERS: SiteExportValuesOptions['filters'] = {

	ska_blocks: key => ![
		'dynamicShortcodes',
		'userDynamicLinks',
		'dynamicShortcodeOptions',
		'dynamicLinkOptions',
		'openRouterModel',
		'openRouterFallbackModel', // Deprecated
		'inspectorControlsGroup',
		'styleCacheMode',
		'inlineGlobalStyles',
		'inlineTailwindGlobalStyles',
		'allowJsonUploads',
		'deferFonts',
		'useBunnyFonts',
		'minify',
		'buttonToLink',
		'headingMarginReset',
		'htmlToBlocksRemove',
		'stripDark',
		'unfilteredHTMLWarn',
	].includes(key),

	ska_theme: key => ![
		'adminCSS',
		'customCSS', // TODO: Should allow, but not when it's just `body {\n\t@apply m-0;\n}` - wouldn't want to overwrite actual custom CSS.
		'underConstruction',
		'cookieNoticeEnabled',
		'allowedConditions',
		'enableInstantPage',
		'betterEditSite',
		'toolbar',
		'devicePreview',
		'groupWithElement',
		'disableComments',
		'disableDuotone',
		'disableEmoji',
		'disableJQueryMigrate',
		'disableWCBlocks',
		'disableWCPatterns',
		'restUsersRequireLogin',
		'templateSelect',
		'viewTransitionEnabled',
		'disableLayoutStyles',
		'disableCoreBlockPatterns',
		'wcAdditionalTabs',
		'wcInitialOpenTab',
		'wcProductsPerPageOptions',
	].includes(key) && (
		IS_WOOCOMMERCE || !key.startsWith('wc')
	),

	ska_blocks_tailwind4: key => ![
		'preflight',
		'theme',
		'themeTheme',
		'tailwindColors',
		'plugins',
		'themePlugins',
		'editorPlugins',
		'properties',
		'compat',
	].includes(key),
}

const filterValue = (value: any, slug: string) => {

	if(slug === 'ska_blocks_presets') {

		const {
			presets = {},
		} = value

		return {
			...value,
			presets: Object.keys(presets).reduce((acc, cur) => {
				const {isDefault = false} = presets[cur]
				if(isDefault) {
					return acc // Don't include presets whose value is default
				}
				acc[cur] = presets[cur]
				return acc
			}, {} as any),
		}
	}

	return value
}

export interface DemoExportModalProps {
	onRequestClose: () => void
}

const DemoExportModal: React.FC<DemoExportModalProps> = ({
	onRequestClose,
}) => {

	const {
		exportLabel,
		importExportLoadingLabel,
		downloadLabel,
	} = useContext(ImportExportStringsContext)

	const {
		site,
		stylesheet,
		postTypes,
		loading,
	} = useExportSelect()

	/** Site options to include. */
	const include = [
		'ska_theme',
		'ska_blocks',
		'ska_blocks_presets',
		'ska_blocks_tailwind4',
	]

	/** Site data for exporting. */
	const exportables = useSiteExportValues(site, include, {
		enabled: !loading,
		filters: OPTION_FILTERS,
	})

	const contentToExport = postTypes.reduce((acc, cur) => {

		const {
			postType,
			records = [],
		} = cur

		/** Demos only include these post types. */
		if(!['wp_template', 'wp_template_part', 'page'].includes(postType)) {
			return acc
		}

		acc[postType] = records
			.filter(entity => {
				switch(postType) {

					/** Export only modified templates. */
					case 'wp_template':
					case 'wp_template_part':
						return entity.source === 'custom'

					/** Export only specific pages. */
					case 'page':
						return [
							'front-page',
							'home',
							'blog',
							'about',
							'services',
							'contact',
						].includes(entity.slug)

					default:
						return false
				}
			})
			.map(entity => {

				const meta = entity?.meta || {}
				const onlyHasFootnotesMeta = Object.keys(meta).length === 1 && Object(meta).hasOwnProperty('footnotes') && meta.footnotes === ''
				const hasMeta = Object.keys(meta).length > 0 && !onlyHasFootnotesMeta

				return {
					id: entity.id,
					title: entity?.title?.raw || '',
					...(entity?.excerpt?.raw && {
						excerpt: entity.excerpt.raw || '',
					}),
					content: entity?.content?.raw || '',
					...(hasMeta && {
						meta,
					}),
					...(['post', 'page'].includes(postType) && {
						template: entity?.template || '',
					}),
				}
			})

		return acc
	}, {} as Record<string, any[]>)

	const valueToExport = {
		__file: SLUG,
		site: {
			title: site?.title || '',
			show_on_front: site?.show_on_front || '',
			page_for_posts: site?.page_for_posts || 0,
			page_on_front: site?.page_on_front || 0,
			posts_per_page: site?.posts_per_page || 7,
		},
		stylesheet,
		...(include.reduce((acc, slug) => {
			if(slug in exportables) {
				acc[slug] = filterValue(exportables[slug], slug)
			}
			return acc
		}, {} as any)),
		content: contentToExport,
	}

	if(!loading) {
		debugLog({valueToExport})
	}

	const onExport = useOnExport(valueToExport, 'ska-demo')

	return (
		<Modal
			className='ska__import-export__export-modal ska__import-export__export-modal--demo'
			title={exportLabel}
			onRequestClose={onRequestClose}
		>
			{loading && (
				<Placeholder
					label={importExportLoadingLabel}
					className='ska__import-export__export-modal__loader'
				>
					<Spinner />
				</Placeholder>
			)}
			{!loading && (
				<View>
					<VStack spacing={4}>
						<VStack spacing={4} justify='start' alignment='start' className='exports-list'>
							{Object.keys(valueToExport.content).map(postType => {
								return (
									<View key={postType}>
										<h2><PostTypeLabel postType={postType} /></h2>
										<ul>
											{valueToExport.content[postType].map((entity: any) => {
												return (
													<li key={entity.id}>
														<code>{entity.id}</code>
														<span>{entity.title}</span>
													</li>
												)
											})}
										</ul>
									</View>
								)
							})}
							<View>
								<h2>Presets</h2>
								<ul>
									{Object.entries(valueToExport.ska_blocks_presets.presets).map(([slug, preset]: any) => {
										return (
											<li key={slug}>
												<code>{slug}</code>
												<span>{preset.title}</span>
											</li>
										)
									})}
								</ul>
							</View>
							<View>
								<h2>ska-blocks options</h2>
								<ul>{Object.keys(valueToExport.ska_blocks).map((option: any) => <li key={option}><code>{option}</code></li>)}</ul>
							</View>
							<View>
								<h2>Tailwind options</h2>
								<ul>{Object.keys(valueToExport.ska_blocks_tailwind4).map((option: any) => <li key={option}><code>{option}</code></li>)}</ul>
							</View>
							<View>
								<h2>ska-theme options</h2>
								<ul>{Object.keys(valueToExport.ska_theme).map((option: any) => <li key={option}><code>{option}</code></li>)}</ul>
							</View>
						</VStack>
						<HStack>
							<Button
								variant='primary'
								icon={download}
								children={downloadLabel}
								onClick={() => {
									onExport()
									onRequestClose()
								}}
							/>
							<JsonView value={valueToExport} />
						</HStack>
					</VStack>
				</View>
			)}
		</Modal>
	)
}

export default DemoExportModal
