/**
 * Button block type
 *
 */
import { ReactComponent as Icon } from './icon.svg';
import { title, iconName, url, iconUser } from '@vkblocks/utils/example-data';
import edit from './edit';
import metadata from './block.json';
import save from './save';
import { deprecated } from './deprecated/save/';
import deprecatedHooks from './deprecated/hooks';
import transforms from './transforms';
import { addFilter } from '@wordpress/hooks';
import { createHigherOrderComponent } from '@wordpress/compose';
import { isHexColor } from '@vkblocks/utils/is-hex-color';

const { name } = metadata;

export { metadata, name };

export const settings = {
	icon: <Icon />,
	example: {
		attributes: {
			content: iconName,
			subCaption: title,
			buttonUrl: url,
			buttonTarget: false,
			buttonSize: 'md',
			buttonType: '0',
			buttonEffect: '',
			buttonColor: 'primary',
			buttonTextColorCustom: 'undefined',
			buttonColorCustom: 'undefined',
			buttonAlign: 'left',
			buttonWidthMobile: 0,
			buttonWidthTablet: 0,
			outerGap: null,
			buttonWidth: 0,
			fontAwesomeIconBefore: iconUser,
			fontAwesomeIconAfter: iconUser,
			iconSizeBefore: null,
			iconSizeAfter: null,
		},
	},
	edit,
	save,
	deprecated,
	transforms,
};

/**
 * ホバー色のCSS値を取得する
 * @param {string} value - 色の値（HEX、rgba、またはパレットスラッグ）
 * @return {string|null} CSS で使用できる色の値、または null
 */
const getHoverColorCssValue = (value) => {
	if (value === undefined || value === '' || value === null) {
		return null;
	}
	// HEX カラーの場合
	if (isHexColor(value)) {
		return value;
	}
	// rgba / rgb / hsla / hsl カラーの場合（厳格にバリデーション）
	const cssFuncColorPattern = /^(rgba?|hsla?)\(\s*[\d.%\s,/]+\s*\)$/;
	if (cssFuncColorPattern.test(value)) {
		return value;
	}
	// パレットのスラッグの場合 → CSS カスタムプロパティで参照
	return `var(--wp--preset--color--${value})`;
};

const generateInlineCss = (attributes) => {
	const {
		buttonTextColorCustom,
		buttonColorCustom,
		buttonHoverBgColorCustom,
		buttonHoverTextColorCustom,
		buttonType,
		blockId,
	} = attributes;
	let inlineCss = '';

	// カスタムカラーの場合
	if (buttonColorCustom !== undefined && isHexColor(buttonColorCustom)) {
		// 塗り
		if (buttonType === '0' || buttonType === null) {
			inlineCss += `.vk_button-${blockId} .has-background {
				background-color: ${buttonColorCustom};
				border: 1px solid ${buttonColorCustom};
			}`;
		}
		// アウトライン
		if (buttonType === '1') {
			inlineCss += `.vk_button-${blockId} .has-text-color.is-style-outline {
				background-color: transparent;
				border: 1px solid ${buttonColorCustom};
				color: ${buttonColorCustom};
			}
			.vk_button-${blockId} .has-text-color.is-style-outline:hover {
				background-color: ${buttonColorCustom};
				border: 1px solid ${buttonColorCustom};
				color: #fff;
			}`;
		}
		// テキストのみ
		if (buttonType === '2') {
			inlineCss = `.vk_button-${blockId} .has-text-color.vk_button_link-type-text {
				color: ${buttonColorCustom};
			}`;
		}
	}

	// 文字色がカスタムカラーの場合
	if (
		buttonTextColorCustom !== undefined &&
		isHexColor(buttonTextColorCustom)
	) {
		if (buttonType === '0' || buttonType === null) {
			inlineCss += ` .vk_button-${blockId} .has-text-color {
				color: ${buttonTextColorCustom};
			}`;
		}
	}

	// ホバー時の背景色が設定されている場合
	// WP コアが .has-*-background-color に !important を付与するため
	// !important で上書きする必要がある
	// filter: none でテーマの brightness/saturate フィルタをリセット
	const hoverBgCssValue = getHoverColorCssValue(buttonHoverBgColorCustom);
	if (hoverBgCssValue) {
		inlineCss += ` .vk_button.vk_button-${blockId} .vk_button_link:hover {
			background-color: ${hoverBgCssValue} !important;
			border-color: ${hoverBgCssValue} !important;
			box-shadow: none !important;
			opacity: 1 !important;
			filter: none !important;
		}`;
	}

	// ホバー時のテキスト色が設定されている場合
	const hoverTextCssValue = getHoverColorCssValue(buttonHoverTextColorCustom);
	if (hoverTextCssValue) {
		inlineCss += ` .vk_button.vk_button-${blockId} .vk_button_link:hover {
			color: ${hoverTextCssValue} !important;
		}`;
		inlineCss += ` .vk_button.vk_button-${blockId} .vk_button_link:hover .vk_button_link_txt,
		.vk_button.vk_button-${blockId} .vk_button_link:hover .vk_button_link_subCaption,
		.vk_button.vk_button-${blockId} .vk_button_link:hover .vk_button_link_before,
		.vk_button.vk_button-${blockId} .vk_button_link:hover .vk_button_link_after {
			color: ${hoverTextCssValue} !important;
		}`;
	}

	return inlineCss;
};

