<?php
/**
 * Elite Notification Settings Module
 *
 * @package Elite_Notification_Lite\Modules
 */

namespace Elite_Notification_Lite\Modules;

use Appsbd_Lite\V4\libs\Ajax_Confirm_Response;
use Appsbd_Lite\V4\libs\AppInput;
use Elite_Notification_Lite\Core\Elite_Notification_Lite;
use Elite_Notification_Lite\Core\Elite_Notification_Module_Lite;
use Elite_Notification_Lite\Libs\Elite_Notification_Client_Language;
use Elite_Notification_Lite\Libs\Elite_Notification_Item;
use Elite_Notification_Lite\Models\Database\Mapbd_Dummy_Notification;
use Elite_Notification_Lite\Styles\Apbd_Snf_1;
use Elite_Notification_Lite\Styles\Apbd_Snf_2;
use Elite_Notification_Lite\Styles\Apbd_Snf_3;
use Elite_Notification_Lite\Styles\Apbd_Snf_4;
use Elite_Notification_Lite\Styles\Apbd_Snf_5;

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

/**
 * Class Elite_Notification_Settings
 *
 * @package Elite_Notification_Lite\Modules
 */
class Elite_Notification_Settings extends Elite_Notification_Module_Lite {
	/**
	 * Its property nt_list
	 *
	 * @var array
	 */
	public $nt_list = array();

	/**
	 * The initialize is generated by appsbd
	 */
	public function initialize() {
		$this->set_notification_list();
		add_filter( 'appsbd-slnf-styles', array( $this, 'set_styles' ) );
	}

	/**
	 * The on init is generated by appsbd
	 */
	public function on_init() {
		parent::on_init();

		if ( version_compare(
			Elite_Notification_Lite::get_instance()->plugin_version,
			'2.0.0',
			'>='
		) && get_option( 'elite-notification_o_APBD_notification_setting' ) ) {
			$updated_settings = get_option( 'elite-notification_o_APBD_notification_setting' );
			if ( ! empty( $updated_settings ) ) {
				$this->options = $updated_settings;
			}
			$old_nt_list = get_option( 'apbd_snlf_nt', array() );
			if ( ! empty( $old_nt_list ) ) {
				$old_nt_list = maybe_unserialize( $old_nt_list );
				$old_nt_list = json_decode( json_encode( $old_nt_list ) );
				if ( is_array( $old_nt_list ) ) {
					$new_nt_list = array();
					foreach ( $old_nt_list as $item ) {
						if ( is_object( $item ) && property_exists(
							$item,
							'__PHP_Incomplete_Class_Name'
						) && 'apbd_notification_item' == $item->__PHP_Incomplete_Class_Name ) {
							$new_object = new elite_notification_item();
							foreach ( get_object_vars( $item ) as $property => $value ) {
								if ( property_exists( $new_object, $property ) ) {
									$new_object->$property = $value;
								}
							}
							$new_nt_list[] = $new_object;
						} else {
							$new_nt_list[] = $item;
						}
					}
					update_option( 'apbd_snlf_nt', $new_nt_list );
				}
			}
			if ( $this->update_option() ) {
				delete_option( 'elite-notification_o_APBD_notification_setting' );
			}
		}

		$this->add_admin_ajax_action( 'option', array( $this, 'ajax_request_callback' ) );
		$this->add_admin_ajax_action( 'get-option', array( $this, 'get_admin_options' ) );
		$this->add_admin_ajax_action( 'reload-log', array( $this, 'reload_log' ) );
		$this->add_admin_ajax_action( 'refresh-app', array( $this, 'refresh_app' ) );
		$this->add_admin_ajax_action( 'update-item-from-source', array( $this, 'manual_update_item_from_source' ) );
		$this->add_ajax_both_action( 'client-data', array( $this, 'client_data' ) );
		$this->add_admin_ajax_action( 'enoti-state', array( $this, 'update_view_status' ) );
		$this->add_ajax_no_priv_action( 'enoti-state', array( $this, 'update_view_status' ) );
		add_action( 'wp_footer', array( $this, 'wp_footer' ) );
		if ( $this->get_option( 'enable_brand', 'Y' ) == 'Y' ) {
			add_filter(
				'slnf-set-nt-by',
				function ( $nt_by ) {
					$nt_by .= '<small > by <a target="_blank" href="https://appsbd.com/elitenofi" class="eln-brand">Elite Notification</a></small>';

					return $nt_by;
				}
			);
		}
		add_filter(
			'query_vars',
			function ( $query_vars ) {
				$query_vars[] = '_aasanl';
				$query_vars[] = '_siid';

				return $query_vars;
			}
		);
		add_action(
			'template_include',
			function ( $template ) {
				$link    = get_query_var( '_aasanl' );
				$link_id = get_query_var( '_siid' );
				if ( ! empty( $link_id ) ) {
					Elite_Notification_Source::increase_click( $link_id );
				}
				if ( empty( $link ) ) {
					return $template;
				}
				wp_redirect( $link );
			}
		);
	}

