<?php

namespace Ilabs\Inpost_International;

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

use Exception;
use Ilabs\Inpost_International\Backend\Ajax_Handler;
use Ilabs\Inpost_International\Backend\Backend;
use Ilabs\Inpost_International\Backend\Orders_Bulk_Actions;
use Ilabs\Inpost_International\Emails\OrderEmail;
use Ilabs\Inpost_International\Frontend\Checkout_Blocks_Map_Button;
use Ilabs\Inpost_International\Frontend\Frontend;
use Ilabs\Inpost_International\Helpers\Helper;
use Ilabs\Inpost_International\Integration\Flexible_Shipping\Flexible_Shipping_Integration;
use Ilabs\Inpost_International\API\API;
use Ilabs\Inpost_International\Settings\Admin_Settings;
use Ilabs\Inpost_International\Settings\Product_Settings;
use Ilabs\Inpost_International\Settings\Settings_Helper;
use Ilabs\Inpost_International\Shipping\Shipping_Method_Base;
use Ilabs\Inpost_International\Shipping\Shipping_Method_Courier;
use Isolated\InpostINTL\Ilabs\Ilabs_Plugin\Abstract_Ilabs_Plugin;
use Isolated\InpostINTL\Ilabs\Ilabs_Plugin\Alerts;
use Isolated\InpostINTL\Ilabs\Ilabs_Plugin\Event_Chain\Event\Wc_Add_To_Cart;
use Isolated\InpostINTL\Ilabs\Ilabs_Plugin\Event_Chain\Event\Wc_Order_Status_Changed;
use Isolated\InpostINTL\Ilabs\Ilabs_Plugin\Event_Chain\Event\Wc_Remove_Cart_Item;
use Isolated\InpostINTL\Ilabs\Ilabs_Plugin\Event_Chain\Interfaces\Wc_Cart_Aware_Interface;
use Isolated\InpostINTL\Ilabs\Ilabs_Plugin\Event_Chain\Interfaces\Wc_Order_Aware_Interface;
use Isolated\InpostINTL\Ilabs\Ilabs_Plugin\Event_Chain\Interfaces\Wc_Product_Aware_Interface;
use Isolated\InpostINTL\Ilabs\Ilabs_Plugin\Woocommerce_Logger;
use WC_Order;
use WC_Session;
use WC_Session_Handler;

use WP_Post;

/**
 * Plugin
 */
class Plugin extends Abstract_Ilabs_Plugin {

	/**
	 * Get woocommerce logger
	 *
	 * @param string|null $log_id $log_id.
	 *
	 * @return Woocommerce_Logger
	 * @throws Exception Exception.
	 */
	public function get_woocommerce_logger( ?string $log_id = null ): Woocommerce_Logger {

		$debug_mode = 'no';

		$log_id = $log_id ? $this->get_from_config( 'slug' ) : '';
		$logger = new Woocommerce_Logger( $log_id );

		if ( 'yes' === $debug_mode ) {
			$logger->set_null_logger( false );
		} else {
			$logger->set_null_logger( true );
		}

		return $logger;
	}



	/**
	 * Before init hooks
	 *
	 * @throws Exception Exception.
	 */
	protected function before_init() {
		add_action(
			'woocommerce_blocks_loaded',
			array( $this, 'woocommerce_block_support' )
		);
	}

	/**
	 * Add woocommerce block support
	 *
	 * @return void
	 */
	public function woocommerce_block_support() {
	}


