<?php
defined( 'ABSPATH' ) || exit;

/**
 * Admin settings page for TukiFlow.
 *
 * Renders a React-powered UI (via @wordpress/components) mounted on
 * #tfdc-admin-root. Settings are read/written through the REST API.
 */
class TFDC_Admin {

	/** @var self|null */
	private static $instance = null;

	/**
	 * Default settings values.
	 *
	 * @var array
	 */
	private static $defaults = array(
		// General.
		'buy_now_enabled'    => true,
		'buy_now_text'       => 'Buy Now',
		'buy_now_position'   => 'after_cart',
		'buy_now_on_loop'    => true,
		'buy_now_clear_cart' => false,
		'hide_add_to_cart'   => false,
		// Single product button style.
		'btn_single_bg'                  => '#6f43df',
		'btn_single_bg_hover'            => '#4c27ad',
		'btn_single_color'               => '#ffffff',
		'btn_single_color_hover'         => '#ffffff',
		'btn_single_border_color'        => '#6f43df',
		'btn_single_border_color_hover'  => '#4c27ad',
		'btn_single_border_width'        => 1,
		'btn_single_border_radius'       => 6,
		'btn_single_font_size'           => '',
		'btn_single_font_weight'         => '600',
		'btn_single_padding_y'           => 12,
		'btn_single_padding_x'           => 20,
		'btn_single_width'               => '',
		'btn_single_width_custom'        => '',
		// Loop / archive button style.
		'btn_loop_bg'                    => '#6f43df',
		'btn_loop_bg_hover'              => '#4c27ad',
		'btn_loop_color'                 => '#ffffff',
		'btn_loop_color_hover'           => '#ffffff',
		'btn_loop_border_color'          => '#6f43df',
		'btn_loop_border_color_hover'    => '#4c27ad',
		'btn_loop_border_width'          => 1,
		'btn_loop_border_radius'         => 6,
		'btn_loop_font_size'             => '',
		'btn_loop_font_weight'           => '600',
		'btn_loop_padding_y'             => 10,
		'btn_loop_padding_x'             => 16,
		'btn_loop_width'                 => '',
		'btn_loop_width_custom'          => '',
	);

