<?php
/**
 * Product-level readiness fields.
 *
 * @package CertaCart_EU_Product_Readiness
 */

namespace CertaCart\EU_Product_Readiness;

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

final class Product_Fields {
	private static ?Product_Fields $instance = null;

	public static function instance(): Product_Fields {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	public function register(): void {
		add_filter( 'woocommerce_product_data_tabs', array( $this, 'add_tab' ) );
		add_action( 'woocommerce_product_data_panels', array( $this, 'render_panel' ) );
		add_action( 'woocommerce_admin_process_product_object', array( $this, 'save' ) );
	}

	public function add_tab( array $tabs ): array {
		$tabs['ccpr_readiness'] = array(
			'label'    => __( 'EU product information', 'certacart-eu-product-readiness' ),
			'target'   => 'ccpr_product_data',
			'class'    => array( 'show_if_simple', 'show_if_variable', 'show_if_external', 'show_if_grouped' ),
			'priority' => 82,
		);
		return $tabs;
	}

	public function render_panel(): void {
		global $post;
		$product = $post ? wc_get_product( $post->ID ) : false;
		if ( ! $product ) {
			return;
		}
		$prefix = Rules::META_PREFIX;
		$evaluation = Rules::evaluate( $product, Settings::all() );
		$requested_task = isset( $_GET['ccpr_task'] ) ? sanitize_key( wp_unslash( $_GET['ccpr_task'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only task context from the report link.
		?>
		<div id="ccpr_product_data" class="panel woocommerce_options_panel hidden">
			<?php wp_nonce_field( 'ccpr_save_product_fields', 'ccpr_product_fields_nonce' ); ?>
			<div class="options_group ccpr-product-summary">
				<p class="form-field"><strong><?php esc_html_e( 'Product information readiness', 'certacart-eu-product-readiness' ); ?></strong><span class="ccpr-product-score"><?php echo ! empty( $evaluation['in_scope'] ) ? esc_html( number_format_i18n( (float) $evaluation['score'], 1 ) . '%' ) : esc_html__( 'Outside EU scope', 'certacart-eu-product-readiness' ); ?></span></p>
				<?php /* translators: %s: number of product issues. */ ?>
				<?php if ( ! empty( $evaluation['in_scope'] ) ) : ?><p class="form-field ccpr-product-summary-copy"><?php echo (int) $evaluation['critical'] + (int) $evaluation['warning'] > 0 ? esc_html( sprintf( _n( '%s item needs attention.', '%s items need attention.', (int) $evaluation['critical'] + (int) $evaluation['warning'], 'certacart-eu-product-readiness' ), number_format_i18n( (int) $evaluation['critical'] + (int) $evaluation['warning'] ) ) ) : esc_html__( 'All supported product checks are complete.', 'certacart-eu-product-readiness' ); ?></p><?php endif; ?>
			</div>
			<details class="ccpr-product-section" <?php echo 'storefront_display_disabled' === $requested_task ? 'open' : ''; ?>>
				<summary><?php esc_html_e( 'Scope and display', 'certacart-eu-product-readiness' ); ?></summary>
			<div class="options_group">
				<?php
				woocommerce_wp_select(
					array(
						'id'          => $prefix . 'targets_eu',
						'label'       => __( 'Offered to EU consumers', 'certacart-eu-product-readiness' ),
						'value'       => $product->get_meta( $prefix . 'targets_eu', true ),
						'options'     => array(
							'inherit' => __( 'Use store default', 'certacart-eu-product-readiness' ),
							'yes'     => __( 'Yes', 'certacart-eu-product-readiness' ),
							'no'      => __( 'No', 'certacart-eu-product-readiness' ),
						),
						'description' => __( 'Use No only when this product is not directed to EU consumers.', 'certacart-eu-product-readiness' ),
						'desc_tip'    => true,
					)
				);
				woocommerce_wp_select(
					array(
						'id'      => $prefix . 'display_information',
						'label'   => __( 'Storefront display', 'certacart-eu-product-readiness' ),
						'value'   => $product->get_meta( $prefix . 'display_information', true ),
						'options' => array(
							'inherit' => __( 'Use store default', 'certacart-eu-product-readiness' ),
							'yes'     => __( 'Show', 'certacart-eu-product-readiness' ),
							'no'      => __( 'Hide', 'certacart-eu-product-readiness' ),
						),
					)
				);
				?>
			</div>
			</details>

			<details class="ccpr-product-section" <?php echo in_array( $requested_task, array( 'manufacturer_details', 'manufacturer_location_unknown' ), true ) ? 'open' : ''; ?>>
				<summary><?php esc_html_e( 'Manufacturer', 'certacart-eu-product-readiness' ); ?></summary>
			<div class="options_group">
				<?php
				$this->text( $product, 'manufacturer_name', __( 'Name / trade name', 'certacart-eu-product-readiness' ) );
				$this->textarea( $product, 'manufacturer_address', __( 'Postal address', 'certacart-eu-product-readiness' ) );
				$this->text( $product, 'manufacturer_email', __( 'Email address', 'certacart-eu-product-readiness' ), 'email' );
				$this->text( $product, 'manufacturer_url', __( 'Website / electronic address', 'certacart-eu-product-readiness' ), 'url' );
				woocommerce_wp_select(
					array(
						'id'      => $prefix . 'manufacturer_in_eu',
						'label'   => __( 'Established in the EU', 'certacart-eu-product-readiness' ),
						'value'   => $product->get_meta( $prefix . 'manufacturer_in_eu', true ),
						'options' => array(
							'inherit' => __( 'Use store default', 'certacart-eu-product-readiness' ),
							'unknown' => __( 'Not confirmed', 'certacart-eu-product-readiness' ),
							'yes'     => __( 'Yes', 'certacart-eu-product-readiness' ),
							'no'      => __( 'No', 'certacart-eu-product-readiness' ),
						),
					)
				);
				?>
			</div>
			</details>

			<details class="ccpr-product-section" <?php echo 'eu_responsible_person' === $requested_task ? 'open' : ''; ?>>
				<summary><?php esc_html_e( 'EU responsible person', 'certacart-eu-product-readiness' ); ?></summary>
			<div class="options_group">
				<?php
				$this->text( $product, 'responsible_person_name', __( 'Name / trade name', 'certacart-eu-product-readiness' ) );
				$this->textarea( $product, 'responsible_person_address', __( 'Postal address', 'certacart-eu-product-readiness' ) );
				$this->text( $product, 'responsible_person_email', __( 'Email address', 'certacart-eu-product-readiness' ), 'email' );
				$this->text( $product, 'responsible_person_url', __( 'Website / electronic address', 'certacart-eu-product-readiness' ), 'url' );
				?>
			</div>
			</details>

			<details class="ccpr-product-section" <?php echo in_array( $requested_task, array( 'product_identifier_missing', 'safety_information_missing' ), true ) ? 'open' : ''; ?>>
				<summary><?php esc_html_e( 'Product identification and safety', 'certacart-eu-product-readiness' ); ?></summary>
			<div class="options_group">
				<?php
				$this->text( $product, 'product_identifier', __( 'Model, type, batch, or other identifier', 'certacart-eu-product-readiness' ), 'text', __( 'The product SKU is used as a fallback.', 'certacart-eu-product-readiness' ) );
				woocommerce_wp_select(
					array(
						'id'      => $prefix . 'safety_state',
						'label'   => __( 'Safety information status', 'certacart-eu-product-readiness' ),
						'value'   => $product->get_meta( $prefix . 'safety_state', true ),
						'options' => array(
							'unreviewed'     => __( 'Not reviewed', 'certacart-eu-product-readiness' ),
							'provided'       => __( 'Provided below', 'certacart-eu-product-readiness' ),
							'not_applicable' => __( 'Not needed for this product', 'certacart-eu-product-readiness' ),
						),
					)
				);
				$this->textarea( $product, 'safety_warning', __( 'Warnings / safety information', 'certacart-eu-product-readiness' ), __( 'Enter the consumer-facing language required for the market where the product is offered.', 'certacart-eu-product-readiness' ) );
				$this->text( $product, 'safety_information_url', __( 'Safety document URL', 'certacart-eu-product-readiness' ), 'url' );
				$this->textarea( $product, 'internal_evidence_note', __( 'Internal evidence note', 'certacart-eu-product-readiness' ), __( 'Optional internal-only note. It is never shown on the storefront.', 'certacart-eu-product-readiness' ) );
				?>
			</div>
			</details>
			<?php do_action( 'ccpr_product_data_panel', $product ); ?>
		</div>
		<?php
	}

	public function save( \WC_Product $product ): void {
		$nonce = isset( $_POST['ccpr_product_fields_nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['ccpr_product_fields_nonce'] ) ) : '';
		if ( ! wp_verify_nonce( $nonce, 'ccpr_save_product_fields' ) || ! current_user_can( 'edit_post', $product->get_id() ) ) {
			return;
		}
		// Read the verified form once. Every value is field-sanitized before storage below.
		$posted = wp_unslash( $_POST ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized

		$selects = array(
			'targets_eu'          => array( 'inherit', 'yes', 'no' ),
			'display_information' => array( 'inherit', 'yes', 'no' ),
			'manufacturer_in_eu'  => array( 'inherit', 'unknown', 'yes', 'no' ),
			'safety_state'        => array( 'unreviewed', 'provided', 'not_applicable' ),
		);
		foreach ( $selects as $key => $allowed ) {
			$name  = Rules::META_PREFIX . $key;
			$value = isset( $posted[ $name ] ) ? wc_clean( $posted[ $name ] ) : '';
			$product->update_meta_data( $name, in_array( $value, $allowed, true ) ? $value : $allowed[0] );
		}

		$text_fields = array( 'manufacturer_name', 'responsible_person_name', 'product_identifier' );
		foreach ( $text_fields as $key ) {
			$this->save_meta( $product, $posted, $key, 'sanitize_text_field' );
		}
		$textarea_fields = array( 'manufacturer_address', 'responsible_person_address', 'safety_warning', 'internal_evidence_note' );
		foreach ( $textarea_fields as $key ) {
			$this->save_meta( $product, $posted, $key, 'sanitize_textarea_field' );
		}
		$email_fields = array( 'manufacturer_email', 'responsible_person_email' );
		foreach ( $email_fields as $key ) {
			$this->save_email_meta( $product, $posted, $key );
		}
		$url_fields = array( 'manufacturer_url', 'responsible_person_url', 'safety_information_url' );
		foreach ( $url_fields as $key ) {
			$this->save_url_meta( $product, $posted, $key );
		}
	}


	private function save_email_meta( \WC_Product $product, array $posted, string $key ): void {
		$name = Rules::META_PREFIX . $key;
		if ( ! isset( $posted[ $name ] ) ) {
			return;
		}
		$raw   = trim( (string) $posted[ $name ] );
		$value = sanitize_email( $raw );
		if ( '' !== $raw && ! is_email( $value ) ) {
			self::add_validation_error( __( 'CertaCart: enter a valid email address in the product information fields.', 'certacart-eu-product-readiness' ) );
			return;
		}
		$product->update_meta_data( $name, $value );
	}

	private function save_url_meta( \WC_Product $product, array $posted, string $key ): void {
		$name = Rules::META_PREFIX . $key;
		if ( ! isset( $posted[ $name ] ) ) {
			return;
		}
		$raw   = trim( (string) $posted[ $name ] );
		$value = esc_url_raw( $raw, array( 'http', 'https' ) );
		if ( '' !== $raw && ! wp_http_validate_url( $value ) ) {
			self::add_validation_error( __( 'CertaCart: enter a valid HTTP(S) URL in the product information fields.', 'certacart-eu-product-readiness' ) );
			return;
		}
		$product->update_meta_data( $name, $value );
	}

	private static function add_validation_error( string $message ): void {
		if ( class_exists( '\\WC_Admin_Meta_Boxes' ) ) {
			\WC_Admin_Meta_Boxes::add_error( $message );
		}
	}

	private function save_meta( \WC_Product $product, array $posted, string $key, callable $sanitizer ): void {
		$name = Rules::META_PREFIX . $key;
		if ( ! isset( $posted[ $name ] ) ) {
			return;
		}
		$value = $sanitizer( $posted[ $name ] );
		$product->update_meta_data( $name, $value );
	}

	private function text( \WC_Product $product, string $key, string $label, string $type = 'text', string $description = '' ): void {
		woocommerce_wp_text_input(
			array(
				'id'          => Rules::META_PREFIX . $key,
				'label'       => $label,
				'value'       => $product->get_meta( Rules::META_PREFIX . $key, true ),
				'type'        => $type,
				'description' => $description,
				'desc_tip'    => '' !== $description,
			)
		);
	}

	private function textarea( \WC_Product $product, string $key, string $label, string $description = '' ): void {
		woocommerce_wp_textarea_input(
			array(
				'id'          => Rules::META_PREFIX . $key,
				'label'       => $label,
				'value'       => $product->get_meta( Rules::META_PREFIX . $key, true ),
				'description' => $description,
				'desc_tip'    => '' !== $description,
				'rows'        => 3,
			)
		);
	}
}
