<?php
/**
 * Admin: tabbed SkyNet Smart Favorites hub.
 *
 * @package SKYNSMFA_Smart_Favorites
 */

declare( strict_types=1 );

namespace SKYNSMFA\Wishlist;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}


final class Admin {
	/**
	 * Singleton instance.
	 *
	 * @var Admin|null
	 */
	private static $instance = null;

	/**
	 * Option group for Settings API.
	 *
	 * @var string
	 */
	private $option_group = 'skynsmfa_wishlist_group';

	/**
	 * Known settings keys and defaults (merge on save).
	 *
	 * @return array<string, string|int>
	 */
	private function get_settings_defaults(): array {
		return array(
			'skynsmfa_enable'               => 'yes',
			'skynsmfa_multiple_enable'      => 'yes',
			'skynsmfa_add_target_mode'      => 'last_used',
			'skynsmfa_loop_icon'            => 'yes',
			'skynsmfa_single_icon'          => 'yes',
			'skynsmfa_loop_position'        => 'after_add_to_cart',
			'skynsmfa_single_position'      => 'after_add_to_cart',
			'skynsmfa_display_mode'         => 'button',
			'skynsmfa_custom_shortcode'     => 'yes',
			'skynsmfa_menu_icon'            => 'yes',
			'skynsmfa_notification_type'    => 'toast',
			'skynsmfa_page_layout'          => 'table',
			'skynsmfa_rate_limit_per_min'   => 120,
			'wishlist_page_id'              => 0,
			'skynsmfa_icon_style'           => 'heart',
			'skynsmfa_icon_custom_id'       => 0,
			'skynsmfa_icon_text_position'   => 'before',
			'skynsmfa_icon_fill'            => 'outline',
			'skynsmfa_icon_color'           => '',
			'skynsmfa_icon_active_color'    => '',
			'skynsmfa_icon_hover_color'     => '',
			'skynsmfa_icon_size'            => 24,
			'skynsmfa_icon_shape'           => 'none',
			'skynsmfa_btn_bg_color'         => '',
			'skynsmfa_btn_text_color'       => '',
			'skynsmfa_btn_border_color'     => '',
			'skynsmfa_btn_active_bg_color'  => '',
			'skynsmfa_btn_active_text_color' => '',
			'skynsmfa_btn_radius'           => '',
			'skynsmfa_label_add'            => '',
			'skynsmfa_label_added'          => '',
			'skynsmfa_label_remove'         => '',
			'skynsmfa_custom_css'           => '',
		);
	}

