<?php

declare ( strict_types=1 );

namespace Simplyin\Simplyin_W_Plugin;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry;
use Exception;
use Simplyin\Simplyin_W_Plugin\Controller\Ajax\Widget\Widget_Controller;
use Simplyin\Simplyin_W_Plugin\Lib\Base_Plugin\Abstract_Base_Plugin;
use Simplyin\Simplyin_W_Plugin\Lib\Base_Plugin\Logger\Logger_Interface;
use Simplyin\Simplyin_W_Plugin\Lib\Base_Plugin\Logger\Null_Logger;
use Simplyin\Simplyin_W_Plugin\Lib\Base_Plugin\Woocommerce_Logger;
use Simplyin\Simplyin_W_Plugin\Lib\Remote\Sin_Core_Api\Simplyin_Api_Legacy_Client;
use Simplyin\Simplyin_W_Plugin\Lib\Session\Simplyin_Session;
use Simplyin\Simplyin_W_Plugin\Payments\Ajax\Blik\Blik_Ajax_Handler;
use Simplyin\Simplyin_W_Plugin\Payments\Ajax\Card\Card_Ajax_Handler;
use Simplyin\Simplyin_W_Plugin\Payments\Gateway\Payment_Fields\Payment_Fields;
use Simplyin\Simplyin_W_Plugin\Payments\Gateway\Woocommerce_Blocks\Payment_Blocks_Support;

class Plugin extends Abstract_Base_Plugin {


	public const SHORT_SLUG = 'simplyin';

	/**
	 * Version marker for the last intentional force of the checkout checkbox default.
	 *
	 * Do not bump this together with the plugin version. Changing this value causes
	 * the plugin to overwrite merchant configuration again and force
	 * simplyin_register_by_default = 'on'.
	 *
	 * Update only after an explicit business decision to repeat the force migration.
	 */
	private const FORCE_REGISTER_BY_DEFAULT_ON_VERSION = '5.5.38';

	private static ?Legacy_App $app = null;

	public static bool $logger_enabled = false;
	private static array $simplyin_config = [];
	private static array $locked_options = [];

	/**
	 * Assets helper.
	 *
	 * @var Assets|null
	 */
	private ?Assets $assets = null;

	/**
	 * Get assets helper.
	 *
	 * @return Assets
	 * @throws Exception When plugin file cannot be resolved.
	 */
	public function assets(): Assets {
		if ( null === $this->assets ) {
			$this->assets = new Assets( $this->get__file__() );
		}

		return $this->assets;
	}

	/**
	 * Before init hook.
	 *
	 * @return void
	 * @throws Exception When config is not available yet.
	 */
	protected function before_init(): void {
		$this->declare_hpos_compatibility();
		$this->before_init_when_api_connected();
	}

