/**
 * @file assets/js/adminjs/admin-appearance.js
 * Color picker init, live preview updates, and Reset All Colors for the Appearance tab; loads on the Appearance tab only.
 * @package MyBookShowroom
 * @since   1.0.0
 */

( function ( $, MBS_Appearance ) {
	'use strict';

	// wp-color-picker is enqueued by MBS_Settings::enqueue_assets() for this
	// tab. If it is somehow missing (dependency-load race, future refactor
	// accident), degrade silently rather than throwing.
	if ( typeof $.fn.wpColorPicker === 'undefined' ) {
		return;
	}

	var freeDefaults = ( MBS_Appearance && MBS_Appearance.defaults && MBS_Appearance.defaults.free ) || {};
	var strings      = ( MBS_Appearance && MBS_Appearance.strings ) || {};
	var __           = wp.i18n.__;

	// ── F-007: Dark palette — mirrors [data-mbs-theme="dark"] in mbs-front.css ──
	// Applied as inline CSS vars on #mbs-live-preview when the Dark Mode checkbox
	// is checked. Inline vars have higher specificity than CSS rules, so setting
	// them here is the only reliable way to override the light token values that
	// updateLivePreview() also sets inline.
	var darkTokens = {
		'--mbs-accent':        '#5BC0CC',
		'--mbs-button-bg':     '#4A6FA5',
		'--mbs-button-text':   '#FFFFFF',
		'--mbs-link':          '#5BC0CC',
		'--mbs-card-bg':       '#1E1E2E',
		'--mbs-border':        '#3A3A4E',
		'--mbs-text':          '#E0E8F0',
		'--mbs-text-light':    '#9AABBA',
		// PRO structural palette — dark equivalents
		'--mbs-navy':          '#4A6FA5',
		'--mbs-navy-dark':     '#2A4A72',
		'--mbs-lavender':      '#8A7094',
		'--mbs-teal-pale':     '#2A5A62',
		'--mbs-lavender-pale': '#3A2A4E',
		'--mbs-beige':         '#2A2820',
		'--mbs-slate':         '#6A7A8A',
		'--mbs-mist':          '#3A4A52',
		// Badge & pills tokens
		'--mbs-pro-bg':            '#2A1A3A',
		'--mbs-pro-text':          '#C8A0E0',
		'--mbs-coming-soon-bg':    '#92400E',
		'--mbs-coming-soon-text':  '#FEF3C7',
		// Accessories
		'--mbs-watermark-text': '#5A6472',
		'--mbs-star':           '#D4903A'
	};

	// ── FREE color field registry ──────────────────────────────────────────
	// Input id ↔ CSS variable ↔ defaults key mapping. Keyed by the option
	// suffix used by the PHP render (e.g. `accent` → `#mbs_appearance_accent`
	// → `--mbs-accent` → `freeDefaults.accent`).
	var freeFields = [
		{ key: 'accent',      cssVar: '--mbs-accent' },
		{ key: 'button_bg',   cssVar: '--mbs-button-bg' },
		{ key: 'button_text', cssVar: '--mbs-button-text' },
		{ key: 'link',        cssVar: '--mbs-link' }
	];

	// ── PRO color field registry ───────────────────────────────────────────
	// PRO tokens only render when mbs_is_pro(), so the input may be absent.
	// updateLivePreview() tolerates missing inputs; the preview falls back
	// to each field's data-default-color attribute when present.
	var proFields = [
		{ key: 'navy',           cssVar: '--mbs-navy' },
		{ key: 'navy_dark',      cssVar: '--mbs-navy-dark' },
		{ key: 'lavender',       cssVar: '--mbs-lavender' },
		{ key: 'teal_pale',      cssVar: '--mbs-teal-pale' },
		{ key: 'lavender_pale',  cssVar: '--mbs-lavender-pale' },
		{ key: 'beige',          cssVar: '--mbs-beige' },
		{ key: 'slate',          cssVar: '--mbs-slate' },
		{ key: 'mist',           cssVar: '--mbs-mist' },
		{ key: 'pro_bg',          cssVar: '--mbs-pro-bg' },
		{ key: 'pro_text',        cssVar: '--mbs-pro-text' },
		{ key: 'coming_soon_bg',  cssVar: '--mbs-coming-soon-bg' },
		{ key: 'coming_soon_text', cssVar: '--mbs-coming-soon-text' },
		{ key: 'card_bg',        cssVar: '--mbs-card-bg' },
		{ key: 'border',         cssVar: '--mbs-border' },
		{ key: 'watermark_text', cssVar: '--mbs-watermark-text' },
		{ key: 'star',           cssVar: '--mbs-star' }
	];

	function inputSelector( key ) {
		return '#mbs_appearance_' + key;
	}

	function readFieldValue( field, fallback ) {
		var $el = $( inputSelector( field.key ) );
		if ( ! $el.length ) {
			return fallback || '';
		}
		return $el.val() || $el.data( 'default-color' ) || fallback || '';
	}

	function updateLivePreview() {
		var $preview = $( '#mbs-live-preview' );
		if ( ! $preview.length ) {
			return;
		}

		// F-007: When dark mode is active on the preview, apply the canonical dark
		// token set. Inline CSS vars have higher specificity than any selector rule,
		// so we must set them here rather than relying on the [data-mbs-theme] CSS.
		if ( $preview.attr( 'data-mbs-theme' ) === 'dark' ) {
			$preview.css( darkTokens );
			return;
		}

		var props = {};

		freeFields.forEach( function ( field ) {
			props[ field.cssVar ] = readFieldValue( field, freeDefaults[ field.key ] );
		} );

		proFields.forEach( function ( field ) {
			var value = readFieldValue( field, '' );
			if ( value ) {
				props[ field.cssVar ] = value;
			}
			// If the PRO input is absent (FREE tier), no CSS var is set — the
			// preview card's inline style uses the stylesheet fallback from
			// mbs-admin-settings.css `var(--mbs-...,  #hex)` declarations.
		} );

		$preview.css( props );

		// Phase 3.3: Update new preview elements with live token values.
		// These elements are only present when the PHP renders them (PRO tier).
		var lavenderVal     = readFieldValue( { key: 'lavender' },      '' );
		var lavenderPaleVal = readFieldValue( { key: 'lavender_pale' }, '' );
		var beigeVal        = readFieldValue( { key: 'beige' },         '' );
		var csoBgVal        = readFieldValue( { key: 'coming_soon_bg' }, '#F59E0B' );
		var csoTextVal      = readFieldValue( { key: 'coming_soon_text' }, '#FFFFFF' );
		var slateVal        = readFieldValue( { key: 'slate' },         '' );
		var tealPaleVal     = readFieldValue( { key: 'teal_pale' },     '' );

		if ( lavenderVal )     { $preview.find( '.mbs-preview-theme-pill' ).css( 'border-color', lavenderVal ); }
		if ( lavenderPaleVal ) { $preview.find( '.mbs-preview-theme-pill' ).css( 'background', lavenderPaleVal ); }
		if ( beigeVal )        { $preview.find( '.mbs-preview-signup-widget' ).css( 'background', beigeVal ); }
		if ( csoBgVal )        { $preview.find( '.mbs-preview-coming-soon' ).css( 'background', csoBgVal ); }
		if ( csoTextVal )      { $preview.find( '.mbs-preview-coming-soon' ).css( 'color', csoTextVal ); }
		if ( slateVal )        { $preview.find( '.mbs-preview-author-filter-btn' ).css( 'color', slateVal ); }
		if ( tealPaleVal )     {
			$preview.find( '.mbs-preview-author-filter-btn' ).on( 'mouseenter', function () {
				$( this ).css( 'background', tealPaleVal );
			} ).on( 'mouseleave', function () {
				$( this ).css( 'background', '' );
			} );
		}
	}

	// F-007: Sync the live preview dark mode state with the "Enable Dark Mode"
	// checkbox. Sets data-mbs-theme="dark" on #mbs-live-preview when checked
	// (removed when unchecked), then calls updateLivePreview() to refresh tokens.
	// The initial state is applied on page load so the preview matches the saved
	// setting without the admin having to interact with the checkbox first.
	function bindDarkModeToggle() {
		var $cb      = $( '#mbs_appearance_dark_mode' );
		var $preview = $( '#mbs-live-preview' );

		if ( ! $cb.length || ! $preview.length ) {
			return;
		}

		// Apply initial state from the saved checkbox value.
		if ( $cb.is( ':checked' ) ) {
			$preview.attr( 'data-mbs-theme', 'dark' );
		}

		$cb.on( 'change', function () {
			if ( $( this ).is( ':checked' ) ) {
				$preview.attr( 'data-mbs-theme', 'dark' );
			} else {
				$preview.removeAttr( 'data-mbs-theme' );
			}
			updateLivePreview();
		} );
	}

	function resetAllColors() {
		if ( ! window.confirm( strings.confirmReset || __( 'Reset all colors to defaults?', 'my-book-showroom' ) ) ) {
			return;
		}

		// FREE defaults from the localized data (single source of truth
		// shared with the PHP render via MBS_Tab_Appearance::FREE_DEFAULTS).
		freeFields.forEach( function ( field ) {
			var $el = $( inputSelector( field.key ) );
			if ( ! $el.length ) {
				return;
			}
			var def = freeDefaults[ field.key ] || $el.data( 'default-color' ) || '';
			if ( def ) {
				$el.wpColorPicker( 'color', def );
			}
		} );

		// PRO defaults from each input's data-default-color attribute.
		$( '.mbs-pro-color-picker' ).each( function () {
			var def = $( this ).data( 'default-color' );
			if ( def ) {
				$( this ).wpColorPicker( 'color', def );
			}
		} );

		updateLivePreview();
	}

	// ── Book Picker ─────────────────────────────────────────────────────────
	// Populates #mbs-preview-book-select from localized MBS_Appearance.books,
	// then swaps cover / title / author in the live preview card on change.
	// Selection is persisted to localStorage so it survives page refreshes.

	var PICKER_KEY    = 'mbs_appearance_preview_book';
	var pickerBooks   = ( MBS_Appearance && MBS_Appearance.books )        || [];
	var fallbackCover = ( MBS_Appearance && MBS_Appearance.fallbackCover ) || '';

	// Captured from the DOM on first load — used to restore placeholder state.
	var previewDefaults = {};

	function capturePreviewDefaults() {
		var $preview = $( '#mbs-live-preview' );
		if ( ! $preview.length ) { return; }
		previewDefaults.title  = $preview.find( '.mbs-preview-title' ).text();
		previewDefaults.author = $preview.find( '.mbs-preview-author' ).text();
		previewDefaults.cover  = $preview.find( '.mbs-preview-cover' ).attr( 'src' ) || fallbackCover;
	}

	function applyPickerSelection( bookId ) {
		var $preview = $( '#mbs-live-preview' );
		if ( ! $preview.length ) { return; }
		var $img    = $preview.find( '.mbs-preview-cover' );
		var $title  = $preview.find( '.mbs-preview-title' );
		var $author = $preview.find( '.mbs-preview-author' );

		if ( ! bookId ) {
			// Restore placeholder defaults.
			$img.attr( 'src', previewDefaults.cover  || fallbackCover );
			$title.text(  previewDefaults.title  || '' );
			$author.text( previewDefaults.author || '' );
			return;
		}

		var book = null;
		pickerBooks.forEach( function ( b ) {
			if ( String( b.id ) === String( bookId ) ) { book = b; }
		} );
		if ( ! book ) { return; }

		$img.attr( 'src', book.cover || fallbackCover );
		$title.text(  book.title );
		$author.text( book.author ? 'by ' + book.author : '' );
	}

	function populateBookPicker() {
		var $select = $( '#mbs-preview-book-select' );
		if ( ! $select.length ) { return; }

		if ( ! pickerBooks.length ) {
			// No books yet — hide the picker so it does not distract.
			$select.closest( '.mbs-preview-book-picker' ).hide();
			return;
		}

		pickerBooks.forEach( function ( book ) {
			$select.append(
				$( '<option>', { value: book.id, text: book.title } )
			);
		} );

		// Restore last saved selection.
		var saved = '';
		try { saved = localStorage.getItem( PICKER_KEY ) || ''; } catch ( e ) {}
		if ( saved ) {
			$select.val( saved );
		}

		// Apply the selection (or placeholder if nothing saved).
		applyPickerSelection( $select.val() );

		$select.on( 'change', function () {
			var val = $( this ).val();
			try { localStorage.setItem( PICKER_KEY, val ); } catch ( e ) {}
			applyPickerSelection( val );
		} );
	}

	$( document ).ready( function () {
		// Initialize color pickers with a change/clear callback that refreshes
		// the live preview. wpColorPicker's `change` fires synchronously with
		// the input value updated, so a direct read works here.
		$( '.mbs-color-picker' ).wpColorPicker( {
			change: function () { updateLivePreview(); },
			clear:  function () { updateLivePreview(); }
		} );

		$( '#mbs-reset-colors' ).on( 'click', resetAllColors );

		// F-007: Wire dark mode toggle — must run before updateLivePreview() so
		// the data-mbs-theme attribute is set before the first preview render.
		bindDarkModeToggle();

		// Book Picker: capture placeholder defaults from the DOM, then populate
		// the selector and apply any saved selection. Must run before the first
		// updateLivePreview() so the cover src and text are already correct when
		// the live preview renders.
		capturePreviewDefaults();
		populateBookPicker();

		// Render the initial preview on page load using the saved option
		// values (or dark tokens if dark mode is already enabled).
		updateLivePreview();
	} );

} )( jQuery, window.MBS_Appearance || {} );
