<?php
/**
 * Settings Manager Class
 *
 * @package ShopExplorer\Admin
 * @since 1.0.0
 */

namespace SHOPEXPLORER\Admin;

use SHOPEXPLORER\Exceptions\SHOPEX_ConfigurationException;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

/**
 * Settings Manager class
 *
 * Handles settings validation, storage, and migration
 *
 * @since 1.0.0
 */
class SHOPEX_SettingsManager {

	/**
	 * Settings option prefix
	 */
	const OPTION_PREFIX = 'shopex_';

	/**
	 * Default settings
	 *
	 * @var array
	 */
	private $default_settings = [
		'database_mode_enabled' => true,
		'multivendor_enabled' => false,
		'auto_sync_enabled' => true,
		'sync_interval' => 300,
		'batch_size' => 100,
		'email_notifications' => false,
		'notification_email' => '',
		// Export/Sync Settings
		'sync_orders' => true,
		'sync_products' => true,
		'sync_customers' => false,
		'sync_success_notifications' => false,
		'sync_error_notifications' => true,
		// Bulk Edit Optimization Settings
		'bulk_edit_optimize_mode' => false,
		'bulk_edit_batch_size' => 5000,
		'bulk_edit_threshold' => 1000,
	];

	/**
	 * Constructor
	 */
	public function __construct() {
		$this->init_hooks();
	}

	/**
	 * Initialize WordPress hooks
	 */
	private function init_hooks() {
		add_action( 'admin_init', [ $this, 'register_settings' ] );
		add_action( 'update_option_' . self::OPTION_PREFIX . 'database_mode_enabled', [ $this, 'validate_mode_settings' ], 10, 2 );
	}

	/**
	 * Register all settings
	 */
	public function register_settings() {
		// General settings
		register_setting( 'shop_explorer_general', self::OPTION_PREFIX . 'database_mode_enabled', [
			'type' => 'boolean',
			'sanitize_callback' => [ $this, 'sanitize_boolean' ],
			'default' => true,
		] );

		register_setting( 'shop_explorer_general', self::OPTION_PREFIX . 'multivendor_enabled', [
			'type' => 'boolean',
			'sanitize_callback' => [ $this, 'sanitize_boolean' ],
			'default' => false,
		] );

		register_setting( 'shop_explorer_general', self::OPTION_PREFIX . 'auto_sync_enabled', [
			'type' => 'boolean',
			'sanitize_callback' => [ $this, 'sanitize_boolean' ],
			'default' => true,
		] );

		register_setting( 'shop_explorer_general', self::OPTION_PREFIX . 'sync_interval', [
			'type' => 'integer',
			'sanitize_callback' => [ $this, 'sanitize_sync_interval' ],
			'default' => 300,
		] );
	}

	/**
	 * Sanitize boolean values
	 *
	 * @param mixed $value
	 * @return bool
	 */
	public function sanitize_boolean( $value ) {
		return (bool) $value;
	}

	/**
	 * Sanitize sync interval
	 *
	 * @param mixed $value
	 * @return int
	 * @throws ConfigurationException
	 */
	public function sanitize_sync_interval( $value ) {
		$value = intval( $value );
		$allowed_intervals = [ 300, 600, 1800, 3600 ]; // 5min, 10min, 30min, 1hour

		if ( ! in_array( $value, $allowed_intervals, true ) ) {
			add_settings_error(
				'shop_explorer_sync_interval',
				'invalid_sync_interval',
				__( 'Invalid sync interval. Please select a valid option.', 'shop-explorer' )
			);
			return 300; // Default to 5 minutes
		}

		return $value;
	}

	/**
	 * Validate mode settings
	 *
	 * @param mixed $old_value
	 * @param mixed $new_value
	 */
	public function validate_mode_settings( $old_value, $new_value ) {
		$database_enabled = get_option( self::OPTION_PREFIX . 'database_mode_enabled', true );

		// Ensure database mode is enabled (since we removed Google Sheets)
		if ( ! $database_enabled ) {
			add_settings_error(
				'shop_explorer_modes',
				'database_mode_required',
				__( 'Database mode must be enabled.', 'shop-explorer' )
			);

			// Revert to database mode
			update_option( self::OPTION_PREFIX . 'database_mode_enabled', true );
		}
	}