	/**
	 * Enqueue frontend scripts
	 *
	 * @throws Exception Exception.
	 */
	public function enqueue_frontend_scripts() {

		global $wp;
		$thankyou_page = ! empty( $wp->query_vars['order-received'] ) ? absint( $wp->query_vars['order-received'] ) : false;

		$current_plugin_version = inpost_intl_core()->get_plugin_version();

		$plugin_geowidget_settings      = get_option( 'inpost_international_settings_geowidget' );
		$disable_assets_enqueue_by_page = false;
		if ( ! empty( $plugin_geowidget_settings['disable_assets_enqueue_by_page'] ) && 'on' === $plugin_geowidget_settings['disable_assets_enqueue_by_page'] ) {
			$disable_assets_enqueue_by_page = true;
		}

		if ( is_cart() || is_checkout()
			|| has_block( 'woocommerce/checkout' )
			|| is_wc_endpoint_url( 'order-received' )
			|| is_wc_endpoint_url( 'orders' )
			|| $disable_assets_enqueue_by_page ) {
			$front_css_path = inpost_intl_core()->get_plugin_dir() . 'assets/css/frontend.css';
			$front_css_ver  = file_exists( $front_css_path ) ? filemtime( $front_css_path ) : $current_plugin_version;
			wp_enqueue_style(
				$this->get_plugin_prefix() . '_front_css',
				$this->get_plugin_css_url() . '/frontend.css',
				array(),
				$front_css_ver
			);

			$geowidget_settings = get_option( 'inpost_international_settings_geowidget' );
			if ( ! empty( $geowidget_settings['map_button_color'] ) ) {
				$map_button_css = '.inpost_intl_show_geowidget { background:  ' . $geowidget_settings['map_button_color'] . ' !important; }';
				wp_add_inline_style( $this->get_plugin_prefix() . '_front_css', wp_kses( $map_button_css, array( 'style' => array() ) ) );
			}
		}

		if ( ! $thankyou_page && ( is_checkout() || has_block( 'woocommerce/checkout' ) || $disable_assets_enqueue_by_page ) ) {

			$helper             = new Helper();
			$inpost_methods     = $helper->get_inpost_shipping_methods();
			$map_button_js_mode = false;
			if ( ! empty( $plugin_geowidget_settings['map_button_output_js'] ) && 'on' === $plugin_geowidget_settings['map_button_output_js'] ) {
				$map_button_js_mode = true;
			}

			$geowidget_token = $this->get_geowidget_token();
			
			if ( empty( $geowidget_token ) ) {
				return;
			}
			
			$this->enqueue_geowidget_assets();

			$map_button_texts = array(
				'PL' => 'Wybierz punkt odbioru',
				'IT' => ! empty( $plugin_geowidget_settings['geowidget_button_text_it'] ) ? $plugin_geowidget_settings['geowidget_button_text_it'] : 'Selezionare un punto di ritiro',
				'ES' => ! empty( $plugin_geowidget_settings['geowidget_button_text_es'] ) ? $plugin_geowidget_settings['geowidget_button_text_es'] : 'Seleccione un punto de recogida',
				'PT' => ! empty( $plugin_geowidget_settings['geowidget_button_text_pt'] ) ? $plugin_geowidget_settings['geowidget_button_text_pt'] : 'Selecionar um ponto de recolha',
				'NL' => ! empty( $plugin_geowidget_settings['geowidget_button_text_nl'] ) ? $plugin_geowidget_settings['geowidget_button_text_nl'] : 'Levering van Locker of Relaispun',
				'FR' => ! empty( $plugin_geowidget_settings['geowidget_button_text_fr'] ) ? $plugin_geowidget_settings['geowidget_button_text_fr'] : 'Sélectionner un point de collecte',
				'BE' => ! empty( $plugin_geowidget_settings['geowidget_button_text_be'] ) ? $plugin_geowidget_settings['geowidget_button_text_be'] : 'Sélectionner un point de collecte',
				'LU' => ! empty( $plugin_geowidget_settings['geowidget_button_text_lu'] ) ? $plugin_geowidget_settings['geowidget_button_text_lu'] : 'Sélectionner un point de collecte',
				'HU' => ! empty( $plugin_geowidget_settings['geowidget_button_text_hu'] ) ? $plugin_geowidget_settings['geowidget_button_text_hu'] : 'Válasszon egy átvételi pontot',
				'AT' => ! empty( $plugin_geowidget_settings['geowidget_button_text_at'] ) ? $plugin_geowidget_settings['geowidget_button_text_at'] : 'Lieferung des Schließfachs oder Relaispunkts',
			);

			$selected_texts = array(
				'PL' => 'Wybrany punkt odbioru',
				'IT' => 'Punto di ritiro',
				'ES' => 'Punto de recogida',
				'PT' => 'Ponto de recolha',
				'NL' => 'Locker of Relaispun',
				'FR' => 'Point de collecte',
				'BE' => 'Point de collecte',
				'LU' => 'Point de collecte',
				'HU' => 'Válasszon egy átvételi pontot',
				'AT' => 'Lieferung des Schließfachs oder Relaispunkts',
			);

			$front_js_path = inpost_intl_core()->get_plugin_dir() . 'assets/js/front.js';
			$front_js_ver  = file_exists( $front_js_path ) ? filemtime( $front_js_path ) : $current_plugin_version;
			wp_enqueue_script(
				$this->get_plugin_prefix() . '_front_js',
				$this->get_plugin_js_url() . '/front.js',
				array( 'jquery', 'wp-i18n' ),
				$front_js_ver,
				array( 'in_footer' => true )
			);

			wp_set_script_translations( inpost_intl_core()->get_plugin_prefix() . '_front_js', 'inpost-international', inpost_intl_core()->get_plugin_dir() . 'lang' );

			wp_localize_script(
				$this->get_plugin_prefix() . '_front_js',
				'inpost_intl_frontend',
				array(
					'ajaxurl'            => admin_url( 'admin-ajax.php' ),
					'nonce'              => wp_create_nonce( 'inpost_intl_frontend' ),
					'logo_src'           => $this->get_plugin_images_url() . '/white.png',
					'plugin_slug'        => INPOST_INTL_PLUGIN_SLUG,
					'map_button_js_mode' => $map_button_js_mode,
					'inpost_methods'     => $inpost_methods,
					'geowidget_token'    => $geowidget_token,
					'button_texts'       => $map_button_texts,
					'selected_texts'     => $selected_texts,
				)
			);
		}
	}


