'use strict';

/// <reference path="../../assets/jquery.d.ts" />

//Note that we use the WordPress version of Lodash here, not the one from the plugin.
declare const lodash;
declare const wsAdminCustomizerPreview;

declare const wsAmeBrandingClsPreviewData: {
	/**
	 * Setting ID -> Color variable name
	 */
	colorSettings: {
		[settingId: string]: {
			initialValue: string | null;
			variableName: string;
		}
	};
	/**
	 * Color variable name -> index
	 */
	colorVariableOrder: Record<string, number>;
	previewBaseUrl: string;

	isOverrideEnabled: boolean;
	overrideSettingId: string;
	//This is expected to always be false in the current implementation, but I'm leaving
	//it here in case I find a way to enable it without using an actual setting.
	forceEnablePreview: boolean;
};

(function ($) {
	if (typeof lodash === 'undefined') {
		return;
	}

	let isOverrideEnabled = wsAmeBrandingClsPreviewData.isOverrideEnabled;
	let forceEnablePreview = wsAmeBrandingClsPreviewData.forceEnablePreview;

	let currentColors: { [variableName: string]: string | null } = {};

	let $nodesToRemove: JQuery[] = [];
	let $latestStylesheet: JQuery = null;

	const updateColorPreview = lodash.throttle(function () {
		let colors = [];
		let hasCustomColors = false;
		for (let variableName in currentColors) {
			let color = currentColors[variableName];
			if ((color !== null) && (color !== '')) {
				hasCustomColors = true;
				const index = wsAmeBrandingClsPreviewData.colorVariableOrder[variableName];
				colors[index] = color.replace('#', '');
			}
		}

		//Preview is enabled only if the "is_color_override_enabled" setting is enabled
		//or if the special "force enable preview" setting is enabled. Preview is disabled
		//if there are no color settings.
		const isPreviewEnabled = (isOverrideEnabled || forceEnablePreview) && hasCustomColors;
		if (!isPreviewEnabled) {
			//Remove all preview stylesheets.
			$nodesToRemove.forEach(function ($node) {
				$node.remove();
			});
			$nodesToRemove = [];
			if ($latestStylesheet) {
				$latestStylesheet.remove();
				$latestStylesheet = null;
			}

			//Also remove the normal color scheme stylesheet generated by PHP
			//if it looks like it was added by this plugin.
			const $colorSchemeStyle = $('head link#colors-css');
			if ($colorSchemeStyle.length > 0) {
				const href = $colorSchemeStyle.attr('href');
				if (href && (href.indexOf('ame_branding_preview_colors')) !== -1) {
					$colorSchemeStyle.remove();
				}
			}

			return;
		}

		const stylesheetUrl = wsAmeBrandingClsPreviewData.previewBaseUrl
			+ '&colors=' + encodeURIComponent(colors.join('.'));

		const $stylesheet = $(
			'<link/>',
			{
				'rel': 'stylesheet',
				'type': 'text/css',
				'href': stylesheetUrl
			}
		);

		if ($latestStylesheet !== null) {
			$nodesToRemove.push($latestStylesheet);
		}
		$latestStylesheet = $stylesheet;

		$stylesheet.on('load', function () {
			if ($nodesToRemove.length > 0) {
				let remaining: typeof $nodesToRemove = [];
				$nodesToRemove.forEach(function ($node) {
					if ($node.is($stylesheet)) {
						//Keep the current stylesheet until the next one loads and removes it.
						//This helps avoid flicker when the user drags color sliders.
						remaining.push($node);
					} else {
						$node.remove();
					}
				});
				$nodesToRemove = remaining;
			}
		});

		$stylesheet.appendTo('head');
	}, 1000);

	function registerPreviewUpdaters() {
		//Initialize the current colors.
		for (const settingId in wsAmeBrandingClsPreviewData.colorSettings) {
			const setting = wsAmeBrandingClsPreviewData.colorSettings[settingId];
			currentColors[setting.variableName] = setting.initialValue;

			wsAdminCustomizerPreview.registerPreviewer(settingId, function (newColor: string | null) {
				currentColors[setting.variableName] = newColor;
				updateColorPreview();
			});
		}

		//Watch for changes to the "color scheme override" setting.
		if (wsAmeBrandingClsPreviewData.overrideSettingId) {
			wsAdminCustomizerPreview.registerPreviewer(
				wsAmeBrandingClsPreviewData.overrideSettingId,
				function (newValue: boolean) {
					isOverrideEnabled = !!newValue;
					updateColorPreview();
				}
			);
		}

		//Enable preview when the user enters the "Color Scheme" section. The "helper"
		//script (in the same directory) detects the section change and calls this method.
		wsAdminCustomizerPreview.registerRpcMethod(
			'ameBrandingAdminColors.setForceEnablePreview',
			function (arg) {
				forceEnablePreview = !!arg;
				updateColorPreview();
			}
		);
	}

	if (typeof wsAdminCustomizerPreview !== 'undefined') {
		registerPreviewUpdaters();
	} else {
		$(document).on('adminMenuEditor:acPreviewStart', function () {
			registerPreviewUpdaters();
		});
	}

})(jQuery);
