<?php
/**
 * Migrate_Old_Settings Migration Class
 *
 * @since   3.0.0
 * @package DokanKits\Setup\Migrations
 */

namespace DokanKits\Setup\Migrations\V300;

use DokanKits\Core\Data\Models\Settings;
use DokanKits\Core\Data\Stores\SettingsDataStore;
use DokanKits\Setup\Migrations\Migration;

/**
 * Class Migrate_Old_Settings
 *
 * Handles migration of old settings to new data model.
 *
 * @since 3.0.0
 */
class MigrateOldSettings extends Migration {

	/**
	 * Constructor.
	 */
	public function __construct() {
		parent::__construct(
			'3.0.0',
			'migrate_old_settings',
			'data_migration'
		);
	}

	/**
	 * Run the migration.
	 *
	 * @param string $version Version being migrated to.
	 *
	 * @return void
	 * @throws \Exception If migration fails.
	 */
	public function migrate( string $version ): void {
		$old_settings_map = $this->get_old_settings_map();

		// Flag to track if any changes were made.
		$settings_updated = false;

		// Migrate settings for each category.
		foreach ( $old_settings_map as $category => $sections ) {
			// Get the settings for this category using data store.
			$settings_store = dokan_kits_get_container()->get( SettingsDataStore::class );
			$settings       = $settings_store->get_settings_by_name( $category );

			// If settings don't exist, create them.
			if ( ! $settings instanceof Settings ) {
				$settings = dokan_kits_get_container()->get( Settings::class );
				$settings->set_name( $category );
				$settings->set_value( array() );
			}

			// Get current values.
			$current_values = $settings->get_value();
			if ( ! is_array( $current_values ) ) {
				$current_values = array();
			}

			$has_updates = false;

			// Process each section within the category.
			foreach ( $sections as $section_name => $option_keys ) {
				// Initialize section if it doesn't exist.
				if ( ! isset( $current_values[ $section_name ] ) ) {
					$current_values[ $section_name ] = array();
				}

				// Migrate each option within the section.
				foreach ( $option_keys as $new_key => $old_key ) {
					$old_value = get_option( $old_key, null );

					// Only update if old value exists and new key doesn't already exist.
					if ( null !== $old_value && ! isset( $current_values[ $section_name ][ $new_key ] ) ) {
						// Convert old value to appropriate format.
						$migrated_value = $this->convert_old_value( $old_value );

						$current_values[ $section_name ][ $new_key ] = $migrated_value;
						$has_updates                                 = true;
						$settings_updated                            = true;

						// Log the migration for debugging.
						if ( function_exists( 'dokan_kits_logger' ) ) {
							dokan_kits_logger()->info(
								sprintf(
									'Migrated setting: %s.%s.%s = %s (from %s)',
									$category,
									$section_name,
									$new_key,
									wp_json_encode( $migrated_value ),
									$old_key
								)
							);
						}

						// Delete the old option after successful migration.
						delete_option( $old_key );
					}
				}
			}

			// Save if changes were made.
			if ( $has_updates ) {
				$settings->set_value( $current_values );
				$settings->save();
			}
		}

		// Delete the old version option.
		delete_option( 'dokan_kits_version' );

		/**
		 * Action fired after migrating old settings to new model.
		 *
		 * @since 3.0.0
		 *
		 * @param string $version          Migration version.
		 * @param bool   $settings_updated Whether any settings were updated.
		 */
		do_action( 'dokan_kits_after_migrate_old_settings', $version, $settings_updated );
	}