	/**
	 * Get geowidget token
	 *
	 * @return string.
	 */
	public function get_geowidget_token() {
		$geowidget_token           = '';
		$plugin_geowidget_settings = get_option( 'inpost_international_settings_geowidget' );
		if ( ! empty( $plugin_geowidget_settings['geowidget_production_token'] ) ) {
			$geowidget_token = $plugin_geowidget_settings['geowidget_production_token'];
		} elseif ( ! empty( $plugin_geowidget_settings['geowidget_sandbox_token'] ) ) {
			$geowidget_token = $plugin_geowidget_settings['geowidget_sandbox_token'];
		} elseif ( ! empty( get_option( 'easypack_geowidget_production_token' ) ) ) {
			$geowidget_token = get_option( 'easypack_geowidget_production_token' );
		} elseif ( ! empty( get_option( 'easypack_geowidget_sandbox_token' ) ) ) {
			$geowidget_token = get_option( 'easypack_geowidget_sandbox_token' );
		}

		return $geowidget_token;
	}


	/**
	 * Enqueue geowidget scripts
	 *
	 * @throws Exception Exception.
	 */
	public function enqueue_geowidget_assets() {

		$current_plugin_version = inpost_intl_core()->get_plugin_version();

		$geowidget_sdk_src         = $this->get_plugin_js_url() . '/global_geowidget_sdk_sandbox.js';
		$plugin_geowidget_settings = get_option( 'inpost_international_settings_geowidget' );
		if ( ! empty( $plugin_geowidget_settings['geowidget_production_token'] ) ) {
			$geowidget_sdk_src = $this->get_plugin_js_url() . '/global_geowidget_sdk.js';
		}

		wp_enqueue_style(
			$this->get_plugin_prefix() . '_global_geowidget_sdk_css',
			$this->get_plugin_css_url() . '/global_geowidget_sdk.css',
			array(),
			$current_plugin_version
		);

		wp_enqueue_script(
			$this->get_plugin_prefix() . '_global_geowidget_js',
			$geowidget_sdk_src,
			array( 'jquery' ),
			$current_plugin_version,
			array( 'in_footer' => true )
		);
	}