	/**
	 * The on plugin version updated is generated by appsbd
	 *
	 * @param mixed $current_version It is current_version param.
	 * @param mixed $previous_version It is previous_version param.
	 */
	public function on_plugin_version_updated( $current_version, $previous_version ) {
		self::do_version_update( $current_version, $previous_version, false );
	}

	/**
	 * The update view status is generated by appsbd
	 */
	public function update_view_status() {
		$id = AppInput::post_value( 'id' );
		Elite_Notification_Source::increase_view( $id );
		exit( 'success' );
	}

	/**
	 * The on client scripts lite is generated by appsbd
	 */
	public function on_client_scripts_lite() {
		wp_register_script(
			'apbd-en-script',
			$this->get_plugin_url( 'cl-assets/js/client-script.js' ),
			array(),
			$this->kernel_object->plugin_version,
			true
		);
		wp_enqueue_script( 'apbd-en-script' );

		wp_register_style(
			'apbd-en-font',
			$this->get_plugin_url( 'admin-assets/font.css' ),
			array(),
			$this->kernel_object->plugin_version,
		);
		wp_enqueue_style( 'apbd-en-font' );

		wp_register_style(
			'apbd-en-style',
			$this->get_plugin_url( 'cl-assets/css/client-style.css' ),
			array(),
			$this->kernel_object->plugin_version,
		);

		wp_enqueue_style( 'apbd-en-style' );

		$jv_object              = new \stdClass();
		$jv_object->ajax_url    = wp_nonce_url( admin_url( 'admin-ajax.php' ), 'appsbd' );
		$jv_object->base_slug   = $this->kernel_object->get_action_prefix();
		$jv_object->ajax_nonce  = wp_create_nonce( 'notification' );
		$jv_object->assets_path = self::get_module_instance()->get_plugin_url( 'cl-assets/' );
		$jv_object->labels      = Elite_Notification_Client_Language::get_client_language( $this->kernel_object );

		wp_localize_script( 'apbd-en-script', 'apbd_en', (array) $jv_object );
	}

	/**
	 * The ajax request callback is generated by appsbd
	 */
	public function ajax_request_callback() {
		$response = new Ajax_Confirm_Response();
		$response->display_with_response( $this->update_request_option(), $this->options );
	}

	/**
	 * The update request option is generated by appsbd
	 *
	 * @return bool|void
	 */
	public function update_request_option() {
		$before_save = $this->options;
		$app_posts   = AppInput::get_posted_data();
		if ( ! empty( $app_posts['action'] ) ) {
			unset( $app_posts['action'] );
		}
		foreach ( $app_posts as $key => $post ) {
			$this->options[ $key ] = $post;
		}
		/**
		 * Its for check is there any change before process
		 *
		 * @since 1.0.0
		 */
		$this->options['sources_cats'] = apply_filters( 'appsbd-slnf-source-category', array() );
		$this->options['sources']      = Elite_Notification_Source::get_all_sources_client_settings();
		/**
		 * Its for check is there any change before process
		 *
		 * @since 1.0.0
		 */
		$this->options['styles'] = apply_filters( 'appsbd-slnf-styles', array() );
		$is_updated              = false;
		if ( $before_save == $this->options ) {
			$this->add_error( 'No change for update' );
		} elseif ( $this->update_option() ) {

			$is_updated = true;
			$this->add_info( 'Saved Successfully' );
		} else {
			$this->add_error( 'No change for update' );
		}

		return $is_updated;
	}

	/**
	 * The reload log is generated by appsbd
	 */
	public function reload_log() {
		$response = new Ajax_Confirm_Response();
		$data     = Elite_Notification_Source::get_source_update_log_msg();
		$response->display_with_response( true, $data );
	}

	/**
	 * The refresh app is generated by appsbd
	 */
	public function refresh_app() {
		$response = new Ajax_Confirm_Response();
		foreach ( $this->kernel_object->module_list as $module_object ) {
			$module_object->on_table_create();
			$module_object->on_active();
		}
		self::do_version_update( $this->kernel_object->plugin_version, $this->kernel_object->plugin_version, true );
		$this->add_info( 'Successfully refreshed' );
		$response->display_with_response( true );
	}

	/**
	 * The do version update is generated by appsbd
	 *
	 * @param mixed $current_version It is current_version param.
	 * @param mixed $previous_version It is previous_version param.
	 * @param mixed $is_force It is is_force param.
	 */
	public static function do_version_update( $current_version, $previous_version, $is_force = false ) {
		if ( $is_force || version_compare( $previous_version, '2.0.0', '>=' ) ) {
			Mapbd_Dummy_Notification::db_column_add_or_modify( 'img_id', 'int', '11', '0' );
		}
	}

