<?php

namespace WPDataAccess\Premium\WPDAPRO_Data_Publisher {

	use WPDataAccess\Data_Tables\WPDA_Data_Tables;
	use WPDataAccess\Plugin_Table_Models\WPDA_Publisher_Model;
	use WPDataAccess\Premium\WPDAPRO_Templates\WPDAPRO_Template_Data_Publisher_Color;
	use WPDataAccess\Premium\WPDAPRO_Templates\WPDAPRO_Template_Data_Publisher_Corner;
	use WPDataAccess\Premium\WPDAPRO_Templates\WPDAPRO_Template_Data_Publisher_Modal;
	use WPDataAccess\Premium\WPDAPRO_Templates\WPDAPRO_Template_Data_Publisher_Space;
	use WPDataAccess\WPDA;

	class WPDAPRO_Data_Publisher_Manage_Styles {

		const WPDA_DATA_PUBLISHER_MANAGE_STYLES          = 'wpda_data_publisher_styles';
		const WPDA_DATA_PUBLISHER_MANAGE_STYLES_DEFAULTS = array( 'default' => 'default' );

		const WPDA_DATA_PUBLISHER_MANAGE_STYLES_SLUG    = 'wpdataaccess-manage-styles';
		const WPDA_DATA_PUBLISHER_MANAGE_STYLES_TITLE   = 'WP Data Access - Manage data table styles';

		/**
		 * DataTable color settings
		 * ------------------------
		 * $header_label_color = header label
		 * $header_bg_color    = header background
		 * $text_color         = text
		 * $hover_color        = hover background
		 * $odd_bg_color       = background odd rows
		 * $even_bg_color      = background even rows
		 * $border_color       = border
		 */
		const WPDA_DATA_PUBLISHER_STYLE_COLORS          = 'wpda_data_publisher_style_colors';
		const WPDA_DATA_PUBLISHER_STYLE_COLORS_DEFAULTS = array(
			'default'     => array(
				'header_label_color' => '#444444',
				'header_bg_color'    => '#b0b0b0',
				'text_color'         => '#444444',
				'hover_color'        => '#ededed',
				'odd_bg_color'       => '#f9f9f9',
				'even_bg_color'      => '#ffffff',
				'border_color'       => '#b0b0b0',
				'selected'			 => '#cecece',
			),
			'black'       => array(
				'header_label_color' => '#ffffff',
				'header_bg_color'    => '#23282d',
				'text_color'         => '#000000',
				'hover_color'        => '#ababab',
				'odd_bg_color'       => '#e5e5e5',
				'even_bg_color'      => '#ffffff',
				'border_color'       => '#23282d',
				'selected'			 => '#cecece',
			),
			'blue'        => array(
				'header_label_color' => '#ffffff',
				'header_bg_color'    => '#096484',
				'text_color'         => '#096484',
				'hover_color'        => '#74b6ce',
				'odd_bg_color'       => '#f0f8ff',
				'even_bg_color'      => '#ffffff',
				'border_color'       => '#096484',
				'selected'			 => '#bfcfdf',
			),
			'blue/yellow' => array(
				'header_label_color' => '#ffffff',
				'header_bg_color'    => '#096484',
				'text_color'         => '#096484',
				'hover_color'        => '#ffd300',
				'odd_bg_color'       => '#ffffdd',
				'even_bg_color'      => '#ffffff',
				'border_color'       => '#096484',
				'selected'			 => '#bfcfdf',
			),
			'green'       => array(
				'header_label_color' => '#ffffff',
				'header_bg_color'    => '#2e6409',
				'text_color'         => '#2e6409',
				'hover_color'        => '#abcdab',
				'odd_bg_color'       => '#e0eee0',
				'even_bg_color'      => '#ffffff',
				'border_color'       => '#2e6409',
				'selected'			 => '#dbddd4',
			),
			'pink'        => array(
				'header_label_color' => '#ffffff',
				'header_bg_color'    => '#ff1493',
				'text_color'         => '#ff1493',
				'hover_color'        => '#ffb9d5',
				'odd_bg_color'       => '#fff0f5',
				'even_bg_color'      => '#ffffff',
				'border_color'       => '#ff1493',
				'selected'			 => '#f7e4eb',
			),
			'red'         => array(
				'header_label_color' => '#ffffff',
				'header_bg_color'    => '#d1675a',
				'text_color'         => '#d1675a',
				'hover_color'        => '#ffbbbb',
				'odd_bg_color'       => '#ffeeee',
				'even_bg_color'      => '#ffffff',
				'border_color'       => '#d1675a',
				'selected'			 => '#f5d6d6',
			),
			'yellow'      => array(
				'header_label_color' => '#ffffff',
				'header_bg_color'    => '#ffd300',
				'text_color'         => '#836e01',
				'hover_color'        => '#fff8e6',
				'odd_bg_color'       => '#ffffdd',
				'even_bg_color'      => '#ffffff',
				'border_color'       => '#ffd300',
				'selected'			 => '#e3e7d4',
			),
		);

		const DEFAULT_COLOR   = 'default';
		const DEFAULT_SPACING = '10';
		const DEFAULT_RADIUS  = '0';
		const DEFAULT_MODAL   = '80';

		private static $styles = null;
		private static $colors = null;

		public function __construct( $args = array() ) {
			if ( ! current_user_can('manage_options') ) {
				wp_die( __( 'ERROR: Not authorized', 'wp-data-access' ) );
			}

			self::init();

			WPDA_Data_Tables::enqueue_styles_and_script();
		}