	/**
	 * Enqueue dashboard scripts
	 *
	 * @throws Exception Exception.
	 */
	public function enqueue_dashboard_scripts() {

		$current_screen = get_current_screen();

		if ( is_a(
			$current_screen,
			'WP_Screen'
		) && 'woocommerce_page_wc-settings' === $current_screen->id ) {

			$sending_options        = get_option( 'inpost_international_settings_sending' );
			$saved_parcel_templates = array();
			if ( ! empty( $sending_options['templates'] ) ) {
				$saved_parcel_templates = $sending_options['templates'];
			}

			$rates_table_js_path = $this->get_plugin_dir() . '/assets/js/rates-table.js';
			$rates_table_js_ver  = file_exists( $rates_table_js_path ) ? filemtime( $rates_table_js_path ) : INPOST_INTL_PLUGIN_VERSION;
			wp_enqueue_script(
				$this->get_plugin_prefix() . '_rates_table_js',
				$this->get_plugin_js_url() . '/rates-table.js',
				array( 'jquery', 'wp-i18n' ),
				$rates_table_js_ver,
				array( 'in_footer' => true )
			);

			wp_set_script_translations( $this->get_plugin_prefix() . '_rates_table_js', 'inpost-international', $this->get_plugin_dir() . 'lang' );

			wp_localize_script(
				$this->get_plugin_prefix() . '_rates_table_js',
				'inpost_rates_table',
				array(
					'ajaxurl'         => admin_url( 'admin-ajax.php' ),
					'settings_url'    => admin_url( 'options-general.php?page=inpost-intl-settings' ),
					'logo_src'        => $this->get_plugin_images_url() . '/white.png',
					'img_path'        => $this->get_plugin_images_url() . '/',
					'plugin_slug'     => INPOST_INTL_PLUGIN_SLUG,
					'saved_templates' => $saved_parcel_templates,
				)
			);

		}
	}


	/**
	 * Plugins loaded hooks
	 *
	 * @return void
	 */
	protected function plugins_loaded_hooks() {

		add_action(
			'before_woocommerce_init',
			function () {

				$helper = Helper::init();

				if ( $helper->is_flexible_shipping_activated() ) {
					$flexible_shipping_integration = new Flexible_Shipping_Integration();
					$flexible_shipping_integration->add_settings_to_flexible_shipping();
				}
			}
		);
	}

	/**
	 * Init Inpost International shipping method
	 *
	 * @throws Exception Exception.
	 */
	public function after_setup_theme(): void {

		// add Inpost shipping method.
		add_filter(
			'woocommerce_shipping_methods',
			function ( $methods ) {

				$inpost_international_shipping_allowed = false;

				if ( get_option( 'inpost_international_only_for_admins' ) ) {
					if ( current_user_can( 'administrator' ) || ! empty( $_COOKIE['inpost_international_debug_frontend'] ) ) {
						$inpost_international_shipping_allowed = true;
					}
				} else {
					$inpost_international_shipping_allowed = true;
				}

				if ( $inpost_international_shipping_allowed ) {

                    if( class_exists('Ilabs\Inpost_International\Shipping\Shipping_Method_Base')) {
                        $inpost_international_locker               = new Shipping_Method_Base();
                        $methods[$inpost_international_locker->id] = get_class($inpost_international_locker);
                    }

                    if( class_exists('Ilabs\Inpost_International\Shipping\Shipping_Method_Courier')) {
                        $inpost_international_courier = new Shipping_Method_Courier();
                        $methods[ $inpost_international_courier->id ] = get_class( $inpost_international_courier );
                    }

				}


				return $methods;
			},
			9999
		);
	}