	/**
	 * Get the single instance.
	 *
	 * @return self
	 */
	public static function get_instance() {
		if ( is_null( self::$instance ) ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Constructor.
	 */
	private function __construct() {
		add_action( 'admin_menu', array( $this, 'add_menu' ) );
		add_action( 'admin_head', array( $this, 'print_admin_menu_icon_styles' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_react_admin' ) );
		add_action( 'wp_ajax_tfdc_search_products', array( $this, 'ajax_search_landing_page_products' ) );
		add_filter( 'plugin_action_links_tukiflow-direct-checkout-woocommerce/tukiflow-direct-checkout-woocommerce.php', array( $this, 'add_settings_link' ) );
	}

	/**
	 * Get merged settings (stored + defaults).
	 *
	 * @return array
	 */
	public static function get_settings() {
		$stored = get_option( 'tfdc_settings', array() );
		$settings = wp_parse_args( $stored, self::$defaults );

		if ( ! array_key_exists( 'hide_add_to_cart', $stored ) && ! empty( $stored['skip_cart'] ) ) {
			$settings['hide_add_to_cart'] = true;
		}

		return $settings;
	}

	/**
	 * Register top-level admin menu.
	 */
	public function add_menu() {
		add_menu_page(
			__( 'TukiFlow', 'tukiflow-direct-checkout-woocommerce' ),
			__( 'TukiFlow', 'tukiflow-direct-checkout-woocommerce' ),
			'manage_options',
			'tukiflow',
			array( $this, 'render_landing_pages' ),
			TFDC_URL . 'assets/icon-256x256.png',
			56
		);
	}

	/**
	 * Keep the branded menu icon aligned with WordPress admin menu sizing.
	 */
	public function print_admin_menu_icon_styles() {
		?>
		<style>
			#adminmenu .toplevel_page_tukiflow .wp-menu-image img {
				box-sizing: border-box;
				object-fit: contain;
				width: 18px;
			}
		</style>
		<?php
	}

	/**
	 * Enqueue the React admin bundle on the TukiFlow settings page.
	 *
	 * @param string $hook Current admin page hook.
	 */
	public function enqueue_react_admin( $hook ) {
		if ( 'toplevel_page_tukiflow' !== $hook ) {
			return;
		}

		$asset_file = TFDC_DIR . 'assets/admin/index.asset.php';
		if ( ! file_exists( $asset_file ) ) {
			// Build hasn't run yet — show a notice and bail.
			add_action( 'admin_notices', function () {
				echo '<div class="notice notice-error"><p>';
				echo esc_html__( 'TukiFlow: admin build missing. Run `npm run build:admin` to generate assets/admin/.', 'tukiflow-direct-checkout-woocommerce' );
				echo '</p></div>';
			} );
			return;
		}

		$asset = require $asset_file;

		wp_enqueue_script(
			'tfdc-admin',
			TFDC_URL . 'assets/admin/index.js',
			$asset['dependencies'],
			$asset['version'],
			true
		);

		if ( file_exists( TFDC_DIR . 'assets/admin/index.css' ) ) {
			wp_enqueue_style(
				'tfdc-admin',
				TFDC_URL . 'assets/admin/index.css',
				array( 'wp-components' ),
				$asset['version']
			);
		}

		wp_localize_script(
			'tfdc-admin',
			'tfdcAdminData',
			array(
				'page'               => 'settings',
				'settings'           => self::get_settings(),
				'apiUrl'             => rest_url( 'tukiflow/v1/settings' ),
				'landingPagesUrl'    => rest_url( 'tukiflow/v1/landing-pages' ),
				'templateLibraryUrl' => rest_url( 'tukiflow/v1/landing-pages/templates' ),
				'ajaxUrl'            => admin_url( 'admin-ajax.php' ),
				'wcSearchNonce'      => wp_create_nonce( 'search-products' ),
				'wpNonce'            => wp_create_nonce( 'wp_rest' ),
				'brand'              => array(
					'logoUrl' => TFDC_URL . 'assets/icon-256x256.png',
					'color'   => '#6f43df',
					'dark'    => '#4c27ad',
				),
			)
		);
	}

	/**
	 * Render the landing pages admin app.
	 */
	public function render_landing_pages() {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'You do not have permission to access this page.', 'tukiflow-direct-checkout-woocommerce' ) );
		}
		?>
		<div class="wrap">
			<h1 class="wp-heading-inline screen-reader-text"><?php esc_html_e( 'TukiFlow', 'tukiflow-direct-checkout-woocommerce' ); ?></h1>
			<div id="tfdc-admin-root"></div>
		</div>
		<?php
	}

	/**
	 * AJAX product search for the landing page popup.
	 *
	 * Keeps WooCommerce's native search behavior while avoiding shared
	 * WooCommerce AJAX hooks that third-party plugins can alter.
	 */
	public function ajax_search_landing_page_products() {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error(
				array(
					'message' => __( 'Insufficient permissions.', 'tukiflow-direct-checkout-woocommerce' ),
				),
				403
			);
		}

		check_ajax_referer( 'search-products', 'security' );

		$term = isset( $_POST['term'] ) ? sanitize_text_field( wp_unslash( $_POST['term'] ) ) : '';
		$term = trim( $term );

		if ( '' === $term ) {
			wp_send_json( array() );
		}

		$product_ids = $this->search_landing_page_products( $term );
		$results     = array();

		foreach ( $product_ids as $product_id ) {
			$product = wc_get_product( $product_id );
			if ( ! $product ) {
				continue;
			}

			$results[] = array(
				'id'            => (string) $product_id,
				'name'          => wp_strip_all_tags( $product->get_formatted_name() ),
				'image'         => $this->get_product_image_url( $product ),
				'regular_price' => $this->get_formatted_product_price( $product->get_regular_price() ),
				'sale_price'    => $this->get_formatted_product_price( $product->get_sale_price() ),
			);
		}

