// External dependencies.
import React, { ReactElement } from 'react';

// Divi dependencies.
import {
	StyleContainer,
	StylesProps,
} from '@divi/module';

// Local dependencies.
import { ApplyButtonAttrs } from './types';
import {
	createBorderStyles,
	createSpacingStyles,
	createTypographyStyles,
	extractBorderAttrs,
	extractSpasingAttrs,
	extractTypographyAttrs,
} from '../../utils';

/**
 * Dynamic Module's style components.
 *
 * @since ??
 */
const ModuleStyles = ({
	settings,
	mode,
	state,
	noStyleTag,
	elements,
	attrs,
	orderClass,
}: StylesProps<ApplyButtonAttrs>): ReactElement => {
	const selectors = {
		button: `${orderClass} .apply-filters__button`,
		buttonHover: `${orderClass} .apply-filters__button:hover`,
		buttonDisabled: `${orderClass} .apply-filters__button:disabled`,
	};

	const typography = extractTypographyAttrs(attrs?.module?.decoration?.applyTypography);
	const typographyStyles = createTypographyStyles(
		selectors.button,
		typography
	);

	const spacing = extractSpasingAttrs(attrs?.module?.decoration?.applySpacing);
	const spacingStyles = createSpacingStyles(
		selectors.button,
		spacing
	);

	const border = extractBorderAttrs(attrs?.module?.decoration?.applyBorder);
	const borderStyles = createBorderStyles(
		selectors.button,
		border
	);

	const opacityValue = (attrValue?: string) => {
		if (!attrValue) {
			return '';
		}

		const raw = String(attrValue).trim();
		const num = parseFloat(raw);
		if (Number.isNaN(num)) {
			return '';
		}

		if (raw.endsWith('%') || num > 1) {
			return String(num / 100);
		}

		return String(num);
	};

	return (
		<StyleContainer mode={mode} state={state} noStyleTag={noStyleTag}>
			{elements.style({
				attrName: 'module',
				styleProps: {
					disabledOn: {
						disabledModuleVisibility: settings?.disabledModuleVisibility,
					},
					advancedStyles: [
						...typographyStyles,
						...spacingStyles,
						...borderStyles,
						{
							componentName: 'divi/common',
							props: {
								property: 'color',
								selector: selectors.button,
								attr: attrs?.module?.decoration?.applyNormalColor,
							},
						},
						{
							componentName: 'divi/common',
							props: {
								property: 'background-color',
								selector: selectors.button,
								attr: attrs?.module?.decoration?.applyNormalBgColor,
							},
						},
						{
							componentName: 'divi/common',
							props: {
								property: 'color',
								selector: selectors.buttonHover,
								attr: attrs?.module?.decoration?.applyHoverColor,
							},
						},
						{
							componentName: 'divi/common',
							props: {
								property: 'background-color',
								selector: selectors.buttonHover,
								attr: attrs?.module?.decoration?.applyHoverBgColor,
							},
						},
						{
							componentName: 'divi/common',
							props: {
								property: 'border-color',
								selector: selectors.buttonHover,
								attr: attrs?.module?.decoration?.applyHoverBorderColor,
							},
						},
						{
							componentName: 'divi/common',
							props: {
								property: 'opacity',
								selector: selectors.buttonDisabled,
								attr: attrs?.module?.decoration?.applyDisabledOpacity,
								declarationFunction: ({ attrValue }) => opacityValue(attrValue as string),
							},
						},
						{
							componentName: 'divi/common',
							props: {
								property: 'color',
								selector: selectors.buttonDisabled,
								attr: attrs?.module?.decoration?.applyDisabledColor,
							},
						},
						{
							componentName: 'divi/common',
							props: {
								property: 'background-color',
								selector: selectors.buttonDisabled,
								attr: attrs?.module?.decoration?.applyDisabledBgColor,
							},
						},
						{
							componentName: 'divi/common',
							props: {
								property: 'border-color',
								selector: selectors.buttonDisabled,
								attr: attrs?.module?.decoration?.applyDisabledBorderColor,
							},
						},
						{
							componentName: 'divi/common',
							props: {
								property: 'align-self',
								selector: selectors.button,
								attr: attrs?.module?.decoration?.applyAlignment,
							},
						},
					],
				},
			})}
		</StyleContainer>
	);
}

export {
	ModuleStyles,
};