	/**
	 * Export settings configuration
	 *
	 * @return array
	 */
	public function export_settings() {
		$settings = [];

		// Export default settings
		foreach ( $this->default_settings as $key => $default ) {
			$settings[ $key ] = get_option( self::OPTION_PREFIX . $key, $default );
		}

		// Export WooCommerce settings
		$woo_settings = get_option( 'wpnts_schedules_interval_woocommerce_settings', [] );
		if ( is_string( $woo_settings ) ) {
			$woo_settings = json_decode( $woo_settings, true );
		}
		if ( ! is_array( $woo_settings ) ) {
			$woo_settings = [];
		}

		// Add WooCommerce settings to export
		$settings['wooanalytics'] = isset( $woo_settings['wooanalytics'] ) ? $woo_settings['wooanalytics'] : false;
		$settings['incomplete_orders_tracking'] = isset( $woo_settings['incomplete_orders_tracking'] ) ? $woo_settings['incomplete_orders_tracking'] : false;
		$settings['cart_interactions_tracking'] = isset( $woo_settings['cart_interactions_tracking'] ) ? $woo_settings['cart_interactions_tracking'] : false;
		$settings['abandonment_delay_minutes'] = isset( $woo_settings['abandonment_delay_minutes'] ) ? $woo_settings['abandonment_delay_minutes'] : 5;
		$settings['cleanup_incomplete_orders_days'] = isset( $woo_settings['cleanup_incomplete_orders_days'] ) ? $woo_settings['cleanup_incomplete_orders_days'] : 30;

		return $settings;
	}

	/**
	 * Import settings configuration
	 *
	 * @param array $settings
	 * @return bool
	 * @throws ConfigurationException
	 */
	public function import_settings( array $settings ) {
		try {
			// Import default settings
			foreach ( $settings as $key => $value ) {
				if ( array_key_exists( $key, $this->default_settings ) ) {
					update_option( self::OPTION_PREFIX . $key, $value );
				}
			}

			// Import WooCommerce settings
			$woo_settings_keys = [
				'wooanalytics',
				'incomplete_orders_tracking',
				'cart_interactions_tracking',
				'abandonment_delay_minutes',
				'cleanup_incomplete_orders_days'
			];

			$current_woo_settings = get_option( 'wpnts_schedules_interval_woocommerce_settings', [] );
			if ( is_string( $current_woo_settings ) ) {
				$current_woo_settings = json_decode( $current_woo_settings, true );
			}
			if ( ! is_array( $current_woo_settings ) ) {
				$current_woo_settings = [];
			}

			$woo_settings_changed = false;
			foreach ( $woo_settings_keys as $key ) {
				if ( isset( $settings[ $key ] ) ) {
					$current_woo_settings[ $key ] = $settings[ $key ];
					$woo_settings_changed = true;
				}
			}

			if ( $woo_settings_changed ) {
				update_option( 'wpnts_schedules_interval_woocommerce_settings', wp_json_encode( $current_woo_settings ) );
			}

			// Validate imported settings
			$this->validate_configuration();

			return true;

		} catch ( \Exception $e ) {
			return false;
		}
	}

	/**
	 * Validate current configuration
	 *
	 * @return bool
	 * @throws ConfigurationException
	 */
	public function validate_configuration() {
		$errors = [];

		// Check mode settings
		$database_enabled = get_option( self::OPTION_PREFIX . 'database_mode_enabled', true );

		if ( ! $database_enabled ) {
			$errors[] = __( 'Database mode must be enabled.', 'shop-explorer' );
		}

		// Check sync interval
		$sync_interval = get_option( self::OPTION_PREFIX . 'sync_interval', 300 );
		$allowed_intervals = [ 60, 300, 600, 900, 1800, 3600, 7200 ];
		if ( ! in_array( (int) $sync_interval, $allowed_intervals, true ) ) {
			$errors[] = __( 'Invalid sync interval configured.', 'shop-explorer' );
		}

		if ( ! empty( $errors ) ) {
			return false;
		}

		return true;
	}

	/**
	 * Reset settings to defaults
	 *
	 * @return bool
	 */
	public function reset_to_defaults() {
		// Reset default settings
		foreach ( $this->default_settings as $key => $value ) {
			update_option( self::OPTION_PREFIX . $key, $value );
		}

		// Reset WooCommerce settings to defaults
		$default_woo_settings = [
			'wooanalytics' => false,
			'incomplete_orders_tracking' => false,
			'cart_interactions_tracking' => false,
			'abandonment_delay_minutes' => 5,
			'cleanup_incomplete_orders_days' => 30,
		];

		update_option( 'wpnts_schedules_interval_woocommerce_settings', wp_json_encode( $default_woo_settings ) );

		return true;
	}

	/**
	 * Get setting value with default fallback
	 *
	 * @param string $key
	 * @param mixed  $default
	 * @return mixed
	 */
	public function get_setting( $key, $default = null ) {
		$option_key = self::OPTION_PREFIX . $key;

		if ( $default === null && isset( $this->default_settings[ $key ] ) ) {
			$default = $this->default_settings[ $key ];
		}

		return get_option( $option_key, $default );
	}

	/**
	 * Update setting value
	 *
	 * @param string $key
	 * @param mixed  $value
	 * @return bool
	 */
	public function update_setting( $key, $value ) {
		$option_key = self::OPTION_PREFIX . $key;
		return update_option( $option_key, $value );
	}

	/**
	 * Delete setting
	 *
	 * @param string $key
	 * @return bool
	 */
	public function delete_setting( $key ) {
		$option_key = self::OPTION_PREFIX . $key;
		return delete_option( $option_key );
	}
}