	/**
	 * The manual update item from source is generated by appsbd
	 */
	public function manual_update_item_from_source() {
		Elite_Notification_Source::get_module_instance()->load_source_item( 'M' );
		$response = new Ajax_Confirm_Response();
		if ( count( $this->nt_list ) > 0 ) {
			$this->add_info(
				$this->__(
					'Successfully update items form source,%s notification in this list',
					count( $this->nt_list )
				)
			);
			$response->display_with_response( true );
		} else {
			$this->add_info( 'No source found to update' );
			$response->display_with_response( true );
		}
		$response->display_with_response( false );
	}

	/**
	 * The get admin options is generated by appsbd
	 */
	public function get_admin_options() {

		$options                            = array();
		$options['hide_in_mobile']          = $this->get_option( 'hide_in_mobile', 'N' );
		$options['hide_in_tab']             = $this->get_option( 'hide_in_tab', 'N' );
		$options['position']                = $this->get_option( 'position', 'apbd-snf-pos-lb' );
		$options['close_on_click']          = $this->get_option( 'close_on_click', 'Y' );
		$options['how_many_notification']   = $this->get_option( 'how_many_notification', 5 );
		$options['dummy_enable']            = $this->get_option( 'dummy_enable', 'I' );
		$options['open_in_new_tab']         = $this->get_option( 'open_in_new_tab', 'I' );
		$options['rmv_btn']                 = $this->get_option( 'rmv_btn', 'Y' );
		$options['is_loop']                 = $this->get_option( 'is_loop', 'Y' );
		$options['delay_time']              = $this->get_option( 'delay_time', 2 );
		$options['time_interval']           = $this->get_option( 'time_interval', 2 );
		$options['display_time']            = $this->get_option( 'display_time', 1 );
		$options['display_animation']       = $this->get_option( 'display_animation', 'ape-bounceIn' );
		$options['display_animation_exit']  = $this->get_option( 'display_animation_exit', 'ape-bounceOut' );
		$options['corn_type']               = $this->get_option( 'corn_type', 'W' );
		$options['source_update_time_type'] = $this->get_option( 'source_update_time_type', 'M' );
		$options['source_update_time_val']  = $this->get_option( 'source_update_time_val' );
		$options['enable_brand']            = $this->get_option( 'enable_brand', 'Y' );
		$options['is_sessioned']            = $this->get_option( 'is_sessioned', 'N' );
		/**
		 * Its for check is there any change before process
		 *
		 * @since 1.0.0
		 */
		$options['sources_cats'] = apply_filters( 'appsbd-slnf-source-category', array() );
		$options['sources']      = Elite_Notification_Source::get_all_sources_client_settings();
		/**
		 * Its for check is there any change before process
		 *
		 * @since 1.0.0
		 */
		$options['styles']        = apply_filters( 'appsbd-slnf-styles', array() );
		$options['scheduler_log'] = Elite_Notification_Source::get_source_update_log_msg();
		$options['cron_settings'] = admin_url( 'admin-ajax.php' ) . '?action=slnf-update-source';

		$response = new Ajax_Confirm_Response();
		$response->display_with_response( true, $options );
	}

	/**
	 * The client data is generated by appsbd
	 */
	public function client_data() {
		$response               = new Ajax_Confirm_Response();
		$settings               = new \stdClass();
		$settings->data_array   = $this->get_notifications( true );
		$settings->all_settings = array(
			'is_hide_mobile'            => $this->get_option( 'hide_in_mobile', 'N' ),
			'is_hide_tab'               => $this->get_option( 'hide_in_tab', 'N' ),
			'is_close_or_click_enabled' => $this->get_option( 'close_on_click', 'Y' ),
			'is_remove_button'          => $this->get_option( 'rmv_btn', 'Y' ),
			'is_loop'                   => $this->get_option( 'is_loop', 'N' ),
			'is_session'                => $this->get_option( 'is_sessioned', 'N' ),
			'is_open_new_tab'           => $this->get_option( 'open_in_new_tab', 'I' ),
			'delay_time'                => $this->get_option( 'delay_time', 2 ) * 1000,
			'interval'                  => $this->get_option( 'time_interval', 5 ) * 1000,
			'display_time'              => $this->get_option( 'display_time', 5 ) * 1000,
			'position'                  => $this->get_option( 'position', 'apbd-snf-pos-bl' ),
			'entrance_animation'        => $this->get_option( 'display_animation', 'ape-bounceIn' ),
			'exit_animation'            => $this->get_option( 'display_animation_exit', 'ape-bounceOut' ),
		);

		if ( count( $settings->data_array ) > 0 ) {
			$response->display_with_response( true, $settings );
		} else {
			$this->add_info( 'No source found' );
			$response->display_with_response( false );
		}
		$response->display_with_response( false );
	}