		public static function init() {
			if ( null === self::$styles ) {
				$user_styles = self::get_user_styles();

				if ( false !== $user_styles ) {
					self::$styles = array_merge( self::WPDA_DATA_PUBLISHER_MANAGE_STYLES_DEFAULTS, $user_styles );//phpcs:ignore - 8.1 proof
				} else {
					self::$styles = self::WPDA_DATA_PUBLISHER_MANAGE_STYLES_DEFAULTS;
				}
			}
			if ( null === self::$colors ) {
				$user_colors = self::get_user_colors();

				if ( false !== $user_colors ) {
					self::$colors = array_merge( self::WPDA_DATA_PUBLISHER_STYLE_COLORS_DEFAULTS, $user_colors );//phpcs:ignore - 8.1 proof
				} else {
					self::$colors = self::WPDA_DATA_PUBLISHER_STYLE_COLORS_DEFAULTS;
				}
			}
		}

		public function show() {
			$default_colors = self::$colors[ self::DEFAULT_COLOR ];
			?>
			<div class="wrap">
				<h1 class="wp-heading-inline">
					<span style="vertical-align:top">Premium Data Tables</span>
				</h1>
				<fieldset class="wpda_fieldset">
					<legend>
						Premium Style Manager
					</legend>
					<div class="manage-styles-container">
						<div class="sim">
							<label>
								Simulate front-end for publication
							</label>
							<select id="pub_listbox">
								<option value="">-- select from list --</option>
								<?php
								$pubs = WPDA_Publisher_Model::get_publication_list();
								foreach ( $pubs as $pub ) {
									$wpnonce = esc_attr( wp_create_nonce( "wpda-publication-{$pub['pub_id']}" ) );
									echo "<option value='{$pub['pub_id']}' data-wpnonce='{$wpnonce}' data-tablename='{$pub['pub_table_name']}'>{$pub['pub_name']} ({$pub['pub_id']})</option>";
								}
								?>
							</select>
							<i id="refresh-page" class="fa-solid fa-arrows-rotate wpda_tooltip" title="Refresh page"></i>
						</div>
						<fieldset class="wpda_fieldset">
							<legend>
								Premium styling
							</legend>
							<div>
								<div class="grid">
									<span>
										<label>
											Style name
										</label>
										<span class="manage-styles-container-inline-grid-4">
											<select id="pub_style_name">
												<?php
												foreach ( self::$styles as $key => $style ) {
													if ( self::DEFAULT_COLOR === $style ) {
														$color   = self::DEFAULT_COLOR;
														$spacing = self::DEFAULT_SPACING;
														$radius  = self::DEFAULT_RADIUS;
														$modal   = self::DEFAULT_MODAL;
													} else {
														$current_style = json_decode( $style, true );

														$color         = isset( $current_style['color'] ) ?
															$current_style['color'] : self::DEFAULT_COLOR;
														$spacing       = isset( $current_style['spacing'] ) ?
															$current_style['spacing'] : self::DEFAULT_SPACING;
														$radius        = isset( $current_style['radius'] ) ?
															$current_style['radius'] : self::DEFAULT_RADIUS;
														$modal         = isset( $current_style['modal'] ) ?
															$current_style['modal'] : self::DEFAULT_MODAL;
													}
													echo "<option value='{$key}' data-color='{$color}' data-spacing='{$spacing}' data-radius='{$radius}' data-modal='{$modal}'>{$key}</option>";
												}
												?>
											</select>
											<i id="button-style-save" class="fas fa-check button button-secondary wpda_tooltip" title="Save style"></i>
											<i id="button-style-save-as" class="fas fa-check-double button button-secondary wpda_tooltip" title="Save style as"></i>
											<i id="button-style-delete" class="fas fa-trash button button-secondary wpda_tooltip" title="Delete style"></i>
										</span>
									</span>
									<span>
										<label>
											Color schemas
										</label>
										<span class="manage-styles-container-inline-grid-3">
											<select id="pub_style_color">
												<?php
												foreach ( self::$colors as $key => $value ) {
													echo "<option value='{$key}'>{$key}</option>";
												}
												?>
											</select>
											<i id="button-color-edit" class="fas fa-palette button button-secondary wpda_tooltip" title="Manage color schema"></i>
											<i id="button-color-delete" class="fas fa-trash button button-secondary wpda_tooltip" title="Delete color schema"></i>
										</span>
									</span>
									<span>
										<label>
											Column spacing
										</label>
										<span class="manage-styles-container-inline-grid">
											<input id="pub_style_space" type="range" value="10" class="wpda_data_type_number" min="0" max="50">
											<span id="pub_style_space_val" class="wpda-range">10px</span>
										</span>
									</span>
									<span>
										<label>
											Border radius
										</label>
										<span class="manage-styles-container-inline-grid">
											<input id="pub_style_corner" type="range" value="0" class="wpda_data_type_number" min="0" max="50">
											<span id="pub_style_corner_val" class="wpda-range">0px</span>
										</span>
									</span>
									<span>
										<label>
											Modal width
										</label>
										<span class="manage-styles-container-inline-grid">
											<input id="pub_style_modal_width" type="range" value="80" class="wpda_data_type_number" min="50" max="100">
											<span id="pub_style_modal_width_val" class="wpda-range">80%</span>
										</span>
									</span>
								</div>
							</div>
							<div id="edit-color-schema" style="display:none">
								<fieldset class="wpda_fieldset">
									<span class="dashicons dashicons-dismiss icon-close wpda_tooltip" title="Close panel"></span>
									<legend>
										Color schema
									</legend>
									<div class="color-container-outer">
										<div class="color-container">
											<div>
												<label for="header_bg_color">
													Header background
												</label>
												<input type="color" id="header_bg_color" value="<?php echo esc_attr( $default_colors['header_bg_color'] ); ?>">
											</div>
											<div>
												<label for="header_label_color">
													Header label
												</label>
												<input type="color" id="header_label_color" value="<?php echo esc_attr( $default_colors['header_label_color'] ); ?>">
											</div>
											<div>
												<label for="text_color">
													Text
												</label>
												<input type="color" id="text_color" value="<?php echo esc_attr( $default_colors['text_color'] ); ?>">
											</div>
											<div>
												<label for="hover_color">
													Hover background
												</label>
												<input type="color" id="hover_color" value="<?php echo esc_attr( $default_colors['hover_color'] ); ?>">
											</div>
											<div>
												<label for="odd_bg_color">
													Background odd rows
												</label>
												<input type="color" id="odd_bg_color" value="<?php echo esc_attr( $default_colors['odd_bg_color'] ); ?>">
											</div>
											<div>
												<label for="even_bg_color">
													Background even rows
												</label>
												<input type="color" id="even_bg_color" value="<?php echo esc_attr( $default_colors['even_bg_color'] ); ?>">
											</div>
											<div>
												<label for="border_color">
													Border
												</label>
												<input type="color" id="border_color" value="<?php echo esc_attr( $default_colors['border_color'] ); ?>">
											</div>
											<div>
												<label for="selected">
													Selected
												</label>
												<input type="color" id="selected" value="<?php echo esc_attr( $default_colors['selected'] ); ?>">
											</div>
										</div>
										<div class="color-container-buttons">
											<span></span>
											<a id="button-color-save" href="javascript:void(0)" class="button button-primary">
												<i class="fas fa-check wpda_icon_on_button"></i>
												Save
											</a>
											<a id="button-color-save-as" href="javascript:void(0)" class="button button-secondary">
												<i class="fas fa-check-double wpda_icon_on_button"></i>
												Save as
											</a>
										</div>
									</div>
								</fieldset>
							</div>
						</fieldset>
						<iframe id="wpda-front-end"></iframe>
					</div>
				</fieldset>
			</div>
			<?php
			$this->css();
			$this->js();
		}