	/**
	 * Convert old option value to new format.
	 *
	 * @param mixed $old_value The old option value.
	 *
	 * @return mixed Converted value.
	 */
	private function convert_old_value( $old_value ) {
		// Handle numeric values.
		if ( is_numeric( $old_value ) ) {
			$numeric_value = (float) $old_value;

			// If it's a whole number greater than 1, keep as number.
			if ( $numeric_value > 1 && (float) (int) $numeric_value === $numeric_value ) {
				return (int) $numeric_value;
			}

			// If it's a decimal, keep as float.
			if ( (float) (int) $numeric_value !== $numeric_value ) {
				return $numeric_value;
			}

			// Convert 1/0 to boolean.
			return 1 === (int) $numeric_value;
		}

		// Handle string boolean values.
		if ( is_string( $old_value ) ) {
			if ( in_array( $old_value, array( '1', 'true', 'yes', 'on' ), true ) ) {
				return true;
			}

			if ( in_array( $old_value, array( '0', 'false', 'no', 'off', '' ), true ) ) {
				return false;
			}
		}

		// Return as-is for other types.
		return $old_value;
	}

	/**
	 * Get mapping of old settings to new structured format.
	 *
	 * Maps old WordPress options to new nested settings structure.
	 * Format: category => section => new_key => old_option_name
	 *
	 * @return array Old settings map with nested structure.
	 */
	private function get_old_settings_map(): array {
		return array(
			'vendor'   => array(
				'registration' => array(
					'remove_vendor_checkbox'               => 'remove_vendor_checkbox',
					'set_default_seller_role_checkbox'     => 'set_default_seller_role_checkbox',
					'remove_become_a_vendor_button_checkbox' => 'remove_become_a_vendor_button_checkbox',
					'enable_own_product_purchase_checkbox' => 'enable_own_product_purchase_checkbox',
				),
			),
			'product'  => array(
				'types'        => array(
					'remove_simple_product_checkbox'   => 'remove_simple_product_checkbox',
					'remove_variable_product_checkbox' => 'remove_variable_product_checkbox',
					'remove_external_product_checkbox' => 'remove_external_product_checkbox',
					'remove_grouped_product_checkbox'  => 'remove_grouped_product_checkbox',
				),
				'fields'       => array(
					'remove_short_description_checkbox'   => 'remove_short_description_checkbox',
					'remove_long_description_checkbox'    => 'remove_long_description_checkbox',
					'remove_inventory_section_checkbox'   => 'remove_inventory_section_checkbox',
					'remove_downloadable_checkbox'        => 'remove_downloadable_checkbox',
					'remove_virtual_checkbox'             => 'remove_virtual_checkbox',
					'remove_linked_product_checkbox'      => 'remove_linked_product_checkbox',
					'remove_attribute_variation_checkbox' => 'remove_attribute_variation_checkbox',
					'remove_shipping_tax_option_checkbox' => 'remove_shipping_tax_option_checkbox',
					'remove_geolocation_option_checkbox'  => 'remove_geolocation_option_checkbox',
				),
				'pro_features' => array(
					'remove_bulk_discount_checkbox'   => 'remove_bulk_discount_checkbox',
					'remove_rma_checkbox'             => 'remove_rma_checkbox',
					'remove_wholesale_checkbox'       => 'remove_wholesale_checkbox',
					'remove_min_max_product_checkbox' => 'remove_min_max_product_checkbox',
					'remove_other_options_checkbox'   => 'remove_other_options_checkbox',
					'remove_product_advertisement_checkbox' => 'remove_product_advertisement_checkbox',
				),
				'images'       => array(
					'show_image_requirements_notice_checkbox' => 'show_image_requirements_notice_checkbox',
					'enable_dimension_restrictions' => 'enable_dimension_restrictions',
					'enable_size_restrictions'      => 'enable_size_restrictions',
					'image_max_width'               => 'image_max_width',
					'image_max_height'              => 'image_max_height',
					'image_max_size'                => 'image_max_size',
				),
			),
			'shipping' => array(
				'order_management' => array(
					'auto_complete_order_checkbox' => 'auto_complete_order_checkbox',
				),
				'split_shipping'   => array(
					'remove_split_shipping_checkbox'     => 'remove_split_shipping_checkbox',
					'remove_split_shipping_pro_checkbox' => 'remove_split_shipping_pro_checkbox',
				),
			),
			'cart'     => array(
				'buttons' => array(
					'hide_add_to_cart_button_checkbox' => 'hide_add_to_cart_button_checkbox',
				),
			),
		);
	}
}
