<?php
namespace WPDRMS\ASP\Compatibility;

use WPDRMS\ASP\Compatibility\ORM\CompatibilityOptions;

final class CompatibilityMigration {
	public static function run(): void {
		self::migrateFromLegacyFlat();
	}

	private static function migrateFromLegacyFlat(): void {
		$old = get_option( 'asp_compatibility', false );
		if ( $old === false || get_site_option( 'asp_compatibility_options', false ) !== false ) {
			return;
		}

		if ( ! is_array( $old ) ) {
			$old = array();
		}

		$old = self::decodeLegacyOptions( $old );

		$new_args = array(
			'selective_exin'                 => array( 'value' => self::commaSplit( $old['selective_exin'] ?? '' ) ),
			'meta_box_post_types'            => array( 'value' => self::pipeSplit( $old['meta_box_post_types'] ?? 'post|page|product' ) ),
			'css_compatibility_level'        => array( 'value' => (string) ( $old['css_compatibility_level'] ?? 'medium' ) ),
			'js_source'                      => array( 'value' => (string) ( $old['js_source'] ?? 'jqueryless-min' ) ),
			'script_loading_method'          => array( 'value' => (string) ( $old['script_loading_method'] ?? 'optimized' ) ),
			'css_loading_method'             => array( 'value' => (string) ( $old['css_loading_method'] ?? 'optimized' ) ),
			'selective_exin_logic'           => array( 'value' => (string) ( $old['selective_exin_logic'] ?? 'exclude' ) ),
			'db_force_case'                  => array( 'value' => (string) ( $old['db_force_case'] ?? 'none' ) ),
			'js_prevent_body_scroll'         => array( 'value' => (bool) ( $old['js_prevent_body_scroll'] ?? false ) ),
			'detect_ajax'                    => array( 'value' => (bool) ( $old['detect_ajax'] ?? true ) ),
			'css_minify'                     => array( 'value' => (bool) ( $old['css_minify'] ?? true ) ),
			'load_google_fonts'              => array( 'value' => (bool) ( $old['load_google_fonts'] ?? true ) ),
			'usecustomajaxhandler'           => array( 'value' => (bool) ( $old['usecustomajaxhandler'] ?? false ) ),
			'init_instances_inviewport_only' => array( 'value' => (bool) ( $old['init_instances_inviewport_only'] ?? true ) ),
			'selective_enabled'              => array( 'value' => (bool) ( $old['selective_enabled'] ?? false ) ),
			'selective_front'                => array( 'value' => (bool) ( $old['selective_front'] ?? true ) ),
			'selective_archive'              => array( 'value' => (bool) ( $old['selective_archive'] ?? true ) ),
			'query_soft_check'               => array( 'value' => (bool) ( $old['query_soft_check'] ?? false ) ),
			'use_acf_getfield'               => array( 'value' => (bool) ( $old['use_acf_getfield'] ?? true ) ),
			'db_force_unicode'               => array( 'value' => (bool) ( $old['db_force_unicode'] ?? false ) ),
			'db_force_utf8_like'             => array( 'value' => (bool) ( $old['db_force_utf8_like'] ?? false ) ),
			'rest_api_enabled'               => array( 'value' => (bool) ( $old['rest_api_enabled'] ?? false ) ),
		);

		CompatibilityOptions::instance()->setArgs( $new_args, false )->save();
	}

	/**
	 * Decodes any _decode_ prefixed values in the legacy option array,
	 * mirroring what asp_decode_params() does when loading options into memory.
	 *
	 * @param array<string, mixed> $old
	 * @return array<string, mixed>
	 */
	private static function decodeLegacyOptions( array $old ): array {
		foreach ( $old as $k => $v ) {
			if ( is_string( $v ) && substr( $v, 0, 8 ) === '_decode_' ) {
				$decoded = json_decode( base64_decode( substr( $v, 8 ) ), true );
				if ( $decoded !== null ) {
					$old[ $k ] = $decoded;
				}
			}
		}
		return $old;
	}

	/**
	 * @param string|array<string> $value
	 * @return array<string>
	 */
	private static function commaSplit( $value ): array {
		if ( is_array( $value ) ) {
			return array_values( array_filter( array_map( 'strval', $value ) ) );
		}
		$value = (string) $value;
		if ( $value === '' ) {
			return array();
		}
		return array_values( array_filter( array_map( 'trim', explode( ',', $value ) ) ) );
	}

	/**
	 * @param string|array<string> $value
	 * @return array<string>
	 */
	private static function pipeSplit( $value ): array {
		if ( is_array( $value ) ) {
			return array_values( array_filter( array_map( 'strval', $value ) ) );
		}
		$value = (string) $value;
		if ( $value === '' ) {
			return array();
		}
		return array_values( array_filter( array_map( 'trim', explode( '|', $value ) ) ) );
	}
}