		private function css() {
			?>
			<style>
				fieldset {
					margin: 20px 0 0 0;
				}

                input[type="range"] {
					display: inline-block;
				}

                .manage-styles-container {
                    display: flex;
                    flex-direction: column;
                    min-height: 75vh;
				}
                .sim {
					margin-bottom: 5px;
                }
                .grid {
					display: grid;
                    grid-template-columns: 1fr 1fr 1fr 1fr 1fr;
					gap: 10px;
                    width: 100%;
				}
                .grid > span {
                    display: grid;
                    grid-template-rows: 1fr;
                }
                .manage-styles-container-inline-grid {
                    display: inline-grid;
                    grid-template-columns: 1fr auto;
                    align-items: center;
				}
                .manage-styles-container-inline-grid-3 {
                    display: inline-grid;
                    grid-template-columns: 1fr auto auto;
                    align-items: center;
                }
                .manage-styles-container-inline-grid-3 i {
					margin: 0 1px !important;
                }
                .manage-styles-container-inline-grid-4 {
                    display: inline-grid;
                    grid-template-columns: 1fr auto auto auto;
                    align-items: center;
                }
                .manage-styles-container-inline-grid-4 i {
                    margin: 0 1px !important;
                }
                div.grid > span > label {
                    margin-bottom: 5px;
                }
                .manage-styles-container iframe {
                    flex-grow: 1;
				}

				.color-container-outer {
					display: grid;
					grid-template-columns: auto auto;
                    gap: 10px;
				}

				.color-container {
					display: flex;
					flex-grow: 1;
					flex-wrap: wrap;
					text-align: center;
					gap: 10px;
				}
                .color-container div {
					display: grid;
                }
				input[type=color] {
					width: 180px;
				}
                .color-container label {
					text-align: left;
				}

				.color-container-buttons {
					display: grid;
                    grid-template-rows: 1fr auto auto;
					gap: 5px;
                    justify-content: flex-end;
				}
				.color-container-buttons a {
					width: 180px;
					height: 30px;
					text-align: center;
				}

				#edit-color-schema fieldset {
					margin: 10px 0 0 0;
					position: relative;
				}
				.icon-close {
                    position: absolute;
                    right: -5px;
                    top: -15px;
                    font-size: 150%;
					cursor: pointer;
				}

				iframe {
                    margin-top: 20px;
                }
			</style>
			<?php
		}