	private function declare_hpos_compatibility(): void {
		add_action(
			'before_woocommerce_init',
			function () {
				if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
					\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility(
						'custom_order_tables',
						$this->get__file__(),
						true
					);
				}
			}
		);
	}

	private function before_init_when_api_connected() {
		if ( (string) get_option( 'SimplyInApiConnection' ) === '1' ) {
			( new Widget_Controller() )->register_ajax_hooks();
			$this->init_payment_gateway();

			add_action( 'woocommerce_blocks_loaded',
				[ $this, 'woocommerce_block_support' ] );


			$blik_ajax_handler = new Blik_Ajax_Handler();
			$blik_ajax_handler->register_ajax_hooks();
			$card_ajax_handler = new Card_Ajax_Handler();
			$card_ajax_handler->register_ajax_hooks();

		}
	}

	protected function plugins_loaded_hooks(): void {
		$this->run_db_migrations();
	}

	private function run_db_migrations(): void {
		$current_version  = function_exists( 'SimplyInGetPluginVersion' ) ? SimplyInGetPluginVersion() : '';
		$migrated_version = get_option( 'simplyin_db_version', '' );

		if ( $migrated_version === $current_version || '' === $current_version ) {
			return;
		}

		$this->migrate_register_by_default();
		$this->migrate_force_register_by_default_on();

		update_option( 'simplyin_db_version', $current_version );
	}

	private function migrate_force_register_by_default_on(): void {
		$applied_version = (string) get_option(
			'simplyin_register_by_default_force_applied_version',
			''
		);

		$already_applied = '' !== $applied_version
		                   && version_compare( $applied_version, self::FORCE_REGISTER_BY_DEFAULT_ON_VERSION, '>=' );

		if ( ! $already_applied ) {
			update_option( 'simplyin_register_by_default', 'on' );
			update_option( 'SimplyInRegisterByDefaultDisabled', false );
			update_option( 'SimplyInRegisterByDefaultStateOld', '' );
			update_option(
				'simplyin_register_by_default_force_applied_version',
				self::FORCE_REGISTER_BY_DEFAULT_ON_VERSION
			);
		}

		delete_option( 'simplyin_migration_force_register_on_5_5_37_done' );
	}

	private function migrate_register_by_default(): void {
		$value = get_option( 'simplyin_register_by_default' );

		if ( false === $value ) {
			return;
		}

		// Normalize pre-5.5.29 slider value ('1') to canonical 'on'.
		if ( '1' === $value ) {
			if ( false === get_option( 'simplyin_register_by_default_legacy' ) ) {
				update_option( 'simplyin_register_by_default_legacy', $value );
			}
			update_option( 'simplyin_register_by_default', 'on' );
			return;
		}

		// Normalize empty string (ambiguous legacy state) to explicit canonical 'off'.
		if ( '' === $value ) {
			if ( false === get_option( 'simplyin_register_by_default_legacy' ) ) {
				update_option( 'simplyin_register_by_default_legacy', $value );
			}
			update_option( 'simplyin_register_by_default', 'off' );
		}
	}

	/**
	 * @throws Exception
	 */
	public function enqueue_frontend_scripts(): void {
		if ( ! get_option( 'SimplyInApiConnection' ) ) {
			return;
		}

		$assets = $this->assets();

		if ( ( is_checkout() && ! has_block( 'woocommerce/checkout' ) ) || is_checkout_pay_page() ) {
			$assets->enqueue_script(
				'SimplyInGatewayJs',
				'public/gateway/front.js',
				[ 'jquery' ],
				true
			);
		}

		$assets->enqueue_style(
			'SimplyInGatewayCss',
			'public/gateway/front.css',
			[],
			'all'
		);

		$assets->enqueue_style(
			'SimplyInThankYouPageCss',
			'public/thankyoupage/status/status.css',
			[],
			'all'
		);

		/**
		 * Allow custom frontend assets.
		 *
		 * @param Assets $assets Assets helper.
		 */
		do_action( 'simplyin_enqueue_frontend_scripts', $assets );
	}


	public function enqueue_dashboard_scripts() {
		$assets = $this->assets();

		$assets->enqueue_script(
			'SimplyInAdminJs',
			'public/admin/admin.js',
			[ 'jquery' ],
			true
		);

		$assets->enqueue_style(
			'SimplyInAdminCss',
			'public/admin/admin.css',
			[],
			'all'
		);

		$assets->enqueue_style(
			'SimplyInGatewayOptionsCss',
			'public/admin/gateway_options.css',
			[],
			'all'
		);
	}

	public function init(): void {


	}

	public function get_woocommerce_logger( ?string $log_id = null
	): Logger_Interface {

		$log_id = $log_id
			? $this->prefix_by_short_slug( $log_id )
			: $this->get_from_config( 'slug' );

		if ( self::$logger_enabled ) {
			$logger = new Woocommerce_Logger( $log_id );
		} else {
			$logger = new Null_Logger();
		}

		return $logger;
	}

	public function get_simplyin_logger(): Simplyin_Logger {
		return new Simplyin_Logger();
	}

	public function prefix_by_short_slug( string $string ): string {
		return self::SHORT_SLUG . '_' . $string;
	}


	public function get_app(): Legacy_App {
		if ( ! self::$app ) {
			self::$app = new Legacy_App();
		}

		return self::$app;
	}

	public function update_option(
		$key,
		$value,
		?string $context = null,
		$locked = false
	) {
		if ( key_exists( $key, self::$locked_options ) ) {
			$this->get_woocommerce_logger( $context )->log_debug(
				sprintf( "[update_option] [key: %s] [locked!]",
					$key ) );

			return;
		}

		if ( $locked ) {
			self::$locked_options[ $key ] = true;
		}

		$this->get_woocommerce_logger( $context )->log_debug(
			sprintf( "[update_option] [key: %s] [value: %s]",
				$key,
				wp_json_encode( $value ) ) );


		update_option( $key, $value );
	}

	public function get_api(): Simplyin_Api_Legacy_Client {
		return new Simplyin_Api_Legacy_Client( 'simplyin',
			SimplyInGetPluginVersion() );
	}

	public function get_simplyin_config(): array {

		return self::$simplyin_config;
	}

	public function set_simplyin_config( array $simplyin_config ): void {
		self::$simplyin_config = $simplyin_config;
	}

	public function get_backend_simplyin_url(): string {
		$simplyin_config = $this->get_simplyin_config();

		if ( isset( $simplyin_config['backendSimplyIn'] ) ) {
			return $simplyin_config['backendSimplyIn'];
		} else {
			return '';
		}
	}

	public function get_environment_version_prefix(): string {
		$simplyin_config = $this->get_simplyin_config();

		if ( isset( $simplyin_config['environmentVersion'] ) ) {
			return $simplyin_config['environmentVersion'];
		} else {
			return '';
		}
	}

	public function get_simplyin_session(): Simplyin_Session {
		return new Simplyin_Session();
	}

	private function init_payment_gateway() {
		add_filter( 'woocommerce_payment_gateways',
			function ( $gateways ) {
				$gateways[]
					= 'Simplyin\Simplyin_W_Plugin\Payments\Gateway\Simplyin_Gateway';

				return $gateways;
			}
		);
	}

	public function woocommerce_block_support() {
		$host = $request_uri = '';
		if ( isset( $_SERVER['HTTP_HOST'] ) ) {
			$host = esc_url_raw( wp_unslash( $_SERVER['HTTP_HOST'] ) );
		}

		if ( isset( $_SERVER['REQUEST_URI'] ) ) {
			$request_uri = esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) );
		}

		$current_url = $host . $request_uri;

		$search_phrase = "order-received";
		if ( strpos( $current_url, $search_phrase ) !== false ) {
			return;
		}

		if ( class_exists( 'Automattic\WooCommerce\Blocks\Payments\Integrations\AbstractPaymentMethodType' ) ) {
			add_action(
				'woocommerce_blocks_payment_method_type_registration',
				function ( PaymentMethodRegistry $payment_method_registry ) {
					$payment_method_registry->register( new Payment_Blocks_Support() );
				}
			);
		}
	}

	public function handle_api_unauthorized(): void {
		$this->update_option( 'SimplyInSettingsErrorMsg',
			__( 'Error connecting to Simply.IN - check the API key.',
				'simplyin' ),
			null,
			true );

		$this->update_option( 'SimplyInApiConnection',
			0,
			'sync' );
		$this->update_option( 'SimplyInApiConnectedLastTry',
			time(),
			'sync' );

		$simplyin_session = $this->get_simplyin_session();
		$previous_token = (string) $simplyin_session->get( 'simplyin_auth_token', '' );
		$previous_session_id = (string) $simplyin_session->get( 'id', '' );

		$simplyin_session->clear();
		Payment_Fields::clear_methods_cache( $previous_token, $previous_session_id );

		$simplyin_session->set( 'simplyin_user_data_commerce', null );
		$simplyin_session->set(
			'simplyin_user_data_commerce_timestamp',
			null
		);
	}

}
