<?php
/**
 * Product Fields Feature
 *
 * @package DokanKits\Features\Product
 */

namespace DokanKits\Features\Product;

use DokanKits\Features\Feature;

/**
 * Product Fields Visibility Feature
 *
 * Controls the visibility of core product fields in the Dokan edit product form.
 * This feature allows site administrators to hide specific product fields in the
 * edit form for vendors, simplifying the UI and focusing vendors on essential fields.
 *
 * @since   3.0.0
 * @package DokanKits\Features\Product
 */
class ProductFields extends Feature {

	/**
	 * Feature settings group for admin UI organization
	 *
	 * @since 3.0.0
	 * @var string
	 */
	protected string $settings_group = 'product';

	/**
	 * Feature settings section within the group
	 *
	 * @since 3.0.0
	 * @var string
	 */
	protected string $settings_section = 'fields';

	/**
	 * Fields configuration with their option keys and CSS selectors
	 *
	 * @since 3.0.0
	 * @var array
	 */
	protected array $fields = array(
		'short_description'   => array(
			'option'   => 'remove_short_description_checkbox',
			'selector' => '.dokan-product-short-description',
		),
		'long_description'    => array(
			'option'   => 'remove_long_description_checkbox',
			'selector' => '.dokan-product-description',
		),
		'inventory'           => array(
			'option'   => 'remove_inventory_section_checkbox',
			'selector' => '.dokan-product-inventory',
		),
		'geolocation'         => array(
			'option'   => 'remove_geolocation_option_checkbox',
			'selector' => '.dokan-geolocation-options',
		),
		'shipping_tax'        => array(
			'option'   => 'remove_shipping_tax_option_checkbox',
			'selector' => '.dokan-product-shipping-tax',
		),
		'linked_product'      => array(
			'option'   => 'remove_linked_product_checkbox',
			'selector' => '.dokan-linked-product-options',
		),
		'attribute_variation' => array(
			'option'   => 'remove_attribute_variation_checkbox',
			'selector' => '.dokan-attribute-variation-options',
		),
		'downloadable'        => array(
			'option'   => 'remove_downloadable_checkbox',
			'selector' => '.dokan-product-type-container .downloadable-checkbox',
		),
		'virtual'             => array(
			'option'   => 'remove_virtual_checkbox',
			'selector' => '.dokan-product-type-container .virtual-checkbox',
		),
	);

	/**
	 * Constructor
	 *
	 * Initialize fields configuration with option keys and selectors
	 *
	 * @since 3.0.0
	 */
	public function __construct() {
		$this->total_features = count( $this->fields );
	}

	/**
	 * Register hooks
	 *
	 * Sets up the necessary actions to hide product fields in the admin
	 * and frontend product edit forms when enabled.
	 *
	 * @since 3.0.0
	 * @return void
	 */
	public function register_hooks(): void {
		add_action( 'wp_head', array( $this, 'add_css' ) );
		add_action( 'admin_head', array( $this, 'add_css' ) );
	}

	/**
	 * Check if any field visibility setting is enabled
	 *
	 * Overrides the parent is_enabled() method to check if any individual
	 * field setting is enabled, rather than using a single option key.
	 *
	 * @since 3.0.0
	 * @return bool Whether any field should be hidden.
	 */
	public function is_enabled(): bool {
		foreach ( $this->fields as $field ) {
			if ( $this->is_field_hidden( $field['option'] ) ) {
				return true;
			}
		}

		return false;
	}

	/**
	 * Get active feature count
	 *
	 * Returns the number of active features within this feature class.
	 * For CartButtons, this checks if the main feature is enabled.
	 *
	 * @since 3.0.0
	 * @return int
	 */
	public function get_active_features_count(): int {
		$count = 0;

		foreach ( $this->fields as $field ) {
			if ( $this->is_field_hidden( $field['option'] ) ) {
				++$count;
			}
		}

		return $count;
	}

	/**
	 * Check if a specific field should be hidden
	 *
	 * @since 3.0.0
	 * @param string $option_key The option key to check.
	 * @return bool Whether the field should be hidden.
	 */
	protected function is_field_hidden( string $option_key ): bool {
		return wc_string_to_bool( $this->get_setting( $option_key, false ) );
	}

	/**
	 * Add CSS to hide selected product fields
	 *
	 * Outputs inline CSS in the head of the document to hide the specified
	 * product fields from the Dokan product edit form.
	 *
	 * @since 3.0.0
	 * @return void
	 */
	public function add_css(): void {
		if ( ! $this->is_enabled() ) {
			return;
		}

		// Skip for admin area except product edit page.
		if ( is_admin() && ! $this->is_product_edit_page() ) {
			return;
		}

		$css = $this->get_field_css();

		if ( ! empty( $css ) ) {
			printf(
				'<style type="text/css" id="dokan-kits-%2$s-%3$s">%1$s</style>',
				esc_html( $css ),
				esc_attr( $this->get_settings_group() ),
				esc_attr( $this->get_settings_section() )
			);
		}
	}

	/**
	 * Check if current page is product edit
	 *
	 * @since 3.0.0
	 * @return bool Whether we're on a product edit page.
	 */
	protected function is_product_edit_page(): bool {
		global $pagenow, $post_type;

		return ( in_array( $pagenow, array( 'post.php', 'post-new.php' ), true ) && 'product' === $post_type );
	}

	/**
	 * Generate CSS to hide selected product fields
	 *
	 * Creates CSS rules to hide the fields that have been selected for removal
	 * in the settings.
	 *
	 * @since 3.0.0
	 * @return string CSS rules.
	 */
	protected function get_field_css(): string {
		$css = '';

		foreach ( $this->fields as $field ) {
			if ( $this->is_field_hidden( $field['option'] ) ) {
				$css .= '.dokan-product-edit-form ' . esc_html( $field['selector'] ) . ' { display: none !important; }';
			}
		}

		return $css;
	}
}
