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

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

import {
	useBlockProps,
	RichText,
	InspectorAdvancedControls,
	// @ts-expect-error
} from '@wordpress/block-editor'

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

// @ts-ignore
import metadata from './block.json'

import {
	useAs,
	useAttributes,
	type AsAttributes,
	type AttributesAttributes,
} from '../../supports'

import type {
	SkaBlocks,
} from '../../types'

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

export interface TextBlockAttributes extends AsAttributes, AttributesAttributes {
	content: string
	placeholder?: string
}

const Edit: React.FC<tBlockEditProps<TextBlockAttributes>> = props => {

	const {
		attributes,
		setAttributes,
	} = props

	const {
		content,
		placeholder = '',
	} = attributes

	const [Element, asProps, {isVoidElement}] = useAs(props)
	const attributesProps = useAttributes(props)
	const blockProps = useBlockProps({
		className: 'ska-text',
		...(attributesProps.style && {
			style: attributesProps.style,
		}),
	})

	const controls = isVoidElement ? null : (
		<InspectorAdvancedControls>
			<TextControl
				label={__('Placeholder', 'ska-blocks')}
				help={__(`Text displayed in the editor when the block doesn't have any content.`, 'ska-blocks')}
				value={placeholder}
				onChange={nextValue => setAttributes({placeholder: nextValue})}
				__nextHasNoMarginBottom
				__next40pxDefaultSize
			/>
		</InspectorAdvancedControls>
	)

	if(isVoidElement) {
		return <>
			{controls}
			<Element
				{...asProps}
				{...attributesProps}
				{...blockProps}
				children={undefined}
			/>
		</>
	}

	return <>
		{controls}
		<RichText
			tagName={Element}
			value={content}
			onChange={(content: string) => setAttributes({content})}
			placeholder={placeholder || __('Text…', 'ska-blocks')}
			{...asProps}
			{...attributesProps}
			{...blockProps}
		/>
	</>
}

const Save: React.FC<tBlockSaveProps<TextBlockAttributes>> = props => {

	const {
		attributes,
	} = props

	const {
		content,
	} = attributes

	const [Element, asProps, {isVoidElement}] = useAs.save(props)
	const attributesProps = useAttributes.save(props)
	const blockProps = useBlockProps.save({
		className: 'ska-text',
	})

	if(isVoidElement) {
		return (
			<Element
				{...asProps}
				{...attributesProps}
				{...blockProps}
				children={undefined}
			/>
		)
	}

	return (
		<RichText.Content
			tagName={Element}
			value={content}
			{...asProps}
			{...attributesProps}
			{...blockProps}
		/>
	)
}

export default (skaBlocks: SkaBlocks): BlockModule => ({
	metadata,
	settings: {
		edit: Edit,
		save: Save,
		transforms: {
			from: [
				{
					type: 'block',
					blocks: ['core/heading'],
					transform: ({content, level}) => {
						return createBlock('ska/text', {
							content,
							skaBlocksAs: {
								element: 'custom',
								customElement: `h${level}`,
							},
						})
					},
				},
				{
					type: 'block',
					blocks: ['core/paragraph'],
					transform: ({content}) => {
						return createBlock('ska/text', {
							content,
							skaBlocksAs: {
								element: 'custom',
								customElement: 'p',
							},
						})
					},
				},
			],
			to: [
				{
					type: 'block',
					blocks: ['core/paragraph'],
					transform: ({content}) => createBlock('core/paragraph', {content}),
				},
			],
		},
		__experimentalLabel: (attributes, {context}) => {

			const customName = attributes?.metadata?.name
			if(context === 'list-view' && customName) {
				return customName
			}

			const {
				skaBlocksVariation,
				skaBlocksAs = {},
				className,
			} = attributes

			if(skaBlocksVariation) {
				return
			}

			if(context === 'list-view') {

				const {
					element = 'span',
					customElement = 'span',
					isVoid,
				} = skaBlocksAs

				const renderClassName = className ? `.${className.split(' ').join('.')}` : ''
				const tagName = `${element === 'custom' ? customElement : element}${renderClassName}`

				if(isVoid) {
					return sprintf(_x(`Void: &lt;%s&gt;`, 'Block name in list view - void element', 'ska-blocks'), tagName)
				}

				return sprintf(_x(`Text: &lt;%s&gt;`, 'Block name in list view - text element', 'ska-blocks'), tagName)
			}
		},
	},
})