		private function js() {
			?>
			<script type="application/javascript">
				var frontend = null;
				var colorTemplate = null;
				var isUpdated = false;
				var systemColors = <?php echo json_encode( self::get_system_color_keys() ); ?>;
				var userColors = <?php echo json_encode( self::get_user_color_keys() ) ?>;

				// Monitor publication status.
				var targetObj = {};
				window.top['wpda_publication_status'] = new Proxy(targetObj, {
					set: function (target, key, value) {
						resetHeightFrontendPage();

						let pubId = jQuery("#pub_listbox option:selected").val();
						window.top['wpda_publication_primary_css_classes'] =
							'wpda-color-' + pubId +
							' wpda-space-' + pubId +
							' wpda-corner-' + pubId +
							' wpda-modal-' + pubId;

						publicationStyling("wpda-premium-styling-colors");
						publicationStyling("wpda-premium-styling-spacing");
						publicationStyling("wpda-premium-styling-borders");
						publicationStyling("wpda-premium-styling-modal");
					}
				});

				function refreshFrontendPage() {
					frontend.attr("src", "<?php echo site_url( '/' . self::WPDA_DATA_PUBLISHER_MANAGE_STYLES_SLUG ); // phpcs:ignore WordPress.Security.EscapeOutput ?>");
					frontend.show();
				}

				function resetHeightFrontendPage() {
					frontend.contents().find("#wpda-premium-styling-borders, #wpda-premium-styling-colors, #wpda-premium-styling-spacing").remove();
				}

				function executeModalScript(response) {
					let tableName = jQuery("#pub_listbox option:selected").data('tablename');
					let pubId = jQuery("#pub_listbox option:selected").val();

					let fncSetModalWidth = tableName + pubId + "SetModalWidth";
					if (typeof document.getElementById("wpda-front-end").contentWindow[fncSetModalWidth] === "function") {
						document.getElementById("wpda-front-end").contentWindow[fncSetModalWidth]();
					}
				}

				function addStyle(elemId, response, callback) {
					try {
						let json = JSON.parse(response);
						if (json.status==="OK") {
							frontend.contents().find("#" + elemId).remove();
							frontend.contents().find("#publication_styling").append(json.msg);
							if (callback!==undefined) {
								callback(response);
							}
						} else {
							console.error("WP Data Access ERROR: " + json.msg);
							checkConsole();
						}
					} catch (e) {
						console.error("WP Data Access ERROR:");
						console.error(e);
						checkConsole();
					}
				}

				function publicationFrontend(wpnonce, pubId) {
					jQuery.ajax({
						type: "POST",
						url: "<?php echo admin_url( 'admin-ajax.php?action=wpda_publication_frontend_simulation' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>",
						data: {
							wpnonce: wpnonce,
							pub_id: pubId
						}
					}).done(
						function (response) {
							try {
								let json = JSON.parse(response);
								if (json.status==="OK") {
									refreshFrontendPage();
								} else {
									console.error("WP Data Access ERROR: " + json.msg);
									checkConsole();
								}
							} catch (e) {
								console.error("WP Data Access ERROR:");
								console.error(e);
								checkConsole();
							}
						}
					);
				}

				function colorChanged(response) {
					try {
						let json = JSON.parse(response);
						if (json.status==="OK") {
							if (colorTemplate===null) {
								// Save raw template for real time refresh mechanism.
								if (json.raw!==undefined) {
									colorTemplate = json.raw;
								}
							}
							if (json.colors!==undefined) {
								if (isUpdated) {
									if (wpdaConfirm(json)) {
										setColors(json);
										isUpdated = false;
									} else {
										changeColorInteractively();
									}
								} else {
									setColors(json);
								}
							}
						} else {
							console.error("WP Data Access ERROR: " + json.msg);
							checkConsole();
						}
					} catch (e) {
						console.error("WP Data Access ERROR:");
						console.error(e);
						checkConsole();
					}
				}

				function wpdaConfirm(json) {
					jQuery("<p></p>").append("Overwrite current color schema?").dialog({
						title: "Confirm",
						modal: true,
						buttons: {
							"Yes": function() {
								jQuery(this).dialog("close");
								setColors(json);
								changeColorInteractively();
								isUpdated = false;
							},
							"No": function() {
								jQuery(this).dialog("close");
							}
						}
					});
				}

				function setColors(json) {
					// Write colors to color panel.
					let colors = JSON.parse(json.colors);
					for (let color in colors) {
						jQuery("#" + color).val(colors[color]);
					}
				}

				function publicationStyling(elemId) {
					let data = {};
					if (jQuery("#pub_listbox option:selected").data('tablename')===undefined) {
						// No publication selected
						data.t = "none";
						data.i = "0";
					} else {
						data.t = jQuery("#pub_listbox option:selected").data('tablename');
						data.i = jQuery("#pub_listbox option:selected").val();
					}

					let callback = undefined;
					switch(elemId) {
						case "wpda-premium-styling-colors":
							data["c"] = jQuery("#pub_style_color option:selected").val();
							if (colorTemplate===null) {
								data["init"] = true;
							}
							callback = colorChanged;
							break;
						case "wpda-premium-styling-spacing":
							data["s"] = jQuery("#pub_style_space").val();
							break;
						case "wpda-premium-styling-borders":
							data["r"] = jQuery("#pub_style_corner").val();
							break;
						case "wpda-premium-styling-modal":
							data["m"] = jQuery("#pub_style_modal_width").val();
							callback = executeModalScript;
							break;
						default:
							// Incorrect call, missing arguments
							return;
					}

					jQuery.ajax({
						type: "POST",
						url: "<?php echo admin_url( 'admin-ajax.php?action=wpda_publication_premium_styling' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>",
						data: data
					}).done(
						function (response) {
							addStyle(elemId, response, callback);
						}
					);
				}

				function changeColorInteractively() {
					if (colorTemplate!==null && frontend!==null) {
						let template = colorTemplate;

						let tableName = jQuery("#pub_listbox option:selected").data('tablename');
						let pubId = jQuery("#pub_listbox option:selected").val();
						let cls = "wpda-color-" + pubId;

						template = template.replaceAll("$table_name", tableName);
						template = template.replaceAll("$pub_id", pubId);
						template = template.replaceAll("$class", cls);

						jQuery("input[type=color]").each(function () {
							let id = jQuery(this).attr("id");
							let val = jQuery(this).val();

							if (id==="selected") {
								let bigint = parseInt(val.substring(1), 16);

								let red = (bigint >> 16) & 255;
								let green = (bigint >> 8) & 255;
								let blue = bigint & 255;

								template = template.replaceAll("$selected_red", red);
								template = template.replaceAll("$selected_green", green);
								template = template.replaceAll("$selected_blue", blue);
							} else {
								template = template.replaceAll("$"+id, val);
							}
						});

						frontend.contents().find("#wpda-premium-styling-colors").remove();
						frontend.contents().find("#publication_styling").append(template);

						isUpdated = true;
					}
				}

				function get_user_color_schema() {
					let colors = {};

					jQuery(".color-container input[type=color]").each(function() {
						let id = jQuery(this).attr("id");
						let val = jQuery(this).val();

						colors[id] = val;
					});

					return colors;
				}

				function addColorSchema(schemaName, colorSchema) {
					jQuery.ajax({
						type: "POST",
						url: "<?php echo admin_url( 'admin-ajax.php?action=wpda_publication_premium_add_color_schema' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>",
						data: {
							w: "<?php echo esc_attr( wp_create_nonce( self::WPDA_DATA_PUBLISHER_STYLE_COLORS . WPDA::get_current_user_id() ) );  ?>",
							n: schemaName,
							c: JSON.stringify(colorSchema)
						}
					}).done(
						function (response) {
							try {
								let json = JSON.parse(response);
								if (json.status==="OK") {
									if (jQuery("#pub_style_color option:selected").val()!==schemaName) {
										jQuery("#pub_style_color").append(
											`<option value="${schemaName}">${schemaName}</option>`
										);
										jQuery(`#pub_style_color option[value=${schemaName}]`).attr("selected", "selected");
									}
									isUpdated = false;
									jQuery.notify("Color schema saved", "info");
								} else {
									console.error("WP Data Access ERROR: " + json.msg);
									checkConsole();
								}
							} catch (e) {
								console.error("WP Data Access ERROR:");
								console.error(e);
								checkConsole();
							}
						}
					);
				}

				function deleteColorSchema(schemaName) {
					if (systemColors.includes(jQuery("#pub_style_color option:selected").val())) {
						wpda_alert("Invalid action", "Cannot remove system color schema.");
						return;
					}

					jQuery.ajax({
						type: "POST",
						url: "<?php echo admin_url( 'admin-ajax.php?action=wpda_publication_premium_delete_color_schema' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>",
						data: {
							w: "<?php echo esc_attr( wp_create_nonce( self::WPDA_DATA_PUBLISHER_STYLE_COLORS . WPDA::get_current_user_id() ) );  ?>",
							n: schemaName
						}
					}).done(
						function (response) {
							try {
								let json = JSON.parse(response);
								if (json.status==="OK") {
									jQuery("#pub_style_color option:selected").remove();
									jQuery.notify("Color schema deleted", "info");
								} else {
									console.error("WP Data Access ERROR: " + json.msg);
									checkConsole();
								}
							} catch (e) {
								console.error("WP Data Access ERROR:");
								console.error(e);
								checkConsole();
							}
						}
					);
				}

				function saveStyle(styleName, style) {
					jQuery.ajax({
						type: "POST",
						url: "<?php echo admin_url( 'admin-ajax.php?action=wpda_publication_premium_add_style' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>",
						data: {
							w: "<?php echo esc_attr( wp_create_nonce( self::WPDA_DATA_PUBLISHER_MANAGE_STYLES . WPDA::get_current_user_id() ) );  ?>",
							n: styleName,
							s: JSON.stringify(style)
						}
					}).done(
						function (response) {
							try {
								let json = JSON.parse(response);
								if (json.status==="OK") {
									if (jQuery("#pub_style_name option:selected").val()!==styleName) {
										jQuery("#pub_style_name").append(
											`<option value="${styleName}">${styleName}</option>`
										);
										jQuery(`#pub_style_name option[value=${styleName}]`).attr("selected", "selected");
									}

									jQuery("#pub_style_name option:selected")
										.data("color", style.color)
										.data("spacing", style.spacing)
										.data("radius", style.radius)
										.data("modal", style.modal)
										.trigger("change");

									jQuery.notify("Style saved", "info");
								} else {
									console.error("WP Data Access ERROR: " + json.msg);
									checkConsole();
								}
							} catch (e) {
								console.error("WP Data Access ERROR:");
								console.error(e);
								checkConsole();
							}
						}
					);
				}

				function deleteStyle(styleName) {
					jQuery.ajax({
						type: "POST",
						url: "<?php echo admin_url( 'admin-ajax.php?action=wpda_publication_premium_delete_style' ); // phpcs:ignore WordPress.Security.EscapeOutput ?>",
						data: {
							w: "<?php echo esc_attr( wp_create_nonce( self::WPDA_DATA_PUBLISHER_MANAGE_STYLES . WPDA::get_current_user_id() ) );  ?>",
							n: styleName
						}
					}).done(
						function (response) {
							try {
								let json = JSON.parse(response);
								if (json.status==="OK") {
									jQuery("#pub_style_name option:selected").remove();
									jQuery("#pub_style_name").trigger("change");
									jQuery.notify("Style deleted", "info");
								} else {
									console.error("WP Data Access ERROR: " + json.msg);
									checkConsole();
								}
							} catch (e) {
								console.error("WP Data Access ERROR:");
								console.error(e);
								checkConsole();
							}
						}
					);
				}

				function saveStyleAs() {
					jQuery(`<p>
						Save current style as:
						<input type="text" id="save-style-as" style="margin-top:5px;width:99%" autocomplete="off" maxlength="50" />
					</p>`).dialog({
						title: "Save as",
						modal: true,
						buttons: {
							"Save as": function() {
								let style = {};

								style["color"] = jQuery("#pub_style_color option:selected").val();
								style["spacing"] = jQuery("#pub_style_space").val();
								style["radius"] = jQuery("#pub_style_corner").val();
								style["modal"] = jQuery("#pub_style_modal_width").val();

								saveStyle(jQuery("#save-style-as").val(), style);

								jQuery(this).dialog("close");
							},
							"Cancel": function() {
								jQuery(this).dialog("close");
							}
						}
					});
				}

				function saveColorAs() {
					jQuery(`<p>
						Save current color schema as:
						<input type="text" id="input-save-as" style="margin-top:5px;width:99%" autocomplete="off" maxlength="50" />
					</p>`).dialog({
						title: "Save as",
						modal: true,
						buttons: {
							"Save as": function() {
								addColorSchema(jQuery("#input-save-as").val(), get_user_color_schema());
								jQuery(this).dialog("close");
							},
							"Cancel": function() {
								jQuery(this).dialog("close");
							}
						}
					});
				}

				function checkConsole() {
					wpda_alert("Error", "Please check the console for more information.");
				}

				function setStyleIcons() {
					if (jQuery("#pub_style_name option:selected").val()==="default") {
						jQuery("#button-style-save").css("pointer-events", "none").css("opacity", "0.4");
						jQuery("#button-style-delete").css("pointer-events", "none").css("opacity", "0.4");
					} else {
						jQuery("#button-style-save").css("pointer-events", "all").css("opacity", "1");
						jQuery("#button-style-delete").css("pointer-events", "all").css("opacity", "1");
					}
				}

				function setColorDeleteIcon() {
					if (systemColors.includes(jQuery("#pub_style_color option:selected").val())) {
						jQuery("#button-color-delete").css("pointer-events", "none").css("opacity", "0.4");
					} else {
						jQuery("#button-color-delete").css("pointer-events", "all").css("opacity", "1");
					}
				}

				jQuery(function() {
					frontend = jQuery(window.top.document).find("#wpda-front-end");

					jQuery("#refresh-page").on("click", function() {
						if (jQuery("#pub_listbox option:selected").val()!=="") {
							refreshFrontendPage();
						}
					});

					jQuery("#pub_listbox").on("change", function() {
						publicationFrontend(jQuery(this).find('option:selected').data('wpnonce'), jQuery(this).val());
					});

					jQuery("#pub_style_name").on("change", function() {
						setStyleIcons();

						let selectedOption = jQuery(this).find("option:selected");
						jQuery("#pub_style_color").val(selectedOption.data("color")).trigger("change");
						jQuery("#pub_style_space").val(selectedOption.data("spacing")).trigger("change");
						jQuery("#pub_style_corner").val(selectedOption.data("radius")).trigger("change");
						jQuery("#pub_style_modal_width").val(selectedOption.data("modal")).trigger("change");
					});
					setStyleIcons();

					jQuery("#button-style-save").on("click", function() {
						let style = {};

						style["color"] = jQuery("#pub_style_color option:selected").val();
						style["spacing"] = jQuery("#pub_style_space").val();
						style["radius"] = jQuery("#pub_style_corner").val();
						style["modal"] = jQuery("#pub_style_modal_width").val();

						saveStyle(jQuery("#pub_style_name option:selected").val(), style);
					});

					jQuery("#button-style-save-as").on("click", function() {
						saveStyleAs();
					});

					jQuery("#button-style-delete").on("click", function() {
						wpda_confirm("Remove?", `Remove style? This action cannot be undone!`).then(function (a) {
							if (a) {
								deleteStyle(jQuery("#pub_style_name option:selected").val());
								refreshFrontendPage();
							}
						});
					});

					jQuery("#pub_style_color").on("change", function() {
						setColorDeleteIcon();
						publicationStyling("wpda-premium-styling-colors");
					});
					setColorDeleteIcon();

					jQuery("#button-color-edit").on("click", function() {
						jQuery("#edit-color-schema").show();
					});

					jQuery("#button-color-delete").on("click", function() {
						wpda_confirm("Remove?", `Remove color schema? This action cannot be undone!`).then(function (a) {
							if (a) {
								deleteColorSchema(jQuery("#pub_style_color option:selected").val());
								refreshFrontendPage();
							}
						});
					});

					jQuery("#pub_style_space").on("change", function() {
						jQuery("#pub_style_space_val").html(this.value + "px");
						publicationStyling("wpda-premium-styling-spacing");
					});

					jQuery("#pub_style_corner").on("change", function() {
						jQuery("#pub_style_corner_val").html(this.value + "px");
						publicationStyling("wpda-premium-styling-borders");
					});

					jQuery("#button-color-save").on("click", function() {
						if (systemColors.includes(jQuery("#pub_style_color option:selected").val())) {
							wpda_alert("Warning", "Cannot overwrite color schema '" + jQuery("#pub_style_color option:selected").val() + "'. Please consider the save as option.");
							return;
						}

						addColorSchema(jQuery("#pub_style_color option:selected").val(), get_user_color_schema());
					});

					jQuery("#button-color-save-as").on("click", function() {
						saveColorAs();
					});

					jQuery("#pub_style_modal_width").on("change", function() {
						jQuery("#pub_style_modal_width_val").html(this.value + "%");
						publicationStyling("wpda-premium-styling-modal");
					});

					jQuery(".icon-close").on("click", function() {
						jQuery("#edit-color-schema").hide();
					});

					jQuery("input[type=color]").on("input", function() {
						changeColorInteractively();
					});
				});
			</script>
			<?php
		}