	/**
	 * Get singleton instance.
	 *
	 * @return Admin
	 */
	public static function instance(): Admin {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	/**
	 * Constructor.
	 */
	private function __construct() {
		add_action( 'admin_menu', array( $this, 'register_menu' ) );
		add_action( 'admin_init', array( $this, 'register_settings' ) );
		add_action( 'admin_init', array( $this, 'handle_recreate_page' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_assets' ) );
	}

	private function page_slug(): string {
		return SKYNSMFA_ADMIN_PAGE_SLUG;
	}

	/**
	 * Register the admin menu.
	 *
	 * @return void
	 */
	public function register_menu(): void {
		add_menu_page(
			__( 'SkyNet Smart Favorites', 'skynet-smart-favorites' ),
			__( 'SkyNet Smart Favorites', 'skynet-smart-favorites' ),
			'manage_woocommerce',
			$this->page_slug(),
			array( $this, 'render_settings_page' ),
			'data:image/svg+xml;base64,' . base64_encode( '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M11.645 20.91l-.007-.003-.022-.012a15.247 15.247 0 01-.383-.218 25.18 25.18 0 01-4.244-3.17C4.688 15.36 2.25 12.174 2.25 8.25 2.25 5.322 4.714 3 7.688 3A5.5 5.5 0 0112 5.052 5.5 5.5 0 0116.313 3c2.973 0 5.437 2.322 5.437 5.25 0 3.925-2.438 7.111-4.739 9.256a25.175 25.175 0 01-4.244 3.17 15.247 15.247 0 01-.383.219l-.022.012-.007.004-.003.001a.752.752 0 01-.704 0l-.003-.001z"/></svg>' ),
			56
		);
	}

	/**
	 * Register the settings.
	 *
	 * @return void
	 */
	public function register_settings(): void {
		register_setting(
			$this->option_group,
			'skynsmfa_settings',
			array(
				'type'              => 'array',
				'sanitize_callback' => array( $this, 'sanitize_settings' ),
			)
		);
	}

	/**
	 * Merge and sanitize settings (partial updates supported).
	 *
	 * @param mixed $input Input settings.
	 * @return array
	 */
	public function sanitize_settings( $input ): array { // phpcs:ignore Squiz.Commenting.FunctionComment.Missing -- public for Pro add-on import.
		$defaults = $this->get_settings_defaults();
		$existing = get_option( 'skynsmfa_settings', array() );
		if ( ! is_array( $existing ) ) {
			$existing = array();
		}

		$out = array_merge( $defaults, $existing );

		if ( 'below_gallery' === (string) ( $out['skynsmfa_single_position'] ?? '' ) ) {
			$out['skynsmfa_single_position'] = 'after_add_to_cart';
		}

		if ( ! is_array( $input ) ) {
			return $out;
		}

		$checkbox_keys = $this->get_settings_checkbox_keys();
		foreach ( $checkbox_keys as $checkbox_key ) {
			if ( array_key_exists( $checkbox_key, $input ) ) {
				$out[ $checkbox_key ] = 'yes' === (string) $input[ $checkbox_key ] ? 'yes' : 'no';
			}
		}

		// Main Settings tab save: unchecked boxes are omitted from POST unless hidden "no" fields exist.
		if ( $this->is_main_settings_tab_submission( $input ) ) {
			foreach ( $this->get_main_settings_tab_checkbox_keys() as $checkbox_key ) {
				if ( ! array_key_exists( $checkbox_key, $input ) ) {
					$out[ $checkbox_key ] = 'no';
				}
			}
		}
		if ( array_key_exists( 'skynsmfa_add_target_mode', $input ) ) {
			$mode = (string) $input['skynsmfa_add_target_mode'];
			$out['skynsmfa_add_target_mode'] = in_array( $mode, array( 'default', 'last_used', 'ask' ), true ) ? $mode : 'last_used';
		}
		if ( array_key_exists( 'skynsmfa_loop_position', $input ) ) {
			$out['skynsmfa_loop_position'] = sanitize_text_field( (string) $input['skynsmfa_loop_position'] );
		}
		if ( array_key_exists( 'skynsmfa_single_position', $input ) ) {
			$sp = (string) $input['skynsmfa_single_position'];
			if ( 'below_gallery' === $sp ) {
				$sp = 'after_add_to_cart';
			}
			$allowed_single = array( 'before_add_to_cart', 'after_add_to_cart', 'over_image' );
			$out['skynsmfa_single_position'] = in_array( $sp, $allowed_single, true ) ? $sp : 'after_add_to_cart';
		}
		if ( array_key_exists( 'skynsmfa_display_mode', $input ) ) {
			$mode = (string) $input['skynsmfa_display_mode'];
			$out['skynsmfa_display_mode'] = in_array( $mode, array( 'button', 'icon', 'icon_text' ), true ) ? $mode : 'button';
		}
		if ( array_key_exists( 'skynsmfa_notification_type', $input ) ) {
			$nt = (string) $input['skynsmfa_notification_type'];
			$out['skynsmfa_notification_type'] = in_array( $nt, array( 'none', 'toast', 'tooltip' ), true ) ? $nt : 'toast';
		}
		if ( array_key_exists( 'skynsmfa_page_layout', $input ) ) {
			$pl = (string) $input['skynsmfa_page_layout'];
			if ( in_array( $pl, array( 'table', 'grid', 'compact' ), true ) ) {
				$out['skynsmfa_page_layout'] = Feature_Gate::resolve_page_layout( $pl );
			} else {
				$out['skynsmfa_page_layout'] = 'table';
			}
		}
		if ( array_key_exists( 'skynsmfa_rate_limit_per_min', $input ) ) {
			$out['skynsmfa_rate_limit_per_min'] = max( 10, min( 600, absint( $input['skynsmfa_rate_limit_per_min'] ) ) );
		}
		if ( array_key_exists( 'wishlist_page_id', $input ) ) {
			$out['wishlist_page_id'] = absint( $input['wishlist_page_id'] );
		}

		if ( array_key_exists( 'skynsmfa_icon_style', $input ) ) {
			$style = (string) $input['skynsmfa_icon_style'];
			$out['skynsmfa_icon_style'] = in_array( $style, Frontend::get_icon_style_keys(), true ) ? $style : 'heart';
		}
		if ( array_key_exists( 'skynsmfa_icon_custom_id', $input ) ) {
			$icon_id = absint( $input['skynsmfa_icon_custom_id'] );
			$out['skynsmfa_icon_custom_id'] = ( $icon_id > 0 && wp_attachment_is_image( $icon_id ) ) ? $icon_id : 0;
		}
		if ( array_key_exists( 'skynsmfa_icon_text_position', $input ) ) {
			$pos = (string) $input['skynsmfa_icon_text_position'];
			$out['skynsmfa_icon_text_position'] = in_array( $pos, array( 'before', 'after' ), true ) ? $pos : 'before';
		}
		if ( array_key_exists( 'skynsmfa_icon_shape', $input ) ) {
			$shape = (string) $input['skynsmfa_icon_shape'];
			$out['skynsmfa_icon_shape'] = in_array( $shape, array( 'none', 'rounded', 'circle' ), true ) ? $shape : 'none';
		}
		if ( array_key_exists( 'skynsmfa_icon_fill', $input ) ) {
			$fill = (string) $input['skynsmfa_icon_fill'];
			$out['skynsmfa_icon_fill'] = in_array( $fill, array( 'outline', 'filled' ), true ) ? $fill : 'outline';
		}
		if ( array_key_exists( 'skynsmfa_icon_size', $input ) ) {
			$out['skynsmfa_icon_size'] = max( 16, min( 64, absint( $input['skynsmfa_icon_size'] ) ) );
		}
		if ( array_key_exists( 'skynsmfa_btn_radius', $input ) ) {
			$radius = trim( (string) $input['skynsmfa_btn_radius'] );
			$out['skynsmfa_btn_radius'] = ( '' === $radius ) ? '' : (string) max( 0, min( 40, absint( $radius ) ) );
		}

		foreach ( $this->get_settings_color_keys() as $color_key ) {
			if ( array_key_exists( $color_key, $input ) ) {
				$color = sanitize_hex_color( (string) $input[ $color_key ] );
				$out[ $color_key ] = is_string( $color ) ? $color : '';
			}
		}

		foreach ( array( 'skynsmfa_label_add', 'skynsmfa_label_added', 'skynsmfa_label_remove' ) as $label_key ) {
			if ( array_key_exists( $label_key, $input ) ) {
				$out[ $label_key ] = sanitize_text_field( (string) $input[ $label_key ] );
			}
		}

		if ( array_key_exists( 'skynsmfa_custom_css', $input ) ) {
			$custom_css = Css_Sanitizer::prepare_for_save( (string) wp_unslash( $input['skynsmfa_custom_css'] ) );
			if ( $custom_css['success'] ) {
				$out['skynsmfa_custom_css'] = $custom_css['css'];
			} else {
				add_settings_error(
					'skynsmfa_settings',
					'skynsmfa_custom_css',
					$custom_css['message'],
					'error'
				);
			}
		}

		/**
		 * Filter sanitized settings (Pro add-on extends email keys, etc.).
		 *
		 * @param array<string, mixed> $out   Sanitized settings.
		 * @param array<string, mixed> $input Raw input.
		 */
		return apply_filters( 'skynsmfa_sanitize_settings', $out, $input );
	}

	/**
	 * Yes/no option keys stored in skynsmfa_settings.
	 *
	 * @return list<string>
	 */
	private function get_settings_checkbox_keys(): array {
		return array(
			'skynsmfa_enable',
			'skynsmfa_multiple_enable',
			'skynsmfa_loop_icon',
			'skynsmfa_single_icon',
			'skynsmfa_custom_shortcode',
			'skynsmfa_menu_icon',
		);
	}

	/**
	 * Hex color option keys stored in skynsmfa_settings (button appearance).
	 *
	 * @return list<string>
	 */
	private function get_settings_color_keys(): array {
		return array(
			'skynsmfa_icon_color',
			'skynsmfa_icon_active_color',
			'skynsmfa_icon_hover_color',
			'skynsmfa_btn_bg_color',
			'skynsmfa_btn_text_color',
			'skynsmfa_btn_border_color',
			'skynsmfa_btn_active_bg_color',
			'skynsmfa_btn_active_text_color',
		);
	}

	/**
	 * Checkbox keys on the Settings tab (options.php form).
	 *
	 * @return list<string>
	 */
	private function get_main_settings_tab_checkbox_keys(): array {
		return array(
			'skynsmfa_enable',
			'skynsmfa_multiple_enable',
			'skynsmfa_loop_icon',
			'skynsmfa_single_icon',
			'skynsmfa_custom_shortcode',
			'skynsmfa_menu_icon',
		);
	}

	/**
	 * Detect a full Settings tab save (not email partial or JSON import patch).
	 *
	 * @param array<string, mixed> $input Sanitizer input.
	 * @return bool
	 */
	private function is_main_settings_tab_submission( array $input ): bool {
		return array_key_exists( 'skynsmfa_add_target_mode', $input )
			|| array_key_exists( 'skynsmfa_rate_limit_per_min', $input )
			|| array_key_exists( 'skynsmfa_page_layout', $input )
			|| array_key_exists( 'skynsmfa_loop_position', $input )
			|| array_key_exists( 'skynsmfa_single_position', $input )
			|| array_key_exists( 'skynsmfa_notification_type', $input );
	}

	/**
	 * Markup for a shortcode shown in admin (one-click select via CSS user-select: all).
	 *
	 * @param string $shortcode Shortcode including brackets.
	 * @return string
	 */
	private function shortcode_select_markup( string $shortcode ): string {
		return '<code class="skynsmfa-shortcode-select">' . esc_html( $shortcode ) . '</code>';
	}

	/**
	 * Render a yes/no settings checkbox with a hidden "no" fallback for unchecked state.
	 *
	 * @param string               $id     Input id.
	 * @param string               $key    skynsmfa_settings array key.
	 * @param string               $label  Visible label.
	 * @param array<string, mixed> $fields Current settings.
	 * @return void
	 */
	private function render_settings_checkbox( string $id, string $key, string $label, array $fields ): void {
		$value = (string) ( $fields[ $key ] ?? 'no' );
		?>
		<div class="skynsmfa-field-row skynsmfa-field-row--switch">
			<label for="<?php echo esc_attr( $id ); ?>" class="skynsmfa-toggle">
				<input type="checkbox" id="<?php echo esc_attr( $id ); ?>" name="skynsmfa_settings[<?php echo esc_attr( $key ); ?>]" value="yes" <?php checked( $value, 'yes' ); ?>>
				<span class="skynsmfa-slider" aria-hidden="true"></span>
				<span class="skynsmfa-label-text"><?php echo esc_html( $label ); ?></span>
			</label>
		</div>
		<?php
	}

	/**
	 * Enqueue admin styles.
	 *
	 * @param string $hook The current admin page.
	 * @return void
	 */
	public function enqueue_assets( string $hook ): void {
		if ( 'toplevel_page_' . $this->page_slug() !== $hook ) {
			return;
		}

		wp_enqueue_style(
			'skynsmfa-admin-style',
			SKYNSMFA_URL . 'assets/css/admin-settings.css',
			array( 'wp-color-picker' ),
			SKYNSMFA_VERSION
		);

		// Media library (custom icon upload) is only used on the Button Customizer tab.
		$active_tab = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : 'settings'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only tab switch, no state change.
		if ( 'appearance' === $active_tab ) {
			wp_enqueue_media();
		}

		wp_enqueue_script(
			'skynsmfa-admin-settings',
			SKYNSMFA_URL . 'assets/js/admin-settings.js',
			array( 'jquery', 'wp-color-picker' ),
			SKYNSMFA_VERSION,
			true
		);

		wp_localize_script(
			'skynsmfa-admin-settings',
			'skynsmfaAdmin',
			array(
				'iconPaths' => self::get_icon_svg_paths(),
				'i18n'      => array(
					'selectIcon'  => __( 'Select custom icon', 'skynet-smart-favorites' ),
					'useIcon'     => __( 'Use this icon', 'skynet-smart-favorites' ),
					'labelAdd'    => __( 'Add to wishlist', 'skynet-smart-favorites' ),
					'labelAdded'  => __( 'Already in wishlist', 'skynet-smart-favorites' ),
				),
			)
		);
	}

	/**
	 * SVG `path` "d" values for each selectable icon style (admin live preview).
	 *
	 * @return array<string, string>
	 */
	public static function get_icon_svg_paths(): array {
		return array(
			'heart'    => 'M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 5.42 4.42 3 7.5 3 9.24 3 10.91 3.81 12 5.09 13.09 3.81 14.76 3 16.5 3 19.58 3 22 5.42 22 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z',
			'star'     => 'M12 17.27l5.18 3.13c.39.24.89-.11.78-.55l-1.37-5.89 4.58-3.97c.34-.3.16-.86-.29-.9l-6.03-.51-2.36-5.57c-.18-.42-.78-.42-.96 0L9.16 8.68l-6.03.51c-.45.04-.63.6-.29.9l4.58 3.97-1.37 5.89c-.11.44.39.79.78.55L12 17.27z',
			'bookmark' => 'M17 3H7c-1.1 0-2 .9-2 2v16l7-3 7 3V5c0-1.1-.9-2-2-2z',
			'bag'      => 'M18 6h-2c0-2.21-1.79-4-4-4S8 3.79 8 6H6c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm-6-2c1.1 0 2 .9 2 2h-4c0-1.1.9-2 2-2zm0 10c-2.21 0-4-1.79-4-4h2c0 1.1.9 2 2 2s2-.9 2-2h2c0 2.21-1.79 4-4 4z',
			'tag'      => 'M21.41 11.58l-9-9C12.05 2.22 11.55 2 11 2H4c-1.1 0-2 .9-2 2v7c0 .55.22 1.05.59 1.42l9 9c.36.36.86.58 1.41.58s1.05-.22 1.41-.59l7-7c.37-.36.59-.86.59-1.41s-.23-1.06-.59-1.42zM5.5 7C4.67 7 4 6.33 4 5.5S4.67 4 5.5 4 7 4.67 7 5.5 6.33 7 5.5 7z',
			'gift'     => 'M20 6h-2.18c.11-.31.18-.65.18-1 0-1.66-1.34-3-3-3-1.05 0-1.96.54-2.5 1.35l-.5.67-.5-.68C10.96 2.54 10.05 2 9 2 7.34 2 6 3.34 6 5c0 .35.07.69.18 1H4c-1.11 0-1.99.89-1.99 2L2 19c0 1.11.89 2 2 2h16c1.11 0 2-.89 2-2V8c0-1.11-.89-2-2-2zm-5-2c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zM9 4c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm11 15H4v-2h16v2zm0-5H4V8h5.08L7 10.83 8.62 12 11 8.76l1-1.36 1 1.36L15.38 12 17 10.83 14.92 8H20v6z',
			'thumb'    => 'M1 21h4V9H1v12zm22-11c0-1.1-.9-2-2-2h-6.31l.95-4.57.03-.32c0-.41-.17-.79-.44-1.06L14.17 1 7.59 7.59C7.22 7.95 7 8.45 7 9v10c0 1.1.9 2 2 2h9c.83 0 1.54-.5 1.84-1.22l3.02-7.05c.09-.23.14-.47.14-.73v-2z',
			'plus'     => 'M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z',
		);
	}

	/**
	 * Handle manual recreation of the wishlist page.
	 *
	 * @return void
	 */
	public function handle_recreate_page(): void {
		if ( ! isset( $_POST['skynsmfa_recreate_page'] ) || ! current_user_can( 'manage_woocommerce' ) ) {
			return;
		}

		check_admin_referer( 'skynsmfa_recreate_action' );

		Plugin::create_pages();

		wp_safe_redirect(
			add_query_arg(
				array(
					'page'      => $this->page_slug(),
					'tab'       => 'tools',
					'recreated' => 'true',
				),
				admin_url( 'admin.php' )
			)
		);
		exit;
	}

	/**
	 * Allowed admin tabs.
	 *
	 * @return array<string, string> slug => label
	 */
	private function get_tabs(): array {
		$tabs = array(
			'settings'   => __( 'Settings', 'skynet-smart-favorites' ),
			'appearance' => __( 'Button Customizer', 'skynet-smart-favorites' ),
			'tools'      => __( 'Tools', 'skynet-smart-favorites' ),
		);

		/**
		 * Admin hub tabs (Pro add-on registers dashboard, popular, emails, etc.).
		 *
		 * @param array<string, string> $tabs Tab slug => label.
		 */
		return apply_filters( 'skynsmfa_admin_tabs', $tabs );
	}

	/**
	 * Current tab slug.
	 *
	 * @return string
	 */
	private function get_current_tab(): string {
		$tabs    = $this->get_tabs();
		$default = (string) apply_filters( 'skynsmfa_default_admin_tab', 'settings' );
		if ( ! isset( $tabs[ $default ] ) ) {
			$default = 'settings';
		}
		$tab = $default;

		if ( $this->is_plugin_admin_screen() ) {
			$tab_input = filter_input( INPUT_GET, 'tab', FILTER_DEFAULT );
			$tab       = is_string( $tab_input ) ? sanitize_key( $tab_input ) : $default;
		}

		return isset( $tabs[ $tab ] ) ? $tab : $default;
	}

	/**
	 * Whether the current request is this plugin's admin hub (authorized).
	 *
	 * @return bool
	 */
	private function is_plugin_admin_screen(): bool {
		if ( ! is_admin() || ! current_user_can( 'manage_woocommerce' ) ) {
			return false;
		}

		$page_input = filter_input( INPUT_GET, 'page', FILTER_DEFAULT );
		$page       = is_string( $page_input ) ? sanitize_text_field( $page_input ) : '';

		return $this->page_slug() === $page;
	}

	/**
	 * Build tab URL.
	 *
	 * @param string $tab Tab slug.
	 * @return string
	 */
	private function tab_url( string $tab ): string {
		return add_query_arg(
			array(
				'page' => $this->page_slug(),
				'tab'  => $tab,
			),
			admin_url( 'admin.php' )
		);
	}

	/**
	 * Render the admin page shell and active tab.
	 *
	 * @return void
	 */
	public function render_settings_page(): void {
		if ( ! current_user_can( 'manage_woocommerce' ) ) {
			return;
		}

		$settings = get_option( 'skynsmfa_settings', array() );
		if ( ! is_array( $settings ) ) {
			$settings = array();
		}

		$fields = array_merge( $this->get_settings_defaults(), $settings );

		if ( 'below_gallery' === (string) ( $fields['skynsmfa_single_position'] ?? '' ) ) {
			$fields['skynsmfa_single_position'] = 'after_add_to_cart';
		}

		$recreated        = sanitize_text_field( (string) filter_input( INPUT_GET, 'recreated', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
		$settings_updated = sanitize_text_field( (string) filter_input( INPUT_GET, 'settings-updated', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );
		$msg              = sanitize_text_field( (string) filter_input( INPUT_GET, 'skynsmfa_msg', FILTER_SANITIZE_FULL_SPECIAL_CHARS ) );

		$notice_html = '';
		if ( 'true' === $recreated ) {
			$notice_html .= '<div class="notice notice-success is-dismissible"><p>' . esc_html__( 'Wishlist page checked and created successfully.', 'skynet-smart-favorites' ) . '</p></div>';
		}
		if ( 'true' === $settings_updated ) {
			$notice_html .= '<div class="notice notice-success is-dismissible"><p>' . esc_html__( 'Settings saved successfully.', 'skynet-smart-favorites' ) . '</p></div>';
		}
		if ( 'import_ok' === $msg ) {
			$notice_html .= '<div class="notice notice-success is-dismissible"><p>' . esc_html__( 'Settings imported successfully.', 'skynet-smart-favorites' ) . '</p></div>';
		}
		if ( 'import_invalid' === $msg ) {
			$notice_html .= '<div class="notice notice-error is-dismissible"><p>' . esc_html__( 'Import failed: invalid JSON file.', 'skynet-smart-favorites' ) . '</p></div>';
		}

		$tab = $this->get_current_tab();

		?>
		<div class="skynsmfa-wrap skynsmfa-wrap--constrained wrap">
			<?php echo wp_kses_post( $notice_html ); ?>

			<div class="skynsmfa-header">
				<div class="skynsmfa-header__brand">
					<a class="skynsmfa-header__logo-link" href="<?php echo esc_url( 'https://skynetsol.com/' ); ?>" target="_blank" rel="noopener noreferrer">
						<span class="skynsmfa-header__logo-text"><?php esc_html_e( 'SkyNet', 'skynet-smart-favorites' ); ?></span>
						<span class="skynsmfa-header__logo-tag"><?php esc_html_e( 'Digital platforms & engineering', 'skynet-smart-favorites' ); ?></span>
					</a>
				</div>
				<div class="skynsmfa-header-inner">
					<p class="skynsmfa-header__eyebrow"><?php esc_html_e( 'WooCommerce extension', 'skynet-smart-favorites' ); ?></p>
					<h1><?php esc_html_e( 'SkyNet Smart Favorites', 'skynet-smart-favorites' ); ?></h1>
					<p class="skynsmfa-header__lead"><?php esc_html_e( 'Wishlists and favorites for WooCommerce — session-aware, guest-friendly, and ready for your storefront.', 'skynet-smart-favorites' ); ?></p>
				</div>
			</div>

			<h2 class="nav-tab-wrapper skynsmfa-nav-tabs">
				<?php foreach ( $this->get_tabs() as $slug => $label ) : ?>
					<a href="<?php echo esc_url( $this->tab_url( $slug ) ); ?>" class="nav-tab <?php echo $tab === $slug ? 'nav-tab-active' : ''; ?>">
						<?php echo esc_html( $label ); ?>
					</a>
				<?php endforeach; ?>
			</h2>

			<div class="skynsmfa-tab-panel skynsmfa-card skynsmfa-tab-panel--connected">
				<?php
				switch ( $tab ) {
					case 'settings':
						$this->render_tab_settings( $fields );
						break;
					case 'appearance':
						$this->render_tab_appearance( $fields );
						break;
					case 'tools':
						$this->render_tab_tools();
						break;
					default:
						/**
						 * Render a Pro or extension admin tab.
						 *
						 * @param string               $tab    Tab slug.
						 * @param array<string, mixed> $fields Merged settings.
						 */
						do_action( 'skynsmfa_render_admin_tab', $tab, $fields );
						break;
				}
				?>
			</div>
		</div>
		<?php
	}

	/**
	 * Settings tab.
	 *
	 * @param array $fields Current settings.
	 * @return void
	 */
	private function render_tab_settings( array $fields ): void {
		?>
		<form action="options.php" method="post" class="skynsmfa-settings-form">
			<?php settings_fields( $this->option_group ); ?>

			<section class="skynsmfa-settings-section" aria-labelledby="skynsmfa-heading-general">
				<header class="skynsmfa-settings-section__header">
					<h2 id="skynsmfa-heading-general" class="skynsmfa-settings-section__title"><?php esc_html_e( 'General', 'skynet-smart-favorites' ); ?></h2>
					<p class="skynsmfa-settings-section__lead"><?php esc_html_e( 'Core wishlist behavior and how lists work for shoppers.', 'skynet-smart-favorites' ); ?></p>
				</header>
				<div class="skynsmfa-settings-section__body">
					<div class="skynsmfa-settings-stack">
						<div class="skynsmfa-field-row skynsmfa-field-row--switch">
							<label for="skynsmfa_enable" class="skynsmfa-toggle">
								<input type="checkbox" id="skynsmfa_enable" name="skynsmfa_settings[skynsmfa_enable]" value="yes" <?php checked( (string) $fields['skynsmfa_enable'], 'yes' ); ?>>
								<span class="skynsmfa-slider" aria-hidden="true"></span>
								<span class="skynsmfa-label-text"><?php esc_html_e( 'Enable wishlist features globally', 'skynet-smart-favorites' ); ?></span>
							</label>
						</div>
						<div class="skynsmfa-field-row skynsmfa-field-row--switch">
							<label for="skynsmfa_multiple_enable" class="skynsmfa-toggle">
								<input type="checkbox" id="skynsmfa_multiple_enable" name="skynsmfa_settings[skynsmfa_multiple_enable]" value="yes" <?php checked( (string) $fields['skynsmfa_multiple_enable'], 'yes' ); ?>>
								<span class="skynsmfa-slider" aria-hidden="true"></span>
								<span class="skynsmfa-label-text"><?php esc_html_e( 'Allow multiple lists', 'skynet-smart-favorites' ); ?></span>
							</label>
						</div>
					</div>
					<div class="skynsmfa-field-block">
						<label for="skynsmfa_add_target_mode" class="skynsmfa-field-block__label"><?php esc_html_e( 'When adding from shop or product page', 'skynet-smart-favorites' ); ?></label>
						<select id="skynsmfa_add_target_mode" name="skynsmfa_settings[skynsmfa_add_target_mode]" class="skynsmfa-select">
							<option value="default" <?php selected( (string) $fields['skynsmfa_add_target_mode'], 'default' ); ?>><?php esc_html_e( 'Always use the default list', 'skynet-smart-favorites' ); ?></option>
							<option value="last_used" <?php selected( (string) $fields['skynsmfa_add_target_mode'], 'last_used' ); ?>><?php esc_html_e( 'Use the list used last (recommended)', 'skynet-smart-favorites' ); ?></option>
							<option value="ask" <?php selected( (string) $fields['skynsmfa_add_target_mode'], 'ask' ); ?>><?php esc_html_e( 'Ask which list each time', 'skynet-smart-favorites' ); ?></option>
						</select>
						<p class="description"><?php esc_html_e( 'Applies when multiple lists are enabled. Guests and customers keep a session “last used” list.', 'skynet-smart-favorites' ); ?></p>
					</div>
				</div>
			</section>

			<section class="skynsmfa-settings-section" aria-labelledby="skynsmfa-heading-button">
				<header class="skynsmfa-settings-section__header">
					<h2 id="skynsmfa-heading-button" class="skynsmfa-settings-section__title"><?php esc_html_e( 'Storefront button', 'skynet-smart-favorites' ); ?></h2>
					<p class="skynsmfa-settings-section__lead"><?php esc_html_e( 'Where the favorites control appears and how it looks on the public site.', 'skynet-smart-favorites' ); ?></p>
				</header>
				<div class="skynsmfa-settings-section__body">
					<div class="skynsmfa-settings-two-col">
						<div class="skynsmfa-settings-col">
							<h3 class="skynsmfa-settings-subhead"><?php esc_html_e( 'Catalog & archives', 'skynet-smart-favorites' ); ?></h3>
							<div class="skynsmfa-settings-stack">
								<div class="skynsmfa-field-row skynsmfa-field-row--switch">
									<label for="skynsmfa_loop_icon" class="skynsmfa-toggle">
										<input type="checkbox" id="skynsmfa_loop_icon" name="skynsmfa_settings[skynsmfa_loop_icon]" value="yes" <?php checked( (string) $fields['skynsmfa_loop_icon'], 'yes' ); ?>>
										<span class="skynsmfa-slider" aria-hidden="true"></span>
										<span class="skynsmfa-label-text"><?php esc_html_e( 'Show on product loop (shop, categories)', 'skynet-smart-favorites' ); ?></span>
									</label>
								</div>
							</div>
							<div class="skynsmfa-field-block">
								<label for="skynsmfa_loop_position" class="skynsmfa-field-block__label"><?php esc_html_e( 'Position on loop', 'skynet-smart-favorites' ); ?></label>
								<select id="skynsmfa_loop_position" name="skynsmfa_settings[skynsmfa_loop_position]" class="skynsmfa-select">
									<option value="before_add_to_cart" <?php selected( (string) $fields['skynsmfa_loop_position'], 'before_add_to_cart' ); ?>><?php esc_html_e( 'Before add to cart', 'skynet-smart-favorites' ); ?></option>
									<option value="after_add_to_cart" <?php selected( (string) $fields['skynsmfa_loop_position'], 'after_add_to_cart' ); ?>><?php esc_html_e( 'After add to cart', 'skynet-smart-favorites' ); ?></option>
									<option value="over_image" <?php selected( (string) $fields['skynsmfa_loop_position'], 'over_image' ); ?>><?php esc_html_e( 'Over product image', 'skynet-smart-favorites' ); ?></option>
								</select>
								<p class="skynsmfa-field-block__help"><?php esc_html_e( 'Over product image works best with Icon only on shop and category grids. For Button with text or Icon + text, use Before or After add to cart.', 'skynet-smart-favorites' ); ?></p>
							</div>
						</div>
						<div class="skynsmfa-settings-col">
							<h3 class="skynsmfa-settings-subhead"><?php esc_html_e( 'Single product', 'skynet-smart-favorites' ); ?></h3>
							<div class="skynsmfa-settings-stack">
								<div class="skynsmfa-field-row skynsmfa-field-row--switch">
									<label for="skynsmfa_single_icon" class="skynsmfa-toggle">
										<input type="checkbox" id="skynsmfa_single_icon" name="skynsmfa_settings[skynsmfa_single_icon]" value="yes" <?php checked( (string) $fields['skynsmfa_single_icon'], 'yes' ); ?>>
										<span class="skynsmfa-slider" aria-hidden="true"></span>
										<span class="skynsmfa-label-text"><?php esc_html_e( 'Show on single product page', 'skynet-smart-favorites' ); ?></span>
									</label>
								</div>
							</div>
							<div class="skynsmfa-field-block">
								<label for="skynsmfa_single_position" class="skynsmfa-field-block__label"><?php esc_html_e( 'Position on product page', 'skynet-smart-favorites' ); ?></label>
								<select id="skynsmfa_single_position" name="skynsmfa_settings[skynsmfa_single_position]" class="skynsmfa-select">
									<option value="after_add_to_cart" <?php selected( (string) $fields['skynsmfa_single_position'], 'after_add_to_cart' ); ?>><?php esc_html_e( 'After add to cart (in summary, recommended)', 'skynet-smart-favorites' ); ?></option>
									<option value="before_add_to_cart" <?php selected( (string) $fields['skynsmfa_single_position'], 'before_add_to_cart' ); ?>><?php esc_html_e( 'Before add to cart (in summary)', 'skynet-smart-favorites' ); ?></option>
									<option value="over_image" <?php selected( (string) $fields['skynsmfa_single_position'], 'over_image' ); ?>><?php esc_html_e( 'Over product image (floating)', 'skynet-smart-favorites' ); ?></option>
								</select>
							</div>
						</div>
					</div>
					<div class="skynsmfa-settings-row-grid">
						<div class="skynsmfa-field-block">
							<label for="skynsmfa_notification_type" class="skynsmfa-field-block__label"><?php esc_html_e( 'After add / remove Notification', 'skynet-smart-favorites' ); ?></label>
							<select id="skynsmfa_notification_type" name="skynsmfa_settings[skynsmfa_notification_type]" class="skynsmfa-select">
								<option value="toast" <?php selected( (string) $fields['skynsmfa_notification_type'], 'toast' ); ?>><?php esc_html_e( 'Toast', 'skynet-smart-favorites' ); ?></option>
								<option value="tooltip" <?php selected( (string) $fields['skynsmfa_notification_type'], 'tooltip' ); ?>><?php esc_html_e( 'Tooltip', 'skynet-smart-favorites' ); ?></option>
								<option value="none" <?php selected( (string) $fields['skynsmfa_notification_type'], 'none' ); ?>><?php esc_html_e( 'None', 'skynet-smart-favorites' ); ?></option>
							</select>
						</div>
					</div>
					<div class="skynsmfa-settings-stack skynsmfa-settings-stack--tight">
						<div class="skynsmfa-field-row skynsmfa-field-row--switch">
							<label for="skynsmfa_custom_shortcode" class="skynsmfa-toggle">
								<input type="checkbox" id="skynsmfa_custom_shortcode" name="skynsmfa_settings[skynsmfa_custom_shortcode]" value="yes" <?php checked( (string) $fields['skynsmfa_custom_shortcode'], 'yes' ); ?>>
								<span class="skynsmfa-slider" aria-hidden="true"></span>
								<span class="skynsmfa-label-text"><?php esc_html_e( 'Enable shortcode', 'skynet-smart-favorites' ); ?> <?php echo wp_kses( $this->shortcode_select_markup( '[skynsmfa_wishlist_icon]' ), array( 'code' => array( 'class' => true ) ) ); ?></span>
							</label>
							<p class="description">
								<?php
								echo esc_html__( 'Per-product add/remove control. On a product page use ', 'skynet-smart-favorites' );
								echo wp_kses( $this->shortcode_select_markup( '[skynsmfa_wishlist_icon]' ), array( 'code' => array( 'class' => true ) ) );
								echo esc_html__( ' with no ID; elsewhere pass product_id="123". Defaults to icon-only (same as before 1.0.3). Optional display="button", display="icon_text", or display="global" to match Button Customizer.', 'skynet-smart-favorites' );
								?>
							</p>
						</div>
						<div class="skynsmfa-field-row skynsmfa-field-row--switch">
							<label for="skynsmfa_menu_icon" class="skynsmfa-toggle">
								<input type="checkbox" id="skynsmfa_menu_icon" name="skynsmfa_settings[skynsmfa_menu_icon]" value="yes" <?php checked( (string) $fields['skynsmfa_menu_icon'], 'yes' ); ?>>
								<span class="skynsmfa-slider" aria-hidden="true"></span>
								<span class="skynsmfa-label-text"><?php esc_html_e( 'Enable favorites menu icon (block and shortcode)', 'skynet-smart-favorites' ); ?></span>
							</label>
							<p class="description">
								<?php
								echo esc_html__( 'Header icon with live item counter. Use the “SkyNet Smart Favorites icon” block under WooCommerce blocks (next to Mini Cart), the ', 'skynet-smart-favorites' );
								echo wp_kses( $this->shortcode_select_markup( '[skynsmfa_wishlist_menu_icon]' ), array( 'code' => array( 'class' => true ) ) );
								echo esc_html__( ' shortcode, or search for “SkyNet” or “favorites” in the block inserter.', 'skynet-smart-favorites' );
								?>
							</p>
						</div>
					</div>
				</div>
			</section>

			<section class="skynsmfa-settings-section" aria-labelledby="skynsmfa-heading-page">
				<header class="skynsmfa-settings-section__header">
					<h2 id="skynsmfa-heading-page" class="skynsmfa-settings-section__title"><?php esc_html_e( 'Wishlist page', 'skynet-smart-favorites' ); ?></h2>
					<p class="skynsmfa-settings-section__lead"><?php esc_html_e( 'The page where customers manage lists and move items to the cart.', 'skynet-smart-favorites' ); ?></p>
				</header>
				<div class="skynsmfa-settings-section__body">
					<div class="skynsmfa-settings-row-grid">
						<div class="skynsmfa-field-block">
							<label for="skynsmfa_page_layout" class="skynsmfa-field-block__label"><?php esc_html_e( 'Layout preset', 'skynet-smart-favorites' ); ?></label>
							<select id="skynsmfa_page_layout" name="skynsmfa_settings[skynsmfa_page_layout]" class="skynsmfa-select">
								<option value="table" <?php selected( (string) $fields['skynsmfa_page_layout'], 'table' ); ?>><?php esc_html_e( 'Table (default)', 'skynet-smart-favorites' ); ?></option>
								<option value="grid" <?php selected( (string) $fields['skynsmfa_page_layout'], 'grid' ); ?>><?php esc_html_e( 'Grid', 'skynet-smart-favorites' ); ?></option>
								<?php if ( Feature_Gate::is_pro_active() ) : ?>
								<option value="compact" <?php selected( (string) $fields['skynsmfa_page_layout'], 'compact' ); ?>><?php esc_html_e( 'Compact', 'skynet-smart-favorites' ); ?></option>
								<?php endif; ?>
							</select>
							<p class="description"><?php esc_html_e( 'Grid layout uses the same column count as WooCommerce → Settings → Products → Catalog → “Products per row”.', 'skynet-smart-favorites' ); ?></p>
							<?php if ( ! Feature_Gate::is_pro_active() ) : ?>
							<p class="description"><?php esc_html_e( 'Compact layout is available in SkyNet Smart Favorites Pro.', 'skynet-smart-favorites' ); ?></p>
							<?php endif; ?>
						</div>
						<div class="skynsmfa-field-block">
							<label for="wishlist_page_id" class="skynsmfa-field-block__label"><?php esc_html_e( 'Assigned page', 'skynet-smart-favorites' ); ?></label>
							<?php
							wp_dropdown_pages(
								array(
									'name'              => 'skynsmfa_settings[wishlist_page_id]',
									'id'                => 'wishlist_page_id',
									'show_option_none'  => esc_html__( '— Select —', 'skynet-smart-favorites' ),
									'option_none_value' => '0',
									'selected'          => absint( $fields['wishlist_page_id'] ?? 0 ),
									'class'             => 'skynsmfa-select',
								)
							);
							?>
							<p class="description">
								<?php
								echo esc_html__( 'The page must include the shortcode ', 'skynet-smart-favorites' );
								echo wp_kses( $this->shortcode_select_markup( '[skynsmfa_wishlist]' ), array( 'code' => array( 'class' => true ) ) );
								echo esc_html__( '.', 'skynet-smart-favorites' );
								?>
							</p>
						</div>
					</div>
				</div>
			</section>

			<section class="skynsmfa-settings-section" aria-labelledby="skynsmfa-heading-perf">
				<header class="skynsmfa-settings-section__header">
					<h2 id="skynsmfa-heading-perf" class="skynsmfa-settings-section__title"><?php esc_html_e( 'Performance & protection', 'skynet-smart-favorites' ); ?></h2>
					<p class="skynsmfa-settings-section__lead"><?php esc_html_e( 'Rate limiting for wishlist AJAX requests.', 'skynet-smart-favorites' ); ?></p>
				</header>
				<div class="skynsmfa-settings-section__body">
					<div class="skynsmfa-field-block skynsmfa-field-block--narrow">
						<label for="skynsmfa_rate_limit_per_min" class="skynsmfa-field-block__label"><?php esc_html_e( 'Max wishlist AJAX actions per IP per minute', 'skynet-smart-favorites' ); ?></label>
						<input type="number" class="skynsmfa-input-number" id="skynsmfa_rate_limit_per_min" name="skynsmfa_settings[skynsmfa_rate_limit_per_min]" value="<?php echo esc_attr( (string) absint( $fields['skynsmfa_rate_limit_per_min'] ?? 120 ) ); ?>" min="10" max="600" step="1">
						<p class="description"><?php esc_html_e( 'Helps reduce automated traffic against wishlist admin-ajax actions.', 'skynet-smart-favorites' ); ?></p>
					</div>
				</div>
			</section>

			<div class="skynsmfa-submit-wrap">
				<?php submit_button( __( 'Save settings', 'skynet-smart-favorites' ), 'primary skynsmfa-btn-primary', 'submit', false ); ?>
			</div>
		</form>
		<?php
	}

	/**
	 * Button Customizer tab (dedicated appearance form).
	 *
	 * @param array $fields Current settings.
	 * @return void
	 */
	private function render_tab_appearance( array $fields ): void {
		?>
		<form action="options.php" method="post" class="skynsmfa-settings-form skynsmfa-appearance-form">
			<?php settings_fields( $this->option_group ); ?>
			<?php settings_errors( 'skynsmfa_settings' ); ?>

			<?php $this->render_appearance_section( $fields ); ?>

			<div class="skynsmfa-submit-wrap">
				<?php submit_button( __( 'Save appearance', 'skynet-smart-favorites' ), 'primary skynsmfa-btn-primary', 'submit', false ); ?>
			</div>
		</form>
		<?php
	}

	/**
	 * Render a single hex color picker field.
	 *
	 * @param string               $key    skynsmfa_settings array key.
	 * @param string               $label  Visible label.
	 * @param array<string, mixed> $fields Current settings.
	 * @return void
	 */
	private function render_color_field( string $key, string $label, array $fields ): void {
		$value = (string) ( $fields[ $key ] ?? '' );
		?>
		<div class="skynsmfa-field-block skynsmfa-field-block--color">
			<label for="<?php echo esc_attr( $key ); ?>" class="skynsmfa-field-block__label"><?php echo esc_html( $label ); ?></label>
			<input
				type="text"
				id="<?php echo esc_attr( $key ); ?>"
				class="skynsmfa-color-field"
				name="skynsmfa_settings[<?php echo esc_attr( $key ); ?>]"
				value="<?php echo esc_attr( $value ); ?>"
				data-default-color=""
				autocomplete="off"
			>
		</div>
		<?php
	}

	/**
	 * Render a single text input field.
	 *
	 * @param string               $key         skynsmfa_settings array key.
	 * @param string               $label       Visible label.
	 * @param string               $placeholder Placeholder (default label).
	 * @param array<string, mixed> $fields      Current settings.
	 * @return void
	 */
	private function render_text_field( string $key, string $label, string $placeholder, array $fields ): void {
		$value = (string) ( $fields[ $key ] ?? '' );
		?>
		<div class="skynsmfa-field-block">
			<label for="<?php echo esc_attr( $key ); ?>" class="skynsmfa-field-block__label"><?php echo esc_html( $label ); ?></label>
			<input
				type="text"
				id="<?php echo esc_attr( $key ); ?>"
				class="skynsmfa-input-text"
				name="skynsmfa_settings[<?php echo esc_attr( $key ); ?>]"
				value="<?php echo esc_attr( $value ); ?>"
				placeholder="<?php echo esc_attr( $placeholder ); ?>"
			>
		</div>
		<?php
	}

	/**
	 * Render the custom CSS textarea (Button Customizer).
	 *
	 * @param array<string, mixed> $fields Current settings.
	 * @return void
	 */
	private function render_custom_css_field( array $fields ): void {
		$value = (string) ( $fields['skynsmfa_custom_css'] ?? '' );
		?>
		<div class="skynsmfa-field-block skynsmfa-field-block--custom-css">
			<label for="skynsmfa_custom_css" class="skynsmfa-field-block__label"><?php esc_html_e( 'CSS rules', 'skynet-smart-favorites' ); ?></label>
			<textarea
				id="skynsmfa_custom_css"
				class="skynsmfa-textarea skynsmfa-textarea--css"
				name="skynsmfa_settings[skynsmfa_custom_css]"
				rows="8"
				spellcheck="false"
				placeholder="<?php echo esc_attr( ".skynsmfa-wishlist-button {\n  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);\n}" ); ?>"
			><?php echo esc_textarea( $value ); ?></textarea>
			<p class="skynsmfa-field-block__help"><?php esc_html_e( 'Example selectors: .skynsmfa-wishlist-button, .skynsmfa-icon-button, .skynsmfa-btn-icon. @import and script-like values are not allowed.', 'skynet-smart-favorites' ); ?></p>
		</div>
		<?php
	}

	/**
	 * Button appearance customization section.
	 *
	 * @param array<string, mixed> $fields Current settings.
	 * @return void
	 */
	private function render_appearance_section( array $fields ): void {
		$display_mode       = (string) ( $fields['skynsmfa_display_mode'] ?? 'button' );
		$show_icon_preview  = ( 'icon' === $display_mode );
		$show_text_preview  = in_array( $display_mode, array( 'button', 'icon_text' ), true );
		$show_icon_settings = in_array( $display_mode, array( 'icon', 'icon_text' ), true );
		$show_text_settings = in_array( $display_mode, array( 'button', 'icon_text' ), true );
		?>
		<section class="skynsmfa-settings-section skynsmfa-settings-section--appearance" aria-labelledby="skynsmfa-heading-appearance">
			<header class="skynsmfa-settings-section__header">
				<h2 id="skynsmfa-heading-appearance" class="skynsmfa-settings-section__title"><?php esc_html_e( 'Button Customizer', 'skynet-smart-favorites' ); ?></h2>
				<p class="skynsmfa-settings-section__lead"><?php esc_html_e( 'Customize how the favorites button looks on your storefront. Changes preview live below and apply to shop and product pages after you save.', 'skynet-smart-favorites' ); ?></p>
			</header>
			<div class="skynsmfa-settings-section__body skynsmfa-settings-section__body--appearance">
				<div class="skynsmfa-appearance-layout">

					<div class="skynsmfa-appearance-preview" aria-hidden="true">
						<h3 class="skynsmfa-settings-subhead skynsmfa-settings-subhead--inline"><?php esc_html_e( 'Live preview', 'skynet-smart-favorites' ); ?></h3>
						<div class="skynsmfa-appearance-preview__stage skynsmfa-appearance-preview__stage--icon<?php echo $show_icon_preview ? '' : ' is-hidden'; ?>">
							<figure class="skynsmfa-preview-item">
								<button type="button" class="skynsmfa-preview-icon" disabled>
									<svg class="skynsmfa-preview-svg" viewBox="0 0 24 24" aria-hidden="true" focusable="false"></svg>
								</button>
								<figcaption><?php esc_html_e( 'Default', 'skynet-smart-favorites' ); ?></figcaption>
							</figure>
							<figure class="skynsmfa-preview-item">
								<button type="button" class="skynsmfa-preview-icon is-hover" disabled>
									<svg class="skynsmfa-preview-svg" viewBox="0 0 24 24" aria-hidden="true" focusable="false"></svg>
								</button>
								<figcaption><?php esc_html_e( 'Hover', 'skynet-smart-favorites' ); ?></figcaption>
							</figure>
							<figure class="skynsmfa-preview-item">
								<button type="button" class="skynsmfa-preview-icon is-added" disabled>
									<svg class="skynsmfa-preview-svg" viewBox="0 0 24 24" aria-hidden="true" focusable="false"></svg>
								</button>
								<figcaption><?php esc_html_e( 'Added', 'skynet-smart-favorites' ); ?></figcaption>
							</figure>
						</div>
						<div class="skynsmfa-appearance-preview__stage skynsmfa-appearance-preview__stage--text<?php echo $show_text_preview ? '' : ' is-hidden'; ?>">
							<figure class="skynsmfa-preview-item skynsmfa-preview-item--text">
								<button type="button" class="button skynsmfa-preview-text" tabindex="-1" aria-disabled="true"><span class="skynsmfa-btn-text"><?php esc_html_e( 'Add to wishlist', 'skynet-smart-favorites' ); ?></span></button>
								<figcaption><?php esc_html_e( 'Default', 'skynet-smart-favorites' ); ?></figcaption>
							</figure>
							<figure class="skynsmfa-preview-item skynsmfa-preview-item--text">
								<button type="button" class="button skynsmfa-preview-text is-added" tabindex="-1" aria-disabled="true"><span class="skynsmfa-btn-text"><?php esc_html_e( 'Already in wishlist', 'skynet-smart-favorites' ); ?></span></button>
								<figcaption><?php esc_html_e( 'Added', 'skynet-smart-favorites' ); ?></figcaption>
							</figure>
						</div>
					</div>

					<hr class="skynsmfa-appearance-divider">

					<div class="skynsmfa-appearance-section">
						<h3 class="skynsmfa-settings-subhead"><?php esc_html_e( 'Display mode', 'skynet-smart-favorites' ); ?></h3>
						<p class="skynsmfa-appearance-section__desc"><?php esc_html_e( 'Choose the overall button type. Sections below show or hide based on your choice.', 'skynet-smart-favorites' ); ?></p>
						<div class="skynsmfa-field-block skynsmfa-field-block--compact">
							<label for="skynsmfa_display_mode" class="skynsmfa-field-block__label"><?php esc_html_e( 'Button type', 'skynet-smart-favorites' ); ?></label>
							<select id="skynsmfa_display_mode" name="skynsmfa_settings[skynsmfa_display_mode]" class="skynsmfa-select">
								<option value="button" <?php selected( (string) $fields['skynsmfa_display_mode'], 'button' ); ?>><?php esc_html_e( 'Button with text', 'skynet-smart-favorites' ); ?></option>
								<option value="icon" <?php selected( (string) $fields['skynsmfa_display_mode'], 'icon' ); ?>><?php esc_html_e( 'Icon only', 'skynet-smart-favorites' ); ?></option>
								<option value="icon_text" <?php selected( (string) $fields['skynsmfa_display_mode'], 'icon_text' ); ?>><?php esc_html_e( 'Icon + text', 'skynet-smart-favorites' ); ?></option>
							</select>
						</div>
					</div>

					<hr class="skynsmfa-appearance-divider">

					<div class="skynsmfa-settings-two-col skynsmfa-appearance-two-col">
						<div class="skynsmfa-settings-col skynsmfa-appearance-section skynsmfa-appearance-section--icon<?php echo $show_icon_settings ? '' : ' is-hidden'; ?>">
							<h3 class="skynsmfa-settings-subhead"><?php esc_html_e( 'Icon', 'skynet-smart-favorites' ); ?></h3>
							<p class="skynsmfa-appearance-section__desc"><?php esc_html_e( 'Icon image, size, shape, and colors.', 'skynet-smart-favorites' ); ?></p>

							<div class="skynsmfa-appearance-subsection">
								<h4 class="skynsmfa-appearance-subsection__title"><?php esc_html_e( 'Icon image', 'skynet-smart-favorites' ); ?></h4>
								<div class="skynsmfa-field-block">
									<label for="skynsmfa_icon_style" class="skynsmfa-field-block__label"><?php esc_html_e( 'Built-in icon', 'skynet-smart-favorites' ); ?></label>
									<select id="skynsmfa_icon_style" name="skynsmfa_settings[skynsmfa_icon_style]" class="skynsmfa-select">
										<option value="heart" <?php selected( (string) $fields['skynsmfa_icon_style'], 'heart' ); ?>><?php esc_html_e( 'Heart', 'skynet-smart-favorites' ); ?></option>
										<option value="star" <?php selected( (string) $fields['skynsmfa_icon_style'], 'star' ); ?>><?php esc_html_e( 'Star', 'skynet-smart-favorites' ); ?></option>
										<option value="bookmark" <?php selected( (string) $fields['skynsmfa_icon_style'], 'bookmark' ); ?>><?php esc_html_e( 'Bookmark', 'skynet-smart-favorites' ); ?></option>
										<option value="bag" <?php selected( (string) $fields['skynsmfa_icon_style'], 'bag' ); ?>><?php esc_html_e( 'Shopping bag', 'skynet-smart-favorites' ); ?></option>
										<option value="tag" <?php selected( (string) $fields['skynsmfa_icon_style'], 'tag' ); ?>><?php esc_html_e( 'Tag', 'skynet-smart-favorites' ); ?></option>
										<option value="gift" <?php selected( (string) $fields['skynsmfa_icon_style'], 'gift' ); ?>><?php esc_html_e( 'Gift', 'skynet-smart-favorites' ); ?></option>
										<option value="thumb" <?php selected( (string) $fields['skynsmfa_icon_style'], 'thumb' ); ?>><?php esc_html_e( 'Thumbs up', 'skynet-smart-favorites' ); ?></option>
										<option value="plus" <?php selected( (string) $fields['skynsmfa_icon_style'], 'plus' ); ?>><?php esc_html_e( 'Plus', 'skynet-smart-favorites' ); ?></option>
									</select>
								</div>
								<?php
								$skynsmfa_custom_icon_id  = absint( $fields['skynsmfa_icon_custom_id'] ?? 0 );
								$skynsmfa_custom_icon_url = $skynsmfa_custom_icon_id > 0 ? wp_get_attachment_image_url( $skynsmfa_custom_icon_id, 'full' ) : '';
								?>
								<div class="skynsmfa-field-block">
									<span class="skynsmfa-field-block__label"><?php esc_html_e( 'Custom upload (optional)', 'skynet-smart-favorites' ); ?></span>
									<input type="hidden" id="skynsmfa_icon_custom_id" name="skynsmfa_settings[skynsmfa_icon_custom_id]" value="<?php echo esc_attr( (string) $skynsmfa_custom_icon_id ); ?>">
									<div class="skynsmfa-custom-icon">
										<img class="skynsmfa-custom-icon__preview" src="<?php echo esc_url( (string) $skynsmfa_custom_icon_url ); ?>" alt="" <?php echo $skynsmfa_custom_icon_url ? '' : 'hidden'; ?> />
										<button type="button" class="button skynsmfa-custom-icon__select"><?php esc_html_e( 'Select image', 'skynet-smart-favorites' ); ?></button>
										<button type="button" class="button-link skynsmfa-custom-icon__remove" <?php echo $skynsmfa_custom_icon_url ? '' : 'hidden'; ?>><?php esc_html_e( 'Remove', 'skynet-smart-favorites' ); ?></button>
									</div>
								</div>
							</div>

							<div class="skynsmfa-appearance-subsection">
								<h4 class="skynsmfa-appearance-subsection__title"><?php esc_html_e( 'Size & shape', 'skynet-smart-favorites' ); ?></h4>
								<div class="skynsmfa-settings-row-grid">
									<div class="skynsmfa-field-block">
										<label for="skynsmfa_icon_size" class="skynsmfa-field-block__label"><?php esc_html_e( 'Size (px)', 'skynet-smart-favorites' ); ?></label>
										<input type="number" class="skynsmfa-input-number" id="skynsmfa_icon_size" name="skynsmfa_settings[skynsmfa_icon_size]" value="<?php echo esc_attr( (string) absint( $fields['skynsmfa_icon_size'] ?? 24 ) ); ?>" min="16" max="64" step="1">
									</div>
								</div>
								<div class="skynsmfa-field-block">
									<label for="skynsmfa_icon_shape" class="skynsmfa-field-block__label"><?php esc_html_e( 'Background shape', 'skynet-smart-favorites' ); ?></label>
									<select id="skynsmfa_icon_shape" name="skynsmfa_settings[skynsmfa_icon_shape]" class="skynsmfa-select">
										<option value="none" <?php selected( (string) $fields['skynsmfa_icon_shape'], 'none' ); ?>><?php esc_html_e( 'None', 'skynet-smart-favorites' ); ?></option>
										<option value="rounded" <?php selected( (string) $fields['skynsmfa_icon_shape'], 'rounded' ); ?>><?php esc_html_e( 'Rounded square', 'skynet-smart-favorites' ); ?></option>
										<option value="circle" <?php selected( (string) $fields['skynsmfa_icon_shape'], 'circle' ); ?>><?php esc_html_e( 'Circle', 'skynet-smart-favorites' ); ?></option>
									</select>
								</div>
								<div class="skynsmfa-field-block">
									<label for="skynsmfa_icon_fill" class="skynsmfa-field-block__label"><?php esc_html_e( 'Idle fill', 'skynet-smart-favorites' ); ?></label>
									<select id="skynsmfa_icon_fill" name="skynsmfa_settings[skynsmfa_icon_fill]" class="skynsmfa-select">
										<option value="outline" <?php selected( (string) $fields['skynsmfa_icon_fill'], 'outline' ); ?>><?php esc_html_e( 'Outline', 'skynet-smart-favorites' ); ?></option>
										<option value="filled" <?php selected( (string) $fields['skynsmfa_icon_fill'], 'filled' ); ?>><?php esc_html_e( 'Filled', 'skynet-smart-favorites' ); ?></option>
									</select>
								</div>
								<div class="skynsmfa-field-block skynsmfa-field-block--icon-text-only<?php echo ( 'icon_text' === $display_mode ) ? '' : ' is-hidden'; ?>">
									<label for="skynsmfa_icon_text_position" class="skynsmfa-field-block__label"><?php esc_html_e( 'Icon position beside text', 'skynet-smart-favorites' ); ?></label>
									<select id="skynsmfa_icon_text_position" name="skynsmfa_settings[skynsmfa_icon_text_position]" class="skynsmfa-select">
										<option value="before" <?php selected( (string) ( $fields['skynsmfa_icon_text_position'] ?? 'before' ), 'before' ); ?>><?php esc_html_e( 'Before text', 'skynet-smart-favorites' ); ?></option>
										<option value="after" <?php selected( (string) ( $fields['skynsmfa_icon_text_position'] ?? 'before' ), 'after' ); ?>><?php esc_html_e( 'After text', 'skynet-smart-favorites' ); ?></option>
									</select>
								</div>
							</div>

							<div class="skynsmfa-appearance-subsection">
								<h4 class="skynsmfa-appearance-subsection__title"><?php esc_html_e( 'Icon colors', 'skynet-smart-favorites' ); ?></h4>
								<div class="skynsmfa-settings-row-grid">
									<?php $this->render_color_field( 'skynsmfa_icon_color', __( 'Default', 'skynet-smart-favorites' ), $fields ); ?>
									<?php $this->render_color_field( 'skynsmfa_icon_hover_color', __( 'Hover', 'skynet-smart-favorites' ), $fields ); ?>
								</div>
								<?php $this->render_color_field( 'skynsmfa_icon_active_color', __( 'When added', 'skynet-smart-favorites' ), $fields ); ?>
							</div>
						</div>

						<div class="skynsmfa-settings-col skynsmfa-appearance-section skynsmfa-appearance-section--text-button<?php echo $show_text_settings ? '' : ' is-hidden'; ?>">
							<h3 class="skynsmfa-settings-subhead"><?php esc_html_e( 'Text button', 'skynet-smart-favorites' ); ?></h3>
							<p class="skynsmfa-appearance-section__desc"><?php esc_html_e( 'Button background, label colors, and corner radius.', 'skynet-smart-favorites' ); ?></p>

							<div class="skynsmfa-appearance-subsection">
								<h4 class="skynsmfa-appearance-subsection__title"><?php esc_html_e( 'Default state', 'skynet-smart-favorites' ); ?></h4>
								<div class="skynsmfa-settings-row-grid">
									<?php $this->render_color_field( 'skynsmfa_btn_bg_color', __( 'Background', 'skynet-smart-favorites' ), $fields ); ?>
									<?php $this->render_color_field( 'skynsmfa_btn_text_color', __( 'Text', 'skynet-smart-favorites' ), $fields ); ?>
								</div>
								<?php $this->render_color_field( 'skynsmfa_btn_border_color', __( 'Border', 'skynet-smart-favorites' ), $fields ); ?>
							</div>
							<div class="skynsmfa-appearance-subsection">
								<h4 class="skynsmfa-appearance-subsection__title"><?php esc_html_e( 'Added state', 'skynet-smart-favorites' ); ?></h4>
								<div class="skynsmfa-settings-row-grid">
									<?php $this->render_color_field( 'skynsmfa_btn_active_bg_color', __( 'Background', 'skynet-smart-favorites' ), $fields ); ?>
									<?php $this->render_color_field( 'skynsmfa_btn_active_text_color', __( 'Text', 'skynet-smart-favorites' ), $fields ); ?>
								</div>
							</div>
							<div class="skynsmfa-appearance-subsection">
								<h4 class="skynsmfa-appearance-subsection__title"><?php esc_html_e( 'Shape', 'skynet-smart-favorites' ); ?></h4>
								<div class="skynsmfa-settings-row-grid">
									<div class="skynsmfa-field-block">
										<label for="skynsmfa_btn_radius" class="skynsmfa-field-block__label"><?php esc_html_e( 'Corner radius (px)', 'skynet-smart-favorites' ); ?></label>
										<input type="number" class="skynsmfa-input-number" id="skynsmfa_btn_radius" name="skynsmfa_settings[skynsmfa_btn_radius]" value="<?php echo esc_attr( (string) ( $fields['skynsmfa_btn_radius'] ?? '' ) ); ?>" min="0" max="40" step="1" placeholder="<?php esc_attr_e( 'Default', 'skynet-smart-favorites' ); ?>">
									</div>
								</div>
							</div>
						</div>
					</div>

					<hr class="skynsmfa-appearance-divider">

					<div class="skynsmfa-appearance-section">
						<h3 class="skynsmfa-settings-subhead"><?php esc_html_e( 'Custom CSS', 'skynet-smart-favorites' ); ?></h3>
						<p class="skynsmfa-appearance-section__desc"><?php esc_html_e( 'Optional CSS for wishlist buttons and icons. Invalid or unsafe rules are rejected on save.', 'skynet-smart-favorites' ); ?></p>
						<?php $this->render_custom_css_field( $fields ); ?>
					</div>

					<hr class="skynsmfa-appearance-divider">

					<div class="skynsmfa-appearance-section">
						<h3 class="skynsmfa-settings-subhead"><?php esc_html_e( 'Labels', 'skynet-smart-favorites' ); ?></h3>
						<p class="skynsmfa-appearance-section__desc"><?php esc_html_e( 'Text on the button and the screen-reader label for remove.', 'skynet-smart-favorites' ); ?></p>
						<div class="skynsmfa-settings-row-grid skynsmfa-settings-row-grid--triple">
							<?php $this->render_text_field( 'skynsmfa_label_add', __( 'Add label', 'skynet-smart-favorites' ), __( 'Add to wishlist', 'skynet-smart-favorites' ), $fields ); ?>
							<?php $this->render_text_field( 'skynsmfa_label_added', __( 'Added label', 'skynet-smart-favorites' ), __( 'Already in wishlist', 'skynet-smart-favorites' ), $fields ); ?>
							<?php $this->render_text_field( 'skynsmfa_label_remove', __( 'Remove label (accessibility)', 'skynet-smart-favorites' ), __( 'Remove from wishlist', 'skynet-smart-favorites' ), $fields ); ?>
						</div>
					</div>

				</div>
			</div>
		</section>
		<?php
	}

	/**
	 * Tools tab.
	 *
	 * @return void
	 */
	private function render_tab_tools(): void {
		?>
		<div class="skynsmfa-tab-inner skynsmfa-tools">
		<section class="skynsmfa-tool-card">
			<h2 class="skynsmfa-tool-card__title"><?php esc_html_e( 'Wishlist page', 'skynet-smart-favorites' ); ?></h2>
			<p class="skynsmfa-tool-card__desc"><?php esc_html_e( 'Recreate the default wishlist page and shortcode if it was deleted.', 'skynet-smart-favorites' ); ?></p>
			<form method="post" action="" class="skynsmfa-tool-card__form">
				<?php wp_nonce_field( 'skynsmfa_recreate_action' ); ?>
				<button type="submit" name="skynsmfa_recreate_page" class="button button-secondary">
					<?php esc_html_e( 'Recreate wishlist page', 'skynet-smart-favorites' ); ?>
				</button>
			</form>
		</section>
		<?php
		/**
		 * Extra Tools tab content (e.g. Pro export/import).
		 */
		do_action( 'skynsmfa_tools_tab_content' );
		?>
		</div>
		<?php
	}
}
