<?php

namespace WPDRMS\ASP\Compatibility;

use Exception;
use WP_Error;
use WP_REST_Request;
use WP_REST_Response;
use WPDRMS\ASP\Compatibility\ORM\CompatibilityOptions;
use WPDRMS\PluginCore\Rest\AbstractRest;

class CompatibilityRoute extends AbstractRest {
	public function registerRoutes( string $route_namespace ): void {
		register_rest_route(
			$route_namespace,
			'options/compatibility',
			array(
				array(
					'methods'             => 'GET',
					'callback'            => array( $this, 'getOptions' ),
					'permission_callback' => array( $this, 'allowOnlyAdmins' ),
				),
				array(
					'methods'             => 'POST',
					'callback'            => array( $this, 'saveOptions' ),
					'permission_callback' => array( $this, 'allowOnlyAdmins' ),
				),
			)
		);

		register_rest_route(
			$route_namespace,
			'options/compatibility/reset',
			array(
				'methods'             => 'POST',
				'callback'            => array( $this, 'resetOptions' ),
				'permission_callback' => array( $this, 'allowOnlyAdmins' ),
			)
		);

	}

	/** @return WP_Error|WP_REST_Response */
	public function getOptions() {
		try {
			return new WP_REST_Response(
				array(
					'options' => CompatibilityOptions::instance(),
				),
				200
			);
		} catch ( Exception $e ) {
			return new WP_Error( 'asp_compatibility_error', $e->getMessage(), array( 'status' => 500 ) );
		}
	}

	/**
	 * @param WP_REST_Request $request
	 * @return WP_Error|WP_REST_Response
	 */
	public function saveOptions( WP_REST_Request $request ) {
		try {
			$params  = $request->get_json_params();
			$options = isset( $params['options'] ) && is_array( $params['options'] ) ? $params['options'] : array();

			$orm = CompatibilityOptions::instance()->setArgs( $options )->save()->load();

			$this->syncLegacyOption( $orm );

			asp_parse_options();
			wd_asp()->css_manager->generator->generate();

			return new WP_REST_Response( array( 'success' => true ), 200 );
		} catch ( Exception $e ) {
			return new WP_Error( 'asp_compatibility_error', $e->getMessage(), array( 'status' => 500 ) );
		}
	}

	/** @return WP_Error|WP_REST_Response */
	public function resetOptions() {
		try {
			$orm = CompatibilityOptions::instance();
			$orm->saveDefaults()->load();
			$this->syncLegacyOption( $orm );
			asp_parse_options();
			wd_asp()->css_manager->generator->generate();
			return new WP_REST_Response( $orm, 200 );
		} catch ( Exception $e ) {
			return new WP_Error( 'asp_compatibility_error', $e->getMessage(), array( 'status' => 500 ) );
		}
	}

	/**
	 * Write legacy flat format to asp_compatibility so all non-ORM consumers stay in sync.
	 *
	 * @param CompatibilityOptions $orm Loaded ORM instance.
	 */
	private function syncLegacyOption( CompatibilityOptions $orm ): void {
		update_option(
			'asp_compatibility',
			array(
				'css_compatibility_level'        => $orm->css_compatibility_level->value,
				'js_source'                      => $orm->js_source->value,
				'script_loading_method'          => $orm->script_loading_method->value,
				'css_loading_method'             => $orm->css_loading_method->value,
				'selective_exin_logic'           => $orm->selective_exin_logic->value,
				'db_force_case'                  => $orm->db_force_case->value,
				'js_prevent_body_scroll'         => $orm->js_prevent_body_scroll->value ? 1 : 0,
				'detect_ajax'                    => $orm->detect_ajax->value ? 1 : 0,
				'css_minify'                     => $orm->css_minify->value ? 1 : 0,
				'load_google_fonts'              => $orm->load_google_fonts->value ? 1 : 0,
				'usecustomajaxhandler'           => $orm->usecustomajaxhandler->value ? 1 : 0,
				'init_instances_inviewport_only' => $orm->init_instances_inviewport_only->value ? 1 : 0,
				'selective_enabled'              => $orm->selective_enabled->value ? 1 : 0,
				'selective_front'                => $orm->selective_front->value ? 1 : 0,
				'selective_archive'              => $orm->selective_archive->value ? 1 : 0,
				'query_soft_check'               => $orm->query_soft_check->value ? 1 : 0,
				'use_acf_getfield'               => $orm->use_acf_getfield->value ? 1 : 0,
				'db_force_unicode'               => $orm->db_force_unicode->value ? 1 : 0,
				'db_force_utf8_like'             => $orm->db_force_utf8_like->value ? 1 : 0,
				'rest_api_enabled'               => $orm->rest_api_enabled->value ? 1 : 0,
				'selective_exin'                 => implode( ',', $orm->selective_exin->value ),
				'meta_box_post_types'            => implode( '|', $orm->meta_box_post_types->value ),
			)
		);
	}
}
