<?php
/**
 * Google Merchant Feed Settings
 *
 * Manages global settings for Google Merchant Feed generation.
 *
 * @package GGM_Commerce
 * @since 1.0.0
 */

defined( 'ABSPATH' ) || exit;

/**
 * Class GGM_Commerce_Google_Merchant_Settings
 *
 * Handles global settings for Google Merchant feeds.
 */
class GGM_Commerce_Google_Merchant_Settings {

	/**
	 * Option name for settings storage.
	 */
	const OPTION_NAME = 'ggm_commerce_google_merchant_settings';

	/**
	 * Singleton instance.
	 *
	 * @var GGM_Commerce_Google_Merchant_Settings|null
	 */
	private static $instance = null;

	/**
	 * Cached settings.
	 *
	 * @var array|null
	 */
	private $settings = null;

	/**
	 * Default settings.
	 *
	 * @var array
	 */
	private $defaults = array(
		'default_brand'          => '',
		'brand_attribute_id'     => 0,
		'default_condition'      => 'new',
		'include_variations'     => true,
		'id_format'              => 'sku', // 'sku' or 'id'.
		'description_field'      => 'description', // 'description' or 'short_description'.
		'currency'               => 'USD',
		'include_tax_in_price'   => false,
		'shipping_country'       => '',
		'shipping_price'         => '',
		'gtin_barcode_type'      => 'EAN-13', // Barcode type to use for GTIN.
		'mpn_source'             => 'sku', // 'sku' or attribute ID.
	);

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

	/**
	 * Private constructor for singleton.
	 */
	private function __construct() {}

	/**
	 * Get all settings.
	 *
	 * @return array
	 */
	public function get_settings() {
		if ( null === $this->settings ) {
			$saved          = get_option( self::OPTION_NAME, array() );
			$this->settings = wp_parse_args( $saved, $this->defaults );
		}
		return $this->settings;
	}

	/**
	 * Get a single setting.
	 *
	 * @param string $key     Setting key.
	 * @param mixed  $default Default value if not set.
	 * @return mixed
	 */
	public function get( $key, $default = null ) {
		$settings = $this->get_settings();
		if ( array_key_exists( $key, $settings ) ) {
			return $settings[ $key ];
		}
		return $default ?? ( $this->defaults[ $key ] ?? null );
	}

	/**
	 * Save settings.
	 *
	 * @param array $settings Settings to save.
	 * @return bool
	 */
	public function save( $settings ) {
		$sanitized = $this->sanitize_settings( $settings );
		$result    = update_option( self::OPTION_NAME, $sanitized );

		// Clear cache.
		$this->settings = null;

		return $result;
	}

	/**
	 * Update a single setting.
	 *
	 * @param string $key   Setting key.
	 * @param mixed  $value Setting value.
	 * @return bool
	 */
	public function set( $key, $value ) {
		$settings         = $this->get_settings();
		$settings[ $key ] = $value;
		return $this->save( $settings );
	}

	/**
	 * Sanitize settings before saving.
	 *
	 * @param array $settings Raw settings.
	 * @return array Sanitized settings.
	 */
	private function sanitize_settings( $settings ) {
		$sanitized = array();

		if ( isset( $settings['default_brand'] ) ) {
			$sanitized['default_brand'] = sanitize_text_field( $settings['default_brand'] );
		}

		if ( isset( $settings['brand_attribute_id'] ) ) {
			$sanitized['brand_attribute_id'] = absint( $settings['brand_attribute_id'] );
		}

		if ( isset( $settings['default_condition'] ) ) {
			$valid_conditions              = array( 'new', 'refurbished', 'used' );
			$sanitized['default_condition'] = in_array( $settings['default_condition'], $valid_conditions, true )
				? $settings['default_condition']
				: 'new';
		}

		if ( isset( $settings['include_variations'] ) ) {
			$sanitized['include_variations'] = (bool) $settings['include_variations'];
		}

		if ( isset( $settings['id_format'] ) ) {
			$sanitized['id_format'] = in_array( $settings['id_format'], array( 'sku', 'id' ), true )
				? $settings['id_format']
				: 'sku';
		}

		if ( isset( $settings['description_field'] ) ) {
			$sanitized['description_field'] = in_array( $settings['description_field'], array( 'description', 'short_description' ), true )
				? $settings['description_field']
				: 'description';
		}

		if ( isset( $settings['currency'] ) ) {
			$sanitized['currency'] = strtoupper( sanitize_text_field( $settings['currency'] ) );
		}

		if ( isset( $settings['include_tax_in_price'] ) ) {
			$sanitized['include_tax_in_price'] = (bool) $settings['include_tax_in_price'];
		}

		if ( isset( $settings['shipping_country'] ) ) {
			$sanitized['shipping_country'] = sanitize_text_field( $settings['shipping_country'] );
		}

		if ( isset( $settings['shipping_price'] ) ) {
			$sanitized['shipping_price'] = sanitize_text_field( $settings['shipping_price'] );
		}

		if ( isset( $settings['gtin_barcode_type'] ) ) {
			$sanitized['gtin_barcode_type'] = sanitize_text_field( $settings['gtin_barcode_type'] );
		}

		if ( isset( $settings['mpn_source'] ) ) {
			$sanitized['mpn_source'] = sanitize_text_field( $settings['mpn_source'] );
		}

		return $sanitized;
	}

	/**
	 * Get available condition options.
	 *
	 * @return array
	 */
	public function get_condition_options() {
		return array(
			'new'         => __( 'New', 'ggm-commerce' ),
			'refurbished' => __( 'Refurbished', 'ggm-commerce' ),
			'used'        => __( 'Used', 'ggm-commerce' ),
		);
	}

	/**
	 * Get available ID format options.
	 *
	 * @return array
	 */
	public function get_id_format_options() {
		return array(
			'sku' => __( 'Product SKU', 'ggm-commerce' ),
			'id'  => __( 'Product ID', 'ggm-commerce' ),
		);
	}

	/**
	 * Get available description field options.
	 *
	 * @return array
	 */
	public function get_description_field_options() {
		return array(
			'description'       => __( 'Full Description', 'ggm-commerce' ),
			'short_description' => __( 'Short Description', 'ggm-commerce' ),
		);
	}

	/**
	 * Reset settings to defaults.
	 *
	 * @return bool
	 */
	public function reset() {
		$this->settings = null;
		return delete_option( self::OPTION_NAME );
	}
}