	/**
	 * Init main plugin classes
	 *
	 * @throws Exception Exception.
	 */
	public function init(): void {

		$this->check_woocommerce_version();

		try {
			// init admin settings.
			$settings_helper = new Settings_Helper();
			if ( is_admin() ) {
				( new Admin_Settings( $settings_helper ) );
				( new Orders_Bulk_Actions() );
			} else {
				// init Frontend hooks.
				( new Frontend() );
			}

			// init plugin hooks.
			( new API() );
			( new Backend() );
			( new Ajax_Handler() );
			( new Product_Settings() );
			( new OrderEmail() );

			// integration with Woocommerce blocks.
			add_action(
				'woocommerce_blocks_checkout_block_registration',
				function ( $integration_registry ) {
					$integration_registry->register( new Checkout_Blocks_Map_Button() );
				}
			);

			add_filter(
				'cron_schedules',
				function ( $schedules ) {
					$schedules['inpost_intl_5_minutes'] = array(
						'interval' => 5 * 60,
						'display'  => esc_html__( 'Every 5 Minutes', 'inpost-international' ),
					);

					return $schedules;
				}
			);


		} catch ( Exception $exception ) {
			if ( function_exists( 'wc_get_logger' ) ) {
				\wc_get_logger()->debug(
					'INPOST International INIT Exception: ',
					array( 'source' => 'inpost-international-init' )
				);
				\wc_get_logger()->debug(
					print_r( $exception->getMessage(), true ),
					array( 'source' => 'inpost-international-init' )
				);
			}
		}
	}


	/**
	 * On activate
	 *
	 * @return void
	 */
	public function plugin_activate_actions() {
		update_option( 'inpost_intl_activated', '1' );
	}

	public function plugin_deactivate_actions() {
		wp_clear_scheduled_hook( 'inpost_intl_cron' );
	}


	/**
	 * Check Woo version
	 *
	 * @return void
	 */
	private function check_woocommerce_version() {
		if ( defined( 'WC_VERSION' ) ) {
			if ( defined( 'WC_VERSION' ) && version_compare( WC_VERSION, '8.1.0', '<' ) ) {
				$alerts = new Alerts();
				$msg    = sprintf(
					esc_html__(
						'The block-based payment module will not work with the installed version of Woocommerce. Install at least 8.1.0 version.',
						'inpost-international'
					)
				);
				$alerts->add_error( 'Inpost International: ' . $msg );
			}
		}
	}


	/**
	 * Get WC logger
	 *
	 * @return false|\WC_Logger|\WC_Logger_Interface
	 */
	public function get_wc_logger() {

		if ( function_exists( 'wc_get_logger' ) ) {
			return wc_get_logger();
		}

		return false;
	}


	/**
	 * Custom plugin debug logger
	 *
	 * @return void
	 */
	public function inpost_logger( $log_heading, $debug_place, $log_data, $log_file_slug = null, $log_level = 'debug' ) {

		if ( ! $log_file_slug ) {
			$log_file_slug = $this->get_from_config( 'slug' );
		}

		if ( function_exists( 'wc_get_logger' ) ) {
			if ( is_object( $log_data ) || is_array( $log_data ) ) {
				\wc_get_logger()->debug( $log_heading, array( 'source' => $log_file_slug ) );
				\wc_get_logger()->debug( $debug_place, array( 'source' => $log_file_slug ) );
				\wc_get_logger()->debug( print_r( $log_data, true ), array( 'source' => $log_file_slug ) );

			} else {

				$log_data = $this->maybe_json( $log_data );

				$logger = wc_get_logger();
				$logger->log(
					$log_level,
					$log_heading,
					array(
						'source'        => $log_file_slug,
						'debug_details' => array(
							'debug_place' => $debug_place,
							'data'        => $log_data,
						),
					)
				);
			}
		}
	}


	/**
	 * Check if a string is valid JSON and decode it if it is.
	 *
	 * @param mixed $maybe_string $maybe_string.
	 *
	 * @return mixed False if not valid JSON, or the decoded data if valid.
	 */
	private function maybe_json( $maybe_string ) {
		if ( ! is_string( $maybe_string ) ) {
			return $maybe_string;
		}

		$string = trim( $maybe_string );

		// Check if the string starts with '{' and ends with '}'.
		if ( substr( $maybe_string, 0, 1 ) !== '{' || substr( $maybe_string, -1 ) !== '}' ) {
			return $maybe_string;
		}

		$result = json_decode( $maybe_string, true );

		if ( json_last_error() === JSON_ERROR_NONE ) {
			return $result;
		}

		return $maybe_string;
	}
}
