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

import {
	hasBlockSupport,
	// @ts-expect-error
} from '@wordpress/blocks'

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

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

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

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

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

import {
	URLPicker,
} from '../components'

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

import {
	usePluginOptions,
} from '../plugins/options'

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

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

export interface DynamicLinkOption {
	label: string
	value: string
}

export interface LinkValue {
	href?: string
	opensInNewTab?: boolean
	id?: number
	kind?: string
	type?: string
}

export interface LinkAttributes {
	skaBlocksLink?: LinkValue
}

export const LINK_SUPPORT_KEY = 'skaBlocksLink'
export const LINK_SUPPORT_DEFAULT_ENABLED = false
export const hasLinkSupport = (block: tBlockNameOrType) => hasBlockSupport(block, LINK_SUPPORT_KEY, LINK_SUPPORT_DEFAULT_ENABLED)

const withCustomAttributes = (settings: tBlockType) => {

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

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

	return settings
}

export const useUserDynamicLinks = () => {

	const {
		userDynamicLinks = {},
	} = usePluginOptions()

	return useMemo(() => {
		return Object.keys(userDynamicLinks).map(key => {
			return {
				label: key,
				value: `#ska-link--${kebabCase(key)}`,
				tooltip: userDynamicLinks[key],
			}
		})
	}, [userDynamicLinks])
}

const DEFAULT_ADDITIONAL_DYNAMIC_LINKS = [] as DynamicLinkOption[]
export const useDynamicLinks = (additionalDynamicLinks = DEFAULT_ADDITIONAL_DYNAMIC_LINKS) => {

	const userDynamicLinks = useUserDynamicLinks()

	return useMemo(() => [
		...dynamicLinks,
		...additionalDynamicLinks,
		...userDynamicLinks,
	], [additionalDynamicLinks, userDynamicLinks])
}

export const LinkControls: React.FC<tBlockEditProps<LinkAttributes> & {additionalDynamicLinks?: DynamicLinkOption[]}> = (props) => {

	const {
		attributes,
		setAttributes,
		additionalDynamicLinks = [],
	} = props

	const {
		skaBlocksLink = {},
	} = attributes

	const {
		href = '',
		opensInNewTab = false,
	} = skaBlocksLink

	const dynamicLinks = useDynamicLinks(additionalDynamicLinks)

	return <>
		<BlockControls>
			<ToolbarGroup>
				<URLPicker
					value={href}
					onChange={(nextValue, {id, kind, type}) => {
						setAttributes({skaBlocksLink: {...skaBlocksLink, href: nextValue, id, kind, type}})
					}}
					opensInNewTab={opensInNewTab}
					onToggleOpensInNewTab={() => setAttributes({skaBlocksLink: {...skaBlocksLink, opensInNewTab: !opensInNewTab}})}
					renderControlBottom={dynamicLinks.length > 0 ? (
						<ButtonGroup.Radio
							label={__('Dynamic link', 'ska-blocks')}
							isSmall
							pills
							options={dynamicLinks}
							value={href}
							onChange={nextValue => {
								setAttributes({
									skaBlocksLink: {
										...skaBlocksLink,
										href: nextValue,
										opensInNewTab,
										id: undefined,
										kind: undefined,
										type: undefined,
									},
								})
							}}
						/>
					) : null}
				/>
			</ToolbarGroup>
		</BlockControls>
	</>
}

export interface LinkProps {
	href?: string
	'data-ska-href'?: string
	target?: string
	rel?: string
}

const getLink = (attributes: LinkAttributes, save = false): LinkProps => {

	const {
		skaBlocksLink = {},
	} = attributes

	const {
		href = '',
		opensInNewTab = false,
	} = skaBlocksLink

	return {
		...(href && {
			[save ? 'href' : 'data-ska-href']: href,
			...(opensInNewTab && {
				target: '_blank',
				rel: 'noopener noreferrer',
			}),
		}),
	}
}

export const useLink = (props: tBlockEditProps<LinkAttributes>): Omit<LinkProps, 'href'> => {
	return getLink(props.attributes, false)
}

useLink.save = (props: tBlockSaveProps<LinkAttributes>): Omit<LinkProps, 'data-ska-href'> => {
	return getLink(props.attributes, true)
}

export const useLinkWrapper = (Element: string, props: tBlockEditProps<LinkAttributes>): [string, Omit<LinkProps, 'href'>] => {
	const linkProps = getLink(props.attributes, false)
	const As = Object.keys(linkProps).length > 0 ? 'a' : Element
	return [As, linkProps]
}

useLinkWrapper.save = (Element: string, props: tBlockSaveProps<LinkAttributes>): [string, Omit<LinkProps, 'data-ska-href'>] => {
	const linkProps = getLink(props.attributes, true)
	const As = Object.keys(linkProps).length > 0 ? 'a' : Element
	return [As, linkProps]
}

export default () => {
	addFilter('blocks.registerBlockType', 'ska-blocks/with-link-attributes', withCustomAttributes)
}
