import {
	useState,
	useEffect
} from '@wordpress/element';
import {
	Flex,
	FlexItem,
	Popover,
	Button,
	ColorPalette,
} from '@wordpress/components';

import { useControlSettingSet } from '../_hooks';

import { __ } from '@wordpress/i18n';

type GlobalColorOverride = {
	slug: string,
	color: string,
};

function mergeBuiltInPalette(palette: paletteColor[], overrides: GlobalColorOverride[]) {
	if (!palette?.length) {
		return [];
	}

	const overrideMap = new Map((overrides || []).map((item) => [item.slug, item.color]));

	return palette.map((item) => ({
		...item,
		color: overrideMap.get(item.slug) || item.color,
	}));
}

type Props = {
	controlSetting: any, // wp.customize.setting or wp.customize.settings[key]
	value: string,
	resetDefault?: string,
	title: string,
	description?: string,
	hiddenTitle?: boolean
}

export default function ApuraColor({ controlSetting, value, resetDefault, title, description, hiddenTitle = false }: Props) {

	const [isVisible, setIsVisible] = useState<boolean>(false);
	const [color, setColor] = useState<string>(value);
	const [builtInPalette] = useState<paletteColor[]>(apuraCustomizerControl?.builtInPalette || []);
	const [paletteOverrides, setPaletteOverrides] = useState<GlobalColorOverride[]>(apuraCustomizerControl?.paletteOverrides || []);
	const [_customPalette, setCustomPalette] = useState<paletteColor[]>(apuraCustomizerControl?.customPalette);

	// カスタマイザーでのパレット上書き設定値が変わったときに再レンダリングする
	useEffect(() => {
		wp.customize(apuraCustomizerControl?.paletteOverridesId, (setting: any) => {
			setting.bind((newOverrides: GlobalColorOverride[]) => {
				setPaletteOverrides(newOverrides || []);
			});
		});
		wp.customize(apuraCustomizerControl?.customPaletteId, (setting: any) => {
			setting.bind((newPalette: paletteColor[]) => {
				setCustomPalette(newPalette);
			});
		});
	}, []);


	// console.log(color);


	useControlSettingSet({
		controlSetting,
		value: color
	});


	const toggleVisible = () => {
		setIsVisible((state) => !state);
	};

	const handleColorChange = (newColor?: string) => {
		setColor(newColor || '');
	}

	const handleRestClick = () => {
		setColor(resetDefault || '');
	}


	// 解決済みパレットとカスタムパレットをマージする.
	const resolvedBuiltInPalette = mergeBuiltInPalette(builtInPalette, paletteOverrides);
	const margePalette = [...resolvedBuiltInPalette, ..._customPalette];

	// カラーはカスタムプロパティを使用.
	const colors = margePalette?.map(({ name, slug }) => {
		return {
			name,
			color: `var(--${slug})`
		}
	});

	// パレット上の色定義
	const paletteStyles: CustomCSS = {
		padding:'6px'
	};

	margePalette.forEach(obj => {
		paletteStyles[`--${obj.slug}`] = obj.color;
	});

	// var(--slug) を color に変換.
	let colorCode = color;
	if (color.includes('var(--')) {
		let _color = margePalette.find(({ slug }) => slug === color.replace(/^var\(--/, '').replace(/\)$/, '')) || null;
		colorCode = _color?.color || '';
	}

	return (
		<div className='apura-color-control'>
			<Flex>
				{!hiddenTitle &&
				<FlexItem>
					<label className="customize-control-title">{title}</label>
				</FlexItem>
				}
				<FlexItem>
					<Button
						className='apura-color-control__button'
						onClick={ toggleVisible }
						aria-label={title}
						title={title}
						style={colorCode ? {background:colorCode} : undefined}
					></Button>
					{isVisible &&
					<Popover
						onClose={() => setIsVisible( false ) }
					>
						<div style={paletteStyles}>
							<ColorPalette
								colors={colors}
								value={color}
								enableAlpha
								clearable={false}
								onChange={handleColorChange}
							/>
						</div>
						<Button
							variant="primary"
							className='apura-color-control__reset'
							onClick={handleRestClick}
						>
							{__('Reset', 'apura')}
						</Button>
					</Popover>
					}
				</FlexItem>
			</Flex>
			{description &&
				<p className='description customize-control-description'>{description}</p>
			}
		</div>
	)
}
