import * as React from 'react'
import {__} from '@wordpress/i18n'
import cx from 'classnames'

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

import {
	htmlAttributeToReactAttribute,
	styleToReactObject,
} from '@ska/utils'

export interface SVGStringRendererProps {
	svg: string
}

/** SVG attributes to not pass. */
const SKIP_ATTRIBUTES = [
	'data-svg-width',
	'data-svg-height',
]

const SVGStringRenderer: React.FC<SVGStringRendererProps> = forwardRef(
	(props, ref) => {

		const {
			svg,
			children,
			...svgProps
		} = props as any

		const [rootAttributes, childrenString] = useMemo(() => {

			const parser = new DOMParser()
			const doc = parser.parseFromString(svg, 'text/html')
			const svgEl = doc.querySelector<SVGElement>('body > svg')
			if(!svgEl) {
				return [{}, '']
			}

			const attributes = svgEl
				.getAttributeNames()
				.filter(v => !SKIP_ATTRIBUTES.includes(v))
				.reduce((acc, cur) => {
					switch(cur) {
						case '': break
						case 'style':
							acc[cur] = styleToReactObject(svgEl.getAttribute(cur) || '')
						break
						default:
							acc[htmlAttributeToReactAttribute(cur)] = svgEl.getAttribute(cur) || ''
					}
					return acc
				}, {} as Record<string, string | object>)

			return [attributes, svgEl.innerHTML.toString()]
		}, [svg])

		return (
			<svg
				ref={ref}
				{...svgProps}
				{...rootAttributes}
				className={cx(svgProps.className, rootAttributes.className)}
				dangerouslySetInnerHTML={{__html: childrenString}}
			/>
		)
	}
)

export const SVGStringRendererNoRef: React.FC<SVGStringRendererProps> = (props) => {

	const {
		svg,
		children,
		...svgProps
	} = props as any

	const getSvg = (): [Record<string, string | object>, string] => {

		const parser = new DOMParser()
		const doc = parser.parseFromString(svg, 'text/html')
		const svgEl = doc.querySelector<SVGElement>('body > svg')
		if(!svgEl) {
			return [{}, '']
		}

		const attributes = svgEl
			.getAttributeNames()
			.filter(v => !SKIP_ATTRIBUTES.includes(v))
			.reduce((acc, cur) => {
				switch(cur) {
					case '': break
					case 'style':
						acc[cur] = styleToReactObject(svgEl.getAttribute(cur) || '')
					break
					default:
						acc[htmlAttributeToReactAttribute(cur)] = svgEl.getAttribute(cur) || ''
				}
				return acc
			}, {} as Record<string, string | object>)

		return [attributes, svgEl.innerHTML.toString()]
	}

	const [rootAttributes, childrenString] = getSvg()

	return (
		<svg
			{...svgProps}
			{...rootAttributes}
			className={cx(svgProps.className, rootAttributes.className)}
			dangerouslySetInnerHTML={{__html: childrenString}}
		/>
	)
}


export default SVGStringRenderer