		public static function add_style() {
			if ( ! current_user_can('manage_options') ) {
				WPDA::sent_msg( 'ERR', 'Not authorized' );
				wp_die();
			}

			if ( ! isset( $_POST['w'], $_POST['n'], $_POST['s'] ) ) {
				WPDA::sent_msg( 'ERR', 'Invalid arguments' );
				wp_die();
			}

			if ( ! wp_verify_nonce(
				sanitize_text_field( wp_unslash( $_REQUEST['w'] ) ),
				self::WPDA_DATA_PUBLISHER_MANAGE_STYLES . WPDA::get_current_user_id()
			)
			) {
				WPDA::sent_msg( 'ERR', 'Invalid token' );
				wp_die();
			}

			$name  = sanitize_text_field( wp_unslash( $_REQUEST['n'] ) ); // input var okay.
			$style = sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ); // input var okay.

			if ( self::DEFAULT_COLOR === $name ) {
				WPDA::sent_msg( 'ERR', 'Cannot overwrite system style' );
				wp_die();
			}

			$styles = self::get_styles();
			$styles[ $name ] = $style;
			update_option( self::WPDA_DATA_PUBLISHER_MANAGE_STYLES, $styles );

			WPDA::sent_msg( 'OK', '' );
			wp_die();
		}

		public static function delete_style() {
			if ( ! current_user_can('manage_options') ) {
				WPDA::sent_msg( 'ERR', 'Not authorized' );
				wp_die();
			}

			if ( ! isset( $_POST['w'], $_POST['n'] ) ) {
				WPDA::sent_msg( 'ERR', 'Invalid arguments' );
				wp_die();
			}

			if ( ! wp_verify_nonce(
				sanitize_text_field( wp_unslash( $_REQUEST['w'] ) ),
				self::WPDA_DATA_PUBLISHER_MANAGE_STYLES . WPDA::get_current_user_id()
			)
			) {
				WPDA::sent_msg( 'ERR', 'Invalid token' );
				wp_die();
			}

			$name  = sanitize_text_field( wp_unslash( $_REQUEST['n'] ) ); // input var okay.

			if ( self::DEFAULT_COLOR === $name ) {
				WPDA::sent_msg( 'ERR', 'Cannot delete system style' );
				wp_die();
			}

			$styles = self::get_styles();
			unset( $styles[ $name ] );
			update_option( self::WPDA_DATA_PUBLISHER_MANAGE_STYLES, $styles );

			WPDA::sent_msg( 'OK', '' );
			wp_die();
		}

		public static function add_color_schema() {
			if ( ! current_user_can('manage_options') ) {
				WPDA::sent_msg( 'ERR', 'Not authorized' );
				wp_die();
			}

			if ( ! isset( $_POST['w'], $_POST['n'], $_POST['c'] ) ) {
				WPDA::sent_msg( 'ERR', 'Invalid arguments' );
				wp_die();
			}

			if ( ! wp_verify_nonce(
						sanitize_text_field( wp_unslash( $_REQUEST['w'] ) ),
						self::WPDA_DATA_PUBLISHER_STYLE_COLORS . WPDA::get_current_user_id()
					)
			) {
				WPDA::sent_msg( 'ERR', 'Invalid token' );
				wp_die();
			}

			$schema_name  = sanitize_text_field( wp_unslash( $_REQUEST['n'] ) ); // input var okay.
			$color_schema = sanitize_text_field( wp_unslash( $_REQUEST['c'] ) ); // input var okay.

			if ( in_array( $schema_name, array_keys( self::WPDA_DATA_PUBLISHER_STYLE_COLORS_DEFAULTS ) ) ) {//phpcs:ignore - 8.1 proof
				WPDA::sent_msg( 'ERR', 'Cannot overwrite system color schema' );
				wp_die();
			}

			self::add_color( $schema_name, $color_schema );

			WPDA::sent_msg( 'OK', '' );
			wp_die();
		}

		public static function delete_color_schema() {
			if ( ! current_user_can('manage_options') ) {
				WPDA::sent_msg( 'ERR', 'Not authorized' );
				wp_die();
			}

			if ( ! isset( $_POST['w'], $_POST['n'] ) ) {
				WPDA::sent_msg( 'ERR', 'Invalid arguments' );
				wp_die();
			}

			if ( ! wp_verify_nonce(
				sanitize_text_field( wp_unslash( $_REQUEST['w'] ) ),
				self::WPDA_DATA_PUBLISHER_STYLE_COLORS . WPDA::get_current_user_id()
			)
			) {
				WPDA::sent_msg( 'ERR', 'Invalid token' );
				wp_die();
			}

			$schema_name  = sanitize_text_field( wp_unslash( $_REQUEST['n'] ) ); // input var okay.

			self::delete_colors( $schema_name );

			WPDA::sent_msg( 'OK', '' );
			wp_die();
		}

		public static function get_premium_styling() {
			// TODO Service does not send real JSON
			// WPDA::sent_header( 'application/json' );

			if ( ! current_user_can('manage_options') ) {
				WPDA::sent_msg( 'ERR', 'Not authorized' );
				wp_die();
			}

			if ( ! isset( $_POST['t'], $_POST['i'] ) ) {
				WPDA::sent_msg( 'ERR', 'Invalid arguments' );
				wp_die();
			}

			$table_name = sanitize_text_field( wp_unslash( $_REQUEST['t'] ) ); // input var okay.
			$pub_id     = sanitize_text_field( wp_unslash( $_REQUEST['i'] ) ); // input var okay.

			if ( isset( $_POST['c'] ) ) {
				$color            = sanitize_text_field( wp_unslash( $_REQUEST['c'] ) ); // input var okay.
				$template         = new WPDAPRO_Template_Data_Publisher_Color();
				$styling_template = $template->get_template(
					array(
						'table_name' => $table_name,
						'pub_id'     => $pub_id,
						'color'      => $color,
					)
				);

				$response =
					array(
						'status' => 'OK',
						'msg'    => $styling_template,
						'colors' => isset( self::$colors[$color] ) ? json_encode( self::$colors[$color] ) : null,
					);

				if ( isset( $_POST['init'] ) ) {
					$response['raw'] = WPDAPRO_Template_Data_Publisher_Color::TEMPLATE;
				}

				// Send manually constructed JSON to add color schema
				echo json_encode( $response ); // phpcs:ignore
				wp_die();
			} elseif ( isset( $_POST['s'] ) ) {
				$spacing          = sanitize_text_field( wp_unslash( $_REQUEST['s'] ) ); // input var okay.
				$template         = new WPDAPRO_Template_Data_Publisher_Space();
				$styling_template = $template->get_template(
					array(
						'table_name' => $table_name,
						'pub_id'     => $pub_id,
						'space'      => $spacing,
					)
				);

				WPDA::sent_msg( 'OK', $styling_template );
				wp_die();
			} elseif ( isset( $_POST['r'] ) ) {
				$radius           = sanitize_text_field( wp_unslash( $_REQUEST['r'] ) ); // input var okay.
				$template         = new WPDAPRO_Template_Data_Publisher_Corner();
				$styling_template = $template->get_template(
					array(
						'table_name' => $table_name,
						'pub_id'     => $pub_id,
						'corner'     => $radius,
					)
				);

				WPDA::sent_msg( 'OK', $styling_template );
				wp_die();
			} elseif ( isset( $_POST['m'] ) ) {
				$modal            = sanitize_text_field( wp_unslash( $_REQUEST['m'] ) ); // input var okay.
				$template         = new WPDAPRO_Template_Data_Publisher_Modal();
				$styling_template = $template->get_template(
					array(
						'table_name' => $table_name,
						'pub_id'     => $pub_id,
						'modal'      => $modal,
					)
				);

				WPDA::sent_msg( 'OK', $styling_template );
				wp_die();
			}

			WPDA::sent_msg( 'ERR', 'Invalid arguments' );
			wp_die();
		}

		private static function create_temporary_page( $pub_id ) {
			// Create page to manage premium Data Tables styles on web page.
			$content = '<div id="publication_container">[wpdataaccess pub_id="' . $pub_id . '"]</div><div id="publication_styling"></div>';
			$page    = get_page_by_title( self::WPDA_DATA_PUBLISHER_MANAGE_STYLES_TITLE );
			if ( isset( $page->ID ) ) {
				$status = get_post_status( $page->ID );
				if ( 'trash' !== $status ) {
					remove_action( 'post_updated', 'wp_save_post_revision' );
					wp_update_post(
						array(
							'ID'           => $page->ID,
							'post_content' => $content,
						)
					);
					add_action( 'post_updated', 'wp_save_post_revision' );

					return $page->ID;
				}
			}

			$user_id = WPDA::get_current_user_id();
			$page    = array(
				'post_type'    => 'page',
				'post_title'   => self::WPDA_DATA_PUBLISHER_MANAGE_STYLES_TITLE,
				'post_content' => $content,
				'post_status'  => 'private',
				'post_author'  => $user_id,
				'post_name'    => self::WPDA_DATA_PUBLISHER_MANAGE_STYLES_SLUG
			);
			if ( ! get_page_by_path( self::WPDA_DATA_PUBLISHER_MANAGE_STYLES_SLUG ) ) {
				return wp_insert_post( $page );
			}

			return null;
		}

		public static function frontend_simulation() {
			if ( ! current_user_can('manage_options') ) {
				WPDA::sent_msg( 'ERR', 'Not authorized' );
				wp_die();
			}

			if ( ! isset( $_POST['wpnonce'], $_POST['pub_id'] ) ) {
				WPDA::sent_msg( 'ERR', 'Invalid arguments' );
				wp_die();
			}

			$wpnonce = sanitize_text_field( wp_unslash( $_REQUEST['wpnonce'] ) ); // input var okay.
			$pub_id  = sanitize_text_field( wp_unslash( $_REQUEST['pub_id'] ) ); // input var okay.

			if ( ! wp_verify_nonce( $wpnonce, "wpda-publication-{$pub_id}" ) ) {
				WPDA::sent_msg( 'ERR', 'Invalid token' );
				wp_die();
			}

			$x = self::create_temporary_page( $pub_id );
			if ( null !== $x ) {
				WPDA::sent_msg( 'OK', $x );
				wp_die();
			} else {
				WPDA::sent_msg( 'ERR', 'Internal server error' );
				wp_die();
			}
		}

		public static function get_styles() {
			$styles = get_option( self::WPDA_DATA_PUBLISHER_MANAGE_STYLES );

			if ( false === $styles ) {
				$styles = array();
			}

			return $styles;
		}

		public static function get_colors() {
			self::init();

			return self::$colors;
		}

		public static function get_color_keys() {
			self::init();

			return array_keys( self::$colors );
		}

		public static function get_system_color_keys() {
			return array_keys( self::WPDA_DATA_PUBLISHER_STYLE_COLORS_DEFAULTS );//phpcs:ignore - 8.1 proof
		}

		private static function get_user_styles() {
			$user_styles = get_option( self::WPDA_DATA_PUBLISHER_MANAGE_STYLES );

			if ( false === $user_styles ) {
				$user_styles = array();
			}

			return $user_styles;
		}

		private static function get_user_colors() {
			$user_colors = get_option( self::WPDA_DATA_PUBLISHER_STYLE_COLORS );

			if ( false === $user_colors ) {
				$user_colors = array();
			}

			return $user_colors;
		}

		public static function get_user_color_keys() {
			$wpda_data_publisher_style_colors = self::get_user_colors();

			return array_keys( $wpda_data_publisher_style_colors );//phpcs:ignore - 8.1 proof
		}

		public static function add_color( $schema_name, $color_schema ) {
			$wpda_data_publisher_style_colors = self::get_user_colors();
			$wpda_data_publisher_style_colors[ $schema_name ] = json_decode( $color_schema, true );
			update_option( self::WPDA_DATA_PUBLISHER_STYLE_COLORS, $wpda_data_publisher_style_colors );

			self::init(); // Reset array
		}

		public static function delete_colors( $schema_name ) {
			$wpda_data_publisher_style_colors = self::get_user_colors();
			unset( $wpda_data_publisher_style_colors[ $schema_name ] );
			update_option( self::WPDA_DATA_PUBLISHER_STYLE_COLORS, $wpda_data_publisher_style_colors );

			self::init(); // Reset array
		}

	}

}