const generateInlineGapCss = (attributes, isSave) => {
	const {
		buttonWidthMobile,
		buttonWidthTablet,
		buttonWidth,
		outerGap,
		blockId,
	} = attributes;
	let inlineCss = '';
	const propaty = isSave
		? '.vk_button'
		: '.vk_buttons .vk_buttons_col .block-editor-block-list__layout .vk_button';

	// 親ブロックのギャップを反映
	if (outerGap) {
		if (buttonWidthMobile) {
			inlineCss += `@media (max-width: 575.98px) {
				${propaty}.vk_button-${blockId} {
					width: calc(${buttonWidthMobile}% - calc(${outerGap} - calc(${outerGap} / (100 / ${buttonWidthMobile}))) - 1px);
				}
			}`;
		}
		if (buttonWidthTablet) {
			inlineCss += `@media(min-width: 576px) and (max-width: 991.98px) {
				${propaty}.vk_button-${blockId} {
					width: calc(${buttonWidthTablet}% - calc(${outerGap} - calc(${outerGap} / (100 / ${buttonWidthTablet}))) - 1px);
				}
			}`;
		}
		if (buttonWidth) {
			inlineCss += `@media (min-width: 992px) {
					${propaty}.vk_button-${blockId} {
					width: calc(${buttonWidth}% - calc(${outerGap} - calc(${outerGap} / (100 / ${buttonWidth}))) - 1px );
				}
			}`;
		}
	}

	return inlineCss;
};

const VKButtonInlineEditorCss = createHigherOrderComponent((BlockEdit) => {
	return (props) => {
		const { attributes } = props;

		if ('vk-blocks/button' === props.name) {
			const cssTag = generateInlineCss(attributes);
			const cssEditor = generateInlineGapCss(attributes, false);
			if (cssTag !== '' || cssEditor !== '') {
				return (
					<>
						<BlockEdit {...props} />
						<style type="text/css">
							{cssTag} {cssEditor}
						</style>
					</>
				);
			}
			return <BlockEdit {...props} />;
		}
		return <BlockEdit {...props} />;
	};
}, 'VKButtonInlineEditorCss');
addFilter('editor.BlockEdit', 'vk-blocks/button', VKButtonInlineEditorCss);

const VKButtonInlineCss = (el, type, attributes) => {
	if ('vk-blocks/button' === type.name) {
		//現在実行されている deprecated内の save関数のindexを取得
		const deprecatedFuncIndex = deprecated.findIndex(
			(item) => item.save === type.save
		);

		// 最新版
		if (-1 === deprecatedFuncIndex) {
			// NOTE: useBlockProps + style要素を挿入する場合、useBlockPropsを使った要素が最初（上）にこないと、
			// カスタムクラスを追加する処理が失敗する[
			const cssTag = generateInlineCss(attributes);
			const cssEditor = generateInlineGapCss(attributes, true);
			if (cssTag !== '' || cssEditor !== '') {
				return (
					<>
						{el}
						<style type="text/css">
							{cssTag} {cssEditor}
						</style>
					</>
				);
			}
			return el;

			//後方互換
		}
		const DeprecatedHook = deprecatedHooks[deprecatedFuncIndex];
		return <DeprecatedHook el={el} attributes={attributes} />;
	}
	return el;
};
addFilter('blocks.getSaveElement', 'vk-blocks/button', VKButtonInlineCss, 11);
