(function ($) {
	'use strict';

	if ('undefined' === typeof wp || 'undefined' === typeof wp.customize) {
		return;
	}

	// Keep these percentages in sync with kubelio_generate_hex_color() calls
	// in inc/core/class-block.php so the customizer preview matches saved output.
	var SHADES = [
		{ percent: 70, light: 'primary-light', dark: 'primary-dark' },
		{ percent: 40, light: 'primary-lighter', dark: 'primary-darker' },
		{ percent: 10, light: 'primary-lightest', dark: 'primary-darkest' },
	];

	var SELECTOR = '.kubelio-default-scheme, .is-style-base';
	var STYLE_ID = 'kubelio-customizer-derived-colors';

	function generateHexColor(hex, percent, mode) {
		hex = String(hex || '').trim().replace('#', '');

		if (3 === hex.length) {
			hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
		}

		if (6 !== hex.length || ! /^[0-9a-fA-F]{6}$/.test(hex)) {
			return '#ffffff';
		}

		var ratio  = Math.max(0, Math.min(100, parseFloat(percent))) / 100;
		var target = 'dark' === mode ? 0 : 255;

		var channel = function (offset) {
			var value = Math.round(parseInt(hex.substr(offset, 2), 16) * ratio + target * (1 - ratio));
			return ('0' + value.toString(16)).slice(-2);
		};

		return '#' + channel(0) + channel(2) + channel(4);
	}

	function getStyleTag() {
		var $tag = $('#' + STYLE_ID);

		if (! $tag.length) {
			$tag = $('<style>', { id: STYLE_ID }).appendTo('head');
		}

		return $tag;
	}

	function updateDerivedColors(primary) {
		var rules = '';

		SHADES.forEach(function (shade) {
			rules += '--wp--preset--color--' + shade.light + ':' + generateHexColor(primary, shade.percent, 'light') + ';';
			rules += '--wp--preset--color--' + shade.dark + ':' + generateHexColor(primary, shade.percent, 'dark') + ';';
		});

		getStyleTag().text(SELECTOR + '{' + rules + '}');
	}

	wp.customize('color_primary', function (value) {
		updateDerivedColors(value.get());
		value.bind(updateDerivedColors);
	});
})(jQuery);
