import * as React from 'react'
import {__, _x} from '@wordpress/i18n'

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

import {
	InspectorControls,
	// @ts-expect-error
} from '@wordpress/block-editor'

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

import {
	createHigherOrderComponent,
} from '@wordpress/compose'

import {
	ButtonGroup,
} from '@ska/components'

import {
	SkaPanelBody,
} from '@ska/plugin'

import {
	queryFilters,
} from '../data'

import type {
	tBlockEditProps,
	tBlockNameOrType,
	tBlockType,
} from '@ska/shared'

export interface QueryValue {
	slug?: string
	/** Limit result count in the editor. Sent via REST as `skaBlocksQueryLimit` and that value modifies posts per page server-side. */
	editorLimit?: number
}

export interface QueryAttributes {
	skaBlocksQuery?: QueryValue
}

const hasQueryFiltersSupport = (block: tBlockNameOrType) => {
	return typeof block === 'string' ? block === 'core/query' : block.name === 'core/query'
}

const withCustomAttributes = (settings: tBlockType) => {

	if(!hasQueryFiltersSupport(settings)) {
		return settings
	}

	if(!settings.attributes.skaBlocksQuery) {
		Object.assign(settings.attributes, {
			skaBlocksQuery: {
				type: 'object',
			},
		})
	}

	return settings
}

const MIN_EDITOR_LIMIT = 0
const MAX_EDITOR_LIMIT = 32

const QueryControls: React.FC<tBlockEditProps<QueryAttributes>> = (props) => {

	const {
		attributes,
		setAttributes,
	} = props

	const {
		query = {},
		skaBlocksQuery = {},
	} = attributes

	const {
		skaBlocksQueryFilter,
		skaBlocksQueryLimit,
		...restQuery
	} = query

	const {
		slug = '',
		editorLimit = 0,
	} = skaBlocksQuery

	return <>
		<InspectorControls>
			<SkaPanelBody
				title={__('Query filters', 'ska-blocks')}
				initialOpen={!!slug || !!editorLimit}
				skaIcon
			>
				<ButtonGroup.Radio
					pills
					isSmall
					label={__('Query filter', 'ska-blocks')}
					options={queryFilters}
					value={slug}
					onChange={nextValue => {
						setAttributes({
							skaBlocksQuery: {
								...skaBlocksQuery,
								slug: nextValue,
							},
							query: {
								...restQuery,
								...(nextValue && {
									skaBlocksQueryFilter: nextValue,
								}),
								...(skaBlocksQueryLimit && {
									skaBlocksQueryLimit,
								}),
							},
						})
					}}
				/>
				<RangeControl
					label={__('Editor results limit', 'ska-blocks')}
					help={__('Limit the amount of results shown in the editor.', 'ska-blocks')}
					min={MIN_EDITOR_LIMIT}
					max={MAX_EDITOR_LIMIT}
					onChange={(nextLimit = 0) => {
						if(
							isNaN(nextLimit)
							|| nextLimit < MIN_EDITOR_LIMIT
							|| nextLimit > MAX_EDITOR_LIMIT
						) {
							return
						}
						setAttributes({
							skaBlocksQuery: {
								...skaBlocksQuery,
								editorLimit: nextLimit,
							},
							query: {
								...restQuery,
								...(skaBlocksQueryFilter && {
									skaBlocksQueryFilter,
								}),
								...(nextLimit > 0 && {
									skaBlocksQueryLimit: nextLimit,
								}),
							},
						})
					}}
					value={parseInt(editorLimit.toString(), 10)}
					__nextHasNoMarginBottom
					__next40pxDefaultSize
				/>
			</SkaPanelBody>
		</InspectorControls>
	</>
}

const withQueryFiltersControls = createHigherOrderComponent(
	(BlockEdit: any) => (props: tBlockEditProps) => {
		if(hasQueryFiltersSupport(props.name)) {
			return <>
				<QueryControls {...props as any as tBlockEditProps<QueryAttributes>} />
				<BlockEdit {...props} />
			</>
		}
		return <BlockEdit {...props} />
	},
	'withSkaBlocksQueryFiltersControls'
)

export default () => {
	addFilter('blocks.registerBlockType', 'ska-blocks/with-query-attributes', withCustomAttributes)
	addFilter('editor.BlockEdit', 'ska-blocks/with-query-controls', withQueryFiltersControls, 5)
}
