<?php
/**
 * Settings registration and access.
 *
 * @package CertaCart_EU_Product_Readiness
 */

namespace CertaCart\EU_Product_Readiness;

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

final class Settings {
	private static ?Settings $instance = null;
	public const OPTION = 'ccpr_settings';

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

	public static function defaults(): array {
		return array(
			'default_targets_eu'           => 'review',
			'default_manufacturer_in_eu'  => 'unknown',
			'display_product_information' => 'yes',
			'display_position'            => 'after_meta',
			'section_heading'             => __( 'Product safety and economic operator information', 'certacart-eu-product-readiness' ),
			'notice_scope'                => 'review',
			'notice_enabled'              => 'no',
			'notice_attachment_id'        => 0,
			'notice_link_url'             => '',
			'notice_alt_text'             => __( 'EU legal guarantee information', 'certacart-eu-product-readiness' ),
			'retention_scans'             => 10,
			'delete_data_on_uninstall'    => 'no',
			'batch_size'                  => 1000,
		);
	}

	public static function seed_defaults(): void {
		if ( false === get_option( self::OPTION, false ) ) {
			add_option( self::OPTION, self::defaults(), '', false );
		}
	}

	public function register(): void {
		add_action( 'admin_init', array( $this, 'register_setting' ) );
	}

	public function register_setting(): void {
		register_setting(
			'ccpr_settings_group',
			self::OPTION,
			array(
				'type'              => 'array',
				'sanitize_callback' => array( $this, 'sanitize' ),
				'default'           => self::defaults(),
			)
		);
	}

	public function sanitize( $input ): array {
		$input    = is_array( $input ) ? $input : array();
		$defaults = self::defaults();
		$output   = array();

		$output['default_targets_eu'] = in_array( $input['default_targets_eu'] ?? '', array( 'review', 'yes', 'no' ), true ) ? $input['default_targets_eu'] : $defaults['default_targets_eu'];
		$output['default_manufacturer_in_eu'] = in_array( $input['default_manufacturer_in_eu'] ?? '', array( 'yes', 'no', 'unknown' ), true ) ? $input['default_manufacturer_in_eu'] : $defaults['default_manufacturer_in_eu'];
		$output['display_product_information'] = 'yes' === ( $input['display_product_information'] ?? '' ) ? 'yes' : 'no';
		$output['display_position'] = in_array( $input['display_position'] ?? '', array( 'after_summary', 'before_add_to_cart', 'after_meta', 'manual' ), true ) ? $input['display_position'] : $defaults['display_position'];
		$output['section_heading'] = sanitize_text_field( $input['section_heading'] ?? $defaults['section_heading'] );
		if ( '' === $output['section_heading'] ) {
			$output['section_heading'] = $defaults['section_heading'];
		}
		$output['notice_scope'] = in_array( $input['notice_scope'] ?? '', array( 'review', 'configured', 'not_applicable' ), true ) ? $input['notice_scope'] : $defaults['notice_scope'];
		$output['notice_enabled'] = 'yes' === ( $input['notice_enabled'] ?? '' ) ? 'yes' : 'no';
		$output['notice_attachment_id'] = absint( $input['notice_attachment_id'] ?? 0 );
		$output['notice_link_url'] = esc_url_raw( $input['notice_link_url'] ?? '', array( 'http', 'https' ) );
		$output['notice_alt_text'] = sanitize_text_field( $input['notice_alt_text'] ?? $defaults['notice_alt_text'] );
		$output['retention_scans'] = max( 1, min( 50, absint( $input['retention_scans'] ?? $defaults['retention_scans'] ) ) );
		$output['delete_data_on_uninstall'] = 'yes' === ( $input['delete_data_on_uninstall'] ?? '' ) ? 'yes' : 'no';
		$output['batch_size'] = max( 50, min( 2000, absint( $input['batch_size'] ?? $defaults['batch_size'] ) ) );
		return $output;
	}

	/**
	 * Sanitize the minimal EU scope choice accepted by a scan request.
	 *
	 * `review` deliberately means that the catalog is checked without a
	 * readiness score. It must not be silently promoted to `yes`.
	 *
	 * @param mixed $value Submitted scope value.
	 * @return string `yes`, `review`, or an empty string for invalid input.
	 */
	public static function sanitize_scan_scope( $value ): string {
		if ( ! is_string( $value ) ) {
			return '';
		}
		$value = sanitize_key( $value );
		return in_array( $value, array( 'yes', 'review' ), true ) ? $value : '';
	}

	public static function all(): array {
		$value = get_option( self::OPTION, array() );
		return wp_parse_args( is_array( $value ) ? $value : array(), self::defaults() );
	}

	public static function get( string $key, $default = null ) {
		$settings = self::all();
		return array_key_exists( $key, $settings ) ? $settings[ $key ] : $default;
	}
}