		wp_send_json( $results );
	}

	/**
	 * Search products for the landing page modal.
	 *
	 * Uses WooCommerce's native product datastore first, then falls back to a
	 * simple WordPress product query if another plugin causes the datastore
	 * search to return no matches unexpectedly.
	 *
	 * @param string $term Search term.
	 * @return int[]
	 */
	private function search_landing_page_products( $term ) {
		$product_ids = array();
		$data_store  = WC_Data_Store::load( 'product' );

		if ( is_object( $data_store ) && method_exists( $data_store, 'search_products' ) ) {
			$product_ids = $data_store->search_products( $term, '', true, true, 30 );
		}

		if ( ! empty( $product_ids ) ) {
			return array_values( array_unique( array_map( 'absint', $product_ids ) ) );
		}

		$fallback_query = new WP_Query(
			array(
				'post_type'              => array( 'product', 'product_variation' ),
				'post_status'            => array_keys( get_post_stati() ),
				's'                      => $term,
				'posts_per_page'         => 30,
				'fields'                 => 'ids',
				'orderby'                => 'title',
				'order'                  => 'ASC',
				'no_found_rows'          => true,
				'ignore_sticky_posts'    => true,
				'update_post_meta_cache' => false,
				'update_post_term_cache' => false,
			)
		);

		if ( empty( $fallback_query->posts ) ) {
			return array();
		}

		return array_values( array_unique( array_map( 'absint', $fallback_query->posts ) ) );
	}

	/**
	 * Get a product thumbnail URL, falling back to the parent product for variations.
	 *
	 * @param WC_Product $product Product object.
	 * @return string
	 */
	private function get_product_image_url( $product ) {
		$image_id = $product->get_image_id();

		if ( ! $image_id && $product->is_type( 'variation' ) ) {
			$parent = wc_get_product( $product->get_parent_id() );
			if ( $parent ) {
				$image_id = $parent->get_image_id();
			}
		}

		return $image_id ? wp_get_attachment_image_url( $image_id, 'thumbnail' ) : '';
	}

	/**
	 * Format a raw WooCommerce price for admin display.
	 *
	 * @param string $price Raw product price.
	 * @return string
	 */
	private function get_formatted_product_price( $price ) {
		if ( '' === $price || null === $price ) {
			return '';
		}

		$formatted_price = html_entity_decode(
			wp_strip_all_tags( wc_price( wc_format_decimal( $price ) ) ),
			ENT_QUOTES,
			get_bloginfo( 'charset' )
		);

		$formatted_price = preg_replace( '/\x{00A0}+/u', '', $formatted_price );

		return is_string( $formatted_price ) ? trim( $formatted_price ) : '';
	}

	/**
	 * Sanitize settings before saving.
	 *
	 * When `_tab` is 'all' (REST API path), every field is processed at once.
	 * When `_tab` is a specific tab key, only that tab's fields are updated
	 * and all other stored values are preserved (legacy Settings API path).
	 *
	 * @param array $input Raw input.
	 * @return array Sanitized settings.
	 */
	public function sanitize_settings( $input ) {
		$clean = self::get_settings();
		$tab   = isset( $input['_tab'] ) ? sanitize_key( $input['_tab'] ) : 'general';

		if ( 'all' === $tab ) {
			$clean = $this->sanitize_general( $input, $clean );
			$clean = $this->sanitize_button_style( $input, $clean );
			return $clean;
		}

		switch ( $tab ) {
			case 'general':
				$clean = $this->sanitize_general( $input, $clean );
				break;
			case 'button-style':
				$clean = $this->sanitize_button_style( $input, $clean );
				break;
		}

		return $clean;
	}

	// -------------------------------------------------------------------------
	// Private sanitization helpers
	// -------------------------------------------------------------------------

	/**
	 * @param array $input
	 * @param array $clean
	 * @return array
	 */
	private function sanitize_general( $input, $clean ) {
		unset( $clean['skip_cart'] );

		$clean['buy_now_enabled']  = ! empty( $input['buy_now_enabled'] );
		$clean['buy_now_text']     = isset( $input['buy_now_text'] ) ? sanitize_text_field( $input['buy_now_text'] ) : 'Buy Now';
		$clean['buy_now_position'] = in_array( $input['buy_now_position'] ?? '', array( 'after_cart', 'before_cart' ), true )
			? $input['buy_now_position']
			: 'after_cart';
		$clean['buy_now_on_loop']    = ! empty( $input['buy_now_on_loop'] );
		$clean['buy_now_clear_cart'] = ! empty( $input['buy_now_clear_cart'] );
		$clean['hide_add_to_cart']   = ! empty( $input['hide_add_to_cart'] );
		return $clean;
	}

	/**
	 * @param array $input
	 * @param array $clean
	 * @return array
	 */
	private function sanitize_button_style( $input, $clean ) {
		$allowed_weights = array( '', '400', '500', '600', '700' );
		$allowed_widths  = array( '', 'auto', 'fit-content', 'full', 'custom' );

		foreach ( array( 'single', 'loop' ) as $ctx ) {
			$p = "btn_{$ctx}_";

			$clean["{$p}bg"]                 = sanitize_hex_color( $input["{$p}bg"] ?? '' ) ?? '';
			$clean["{$p}bg_hover"]           = sanitize_hex_color( $input["{$p}bg_hover"] ?? '' ) ?? '';
			$clean["{$p}color"]              = sanitize_hex_color( $input["{$p}color"] ?? '' ) ?? '';
			$clean["{$p}color_hover"]        = sanitize_hex_color( $input["{$p}color_hover"] ?? '' ) ?? '';
			$clean["{$p}border_color"]       = sanitize_hex_color( $input["{$p}border_color"] ?? '' ) ?? '';
			$clean["{$p}border_color_hover"] = sanitize_hex_color( $input["{$p}border_color_hover"] ?? '' ) ?? '';

			$clean["{$p}border_width"]  = '' !== ( $input["{$p}border_width"] ?? '' )  ? absint( $input["{$p}border_width"] )  : '';
			$clean["{$p}border_radius"] = '' !== ( $input["{$p}border_radius"] ?? '' ) ? absint( $input["{$p}border_radius"] ) : '';
			$clean["{$p}font_size"]     = '' !== ( $input["{$p}font_size"] ?? '' )     ? absint( $input["{$p}font_size"] )     : '';
			$clean["{$p}padding_y"]     = '' !== ( $input["{$p}padding_y"] ?? '' )     ? absint( $input["{$p}padding_y"] )     : '';
			$clean["{$p}padding_x"]     = '' !== ( $input["{$p}padding_x"] ?? '' )     ? absint( $input["{$p}padding_x"] )     : '';

			$clean["{$p}font_weight"]  = in_array( $input["{$p}font_weight"] ?? '', $allowed_weights, true )
				? $input["{$p}font_weight"]
				: '';
			$clean["{$p}width"]        = in_array( $input["{$p}width"] ?? '', $allowed_widths, true )
				? $input["{$p}width"]
				: '';
			$clean["{$p}width_custom"] = self::sanitize_css_dimension( $input["{$p}width_custom"] ?? '' );
		}

		return $clean;
	}

	/**
	 * Sanitize a CSS dimension value (e.g. 200px, 50%, 2rem).
	 *
	 * @param string $value Raw value.
	 * @return string Sanitized value or empty string if invalid.
	 */
	private static function sanitize_css_dimension( $value ) {
		$value = trim( sanitize_text_field( $value ) );
		if ( '' === $value ) {
			return '';
		}
		if ( preg_match( '/^[\d.]+(px|em|rem|%|vh|vw|vmin|vmax|ch|ex|cm|mm|in|pt|pc)?$/i', $value ) ) {
			return $value;
		}
		return '';
	}

	/**
	 * Add "Settings" link on the plugins list page.
	 *
	 * @param array $links Existing action links.
	 * @return array
	 */
	public function add_settings_link( $links ) {
		$settings_link = '<a href="' . esc_url( admin_url( 'admin.php?page=tukiflow' ) ) . '">' . __( 'Settings', 'tukiflow-direct-checkout-woocommerce' ) . '</a>';
		array_unshift( $links, $settings_link );
		return $links;
	}
}