	/**
	 * The set styles is generated by appsbd
	 *
	 * @param mixed $styles It is styles param.
	 *
	 * @return \Elite_Notification_Lite\Libs\Apbd_En_Style_Base []
	 */
	public function set_styles( $styles ) {
		$styles[] = new Apbd_Snf_1();
		$styles[] = new Apbd_Snf_2();
		$styles[] = new Apbd_Snf_3();
		$styles[] = new Apbd_Snf_4();
		$styles[] = new Apbd_Snf_5();

		return $styles;
	}

	/**
	 * The update notification list is generated by appsbd
	 *
	 * @return bool
	 */
	public function update_notification_list() {
		return update_option( 'apbd_snlf_nt', $this->nt_list ) || add_option( 'apbd_snlf_nt', $this->nt_list );
	}

	/**
	 * The set notification list is generated by appsbd
	 */
	public function set_notification_list() {
		$module_name   = get_class( $this );
		$this->nt_list = get_option( 'apbd_snlf_nt', array() );
	}

	/**
	 * The clear notification list is generated by appsbd
	 */
	public static function clear_notification_list() {
		self::get_module_instance()->nt_list = array();
		self::get_module_instance()->update_notification_list();
	}

	/**
	 * The add notification item list is generated by appsbd
	 *
	 * @param array $nt_items It is nt_items param.
	 */
	public function add_notification_item_list( $nt_items = array() ) {
		foreach ( $nt_items as $nt_item ) {
			if ( $nt_item instanceof Elite_Notification_Item ) {
				$this->add_notification_item( $nt_item, false );
			}
		}

		$this->sort_update_notification_items();
	}

	/**
	 * The add notification item is generated by appsbd
	 *
	 * @param mixed $nt_item It is nt_item param.
	 * @param bool  $do_sort_and_update It is do_sort_and_update param.
	 */
	public function add_notification_item( $nt_item, $do_sort_and_update = true ) {
		$nt_item->set_id();
		$this->nt_list[] = $nt_item;
		if ( $do_sort_and_update ) {
			$this->sort_update_notification_items();
		}
	}

	/**
	 * The sort update notification items is generated by appsbd
	 */
	public function sort_update_notification_items() {
		$allowed_noti_count = $this->get_option( 'how_many_notification', 5 );
		usort(
			$this->nt_list,
			function ( $a, $b ) {
				if ( $a->op_timestamp == $b->op_timestamp ) {
					return 0;
				}

				return ( $a->op_timestamp > $b->op_timestamp ) ? - 1 : 1;
			}
		);
		if ( count( $this->nt_list ) > $allowed_noti_count ) {
			$this->nt_list = array_slice( $this->nt_list, 0, $allowed_noti_count );
		}
		$this->update_notification_list();
	}

	/**
	 * The set item is generated by appsbd
	 *
	 * @param Elite_Notification_Item $item It is item param.
	 */
	private function set_item( &$item ) {
		$item->set_time();
		$item->set_click_link();
		/**
		 * Its for check is there any change before process
		 *
		 * @since 1.0.0
		 */
		$item->nt_by = apply_filters( 'slnf-set-nt-by', $item->nt_by );
	}

	/**
	 * The get notifications is generated by appsbd
	 * serve
	 *
	 * @param bool $view_count It is view_count param.
	 */
	public function get_notifications( $view_count = true ) {
		$allowed_noti_count = $this->get_option( 'how_many_notification', 5 );
		foreach ( $this->nt_list as &$nf_item ) {
			$this->set_item( $nf_item );
		}
		Elite_Notification_Source::get_module_instance()->update_option();
		if ( $this->get_option( 'dummy_enable', 'I' ) == 'A' ) {
			$dummy_limit = $allowed_noti_count - count( $this->nt_list );
			if ( $dummy_limit > 0 ) {
				$data        = Mapbd_Dummy_Notification::find_all_by(
					'status',
					'A',
					array(),
					'op_date',
					'DESC',
					$dummy_limit
				);
				$final_items = $this->nt_list;
				foreach ( $data as $item ) {
					$item_obj = Mapbd_Dummy_Notification::get_notification_item( $item );
					$item_obj->set_time();
					$item_obj->set_click_link();
					/**
					 * Its for check is there any change before process
					 *
					 * @since 1.0.0
					 */
					$item_obj->nt_by = apply_filters( 'slnf-set-nt-by', $item_obj->nt_by );
					$final_items[]   = $item_obj;
				}

				return $final_items;
			} else {
				return $this->nt_list;
			}
		}

		return $this->nt_list;
	}

	/**
	 * The wp footer is generated by appsbd
	 */
	public function wp_footer() {
		?>
		<div id="elite-notification-client"></div>
		<?php
	}
}

