<?php

namespace CarDealerPress\Admin\Functions;

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

use CarDealerPress\includes\helpers\Allowed_Html;
use CarDealerPress\Includes\Database\{Company_Handler, Create_Tables, Inserts, Inventory_Handler,Requests, Update_Delete};
use CarDealerPress\Includes\Functions\{Alter_Options,
	Extender_Ajax,
	Logger,
	Saved_Ajax,
	Sc_Ajax,
	Transfer,
	VehicleManagementSystem};
use CarDealerPress\Includes\Helpers\helpers as helpers;
use CarDealerPress\Includes\Helpers\{Multi_Request,Option, Remote_Requests};
use CarDealerPress\Includes\Init\Default_Options;
use DateTime;
use DateTimeZone;

class Main {
	use Logger;

	/**
	 * @var array|mixed
	 */
	public static $company;
	/**
	 * @var int
	 */
	private static $blog;
	public static Requests $db_request;
	public $update_delete;
	public $inserts;
	public $company_handler;
	public $multi_request;
	public $theme_options;

	public $admin_options;

	private $inventory_handler;
	/**
	 * @var VehicleManagementSystem
	 */
	private $vms;

	public function __construct() {
		self::$blog = get_current_blog_id();
		$this->init_wp_cron_job_create();
		self::$db_request = new Requests();
		$this->company_handler   = new Company_Handler();
		$this->inventory_handler = new Inventory_Handler();
		$this->initialize();
		add_action( 'init', array( $this, 'cdp_post_handler' ) );
		$this->send_additional_header_data();
		(new Allowed_Html());
	}

	function init_wp_cron_job_create() {
		register_activation_hook( __FILE__, array( $this, 'cardealerpress_activation' ) );
		add_action( 'cdp_cron_inventory_update', array( $this, 'init_cdp_cron_inventory_update' ) );
		$this->add_wp_cron_job();
	}

	public function initialize() {
		if ( ! get_option( 'cdp_admin_options' ) ) {
			new Transfer();
		}
		if ( ! get_option( 'cdp_admin_options' ) ) {
			$this->initialize_default_options();
			(new Create_Tables())->all_tables();
			$this->append_log( array( 'message' => 'CDP Message: Created Options, no previous install detected' ) );
		}
		if ( ! get_option('cdp_db_name_update')){
			(new Create_Tables())->company_table();
			(new Create_Tables())->data_table();
			$this->append_log( array( 'message' => 'CDP Message: Created Company and Data tables for db renaming' ) );
			// populate tables with data
			$this->get_and_populate_dealer_data( array('company_id'=> helpers::company_id() ));
			add_option( 'cdp_db_name_update', 1 );
		}
		$this->setup();
	}

	public function setup() {
		$company_id = helpers::company_id();
		if ( '0' === $company_id ) {
			add_action(
				'admin_notices',
				array(
					$this,
					'display_admin_register_notice',
				)
			);
			$this->append_log( array( 'message' => 'CDP Message: Error No Company Id set. Id is set to: ' . $company_id ) );
		} else {
			$this->set_option_variables();
			$this->initialize_setup();
			self::$company = ( self::$db_request->cdp_company_request()[0] ?? array() );
			if (self::$company) {
				$this->setup_routing();
			}
			$this->register_sc_ajax();
			$this->register_saved_ajax();
			$this->register_extender_ajax();
			$this->add_filter_hooks();
			$this->add_menu_vms_link();
			$this->wp_header_add();
			new Alter_Options();
		}
	}

	public function initialize_default_options() {
		add_option( 'cdp_admin_options', Default_Options::$default_options_admin );
		add_option( 'cdp_theme_options', Default_Options::$default_options_theme );
	}

	private function set_option_variables() {
		$this->theme_options = Option::get_cdp_theme_options();
		$this->admin_options = Option::get_cdp_admin_options();
	}

	public function initialize_setup() {
		// Legacy, leaving as a reminder to follow up. and fix the $this->vms.
		if ( $this->admin_options['admin']['help']['host'] && helpers::company_id() ) {
			$this->vms = new VehicleManagementSystem( $this->admin_options['admin']['help']['host'], helpers::company_id() );
		}
	}

	/**
	 *
	 * # TODO: Future refactor to a routing class
	 **/
	public function setup_routing() {
		add_action( 'rewrite_rules_array', array( &$this, 'add_rewrite_rules' ), 1 );
		add_action( 'init', array( &$this, 'create_taxonomies' ) );
	}

	public function register_sc_ajax() {
		// Legacy shortcodes.
		$sc_ajax = new Sc_Ajax( $this->theme_options, $this->vms, self::$company );
		add_action(
			'wp_ajax_sc_ajax_handler',
			array(
				&$sc_ajax,
				'sc_ajax_handler',
			)
		);
		add_action(
			'wp_ajax_nopriv_sc_ajax_handler',
			array(
				&$sc_ajax,
				'sc_ajax_handler',
			)
		);
	}

	public function register_saved_ajax() {
		$ajax = new Saved_Ajax();
		add_action(
			'wp_ajax_saved_ajax_handler',
			array(
				&$ajax,
				'saved_ajax_handler',
			)
		);
		add_action(
			'wp_ajax_nopriv_saved_ajax_handler',
			array(
				&$ajax,
				'saved_ajax_handler',
			)
		);
	}

	public function register_extender_ajax() {
		// Flamingo ajax.
		$front_ajax = new Extender_Ajax();
		add_action(
			'wp_ajax_extender_ajax_handler',
			array(
				&$front_ajax,
				'extender_ajax_handler',
			)
		);
		add_action(
			'wp_ajax_nopriv_extender_ajax_handler',
			array(
				&$front_ajax,
				'extender_ajax_handler',
			)
		);
	}
	public function check_for_wordpress_seo() {
		// https://gist.github.com/amboutwe/8cfb7a3d8f05e580867341d4ff84141d#file-yoast_seo_sitemap_add_external-php
		if (is_plugin_active('wordpress-seo/wp-seo.php')) {
			add_filter(
				'wpseo_sitemap_index',
				array(
					&$this,
					'add_custom_sitemap_link',
				)
			);
		}
	}

	public function check_for_seo_by_rank_math() {
		if (is_plugin_active('seo-by-rank-math/rank-math.php')) {
			// Filter to add external Sitemap to the Rank Math Sitemap
			// https://rankmath.com/kb/filters-hooks-api-developer/#add-external-sitemap
			add_filter( 'rank_math/sitemap/index', function () {
				return $this->add_custom_sitemap_link();
			}, 11 );
		}
	}

	/** Routing. **/
	public function add_filter_hooks() {
		if ( ! empty( self::$company['seo'] ) ) {
			include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
			$this->check_for_wordpress_seo();
			$this->check_for_seo_by_rank_math();
		}

		add_filter( 'redirect_canonical', array( &$this, 'stop_canonical' ) );
		add_filter(
			'gform_pre_send_email',
			function ( $email ) {
				if ( isset($_COOKIE['cdp_page_url']) ? sanitize_text_field( wp_unslash( $_COOKIE['cdp_page_url'] ) ) : '' ) {
					$merge_tag        = '{cdp_embed_url}';
					$new_message      = str_replace( $merge_tag, sanitize_text_field( wp_unslash($_COOKIE['cdp_page_url'])), $email['message'] );
					$email['message'] = $new_message;
				}

				return $email;
			}
		);
		// @codingStandardsIgnoreStart
		$safe = helpers::sanitize_get($_GET);
		// @codingStandardsIgnoreEnd
		if ( isset( $safe['external_user_id'] ) ) {
			add_filter(
				'gform_field_value_dt_external_user_id',
				function ($safe) {
					return $safe['external_user_id'];
				}
			);
			setcookie( 'cdp_external_user_id', $safe['external_user_id'], 0, '/' );
		}

		// Removes extra elements being added to widgets
		remove_filter( 'widget_text_content', 'wpautop' );

		add_filter(
			'gform_notification',
			array(
				$this,
				'cdp_change_notification_format',
			),
			10,
			3
		);
	}

	public function add_menu_vms_link() {
		// Adds a link to the admin bar for VMS.
		add_action( 'wp_before_admin_bar_render', array( $this, 'add_vms_link' ) );
	}

	public function wp_header_add() {
		add_action( 'wp_head', array( $this, 'add_meta_viewport' ) );
	}

	public function send_additional_header_data() {
		add_action( 'send_headers', array( $this, 'additional_headers' ) );
	}

	public static function get_theme_names( $type ) {
		$directories = scandir( plugin_dir_path( __FILE__ ) . '../../templates/' . $type . '/' );
		$ignore      = array(
			'.',
			'..',
		);
		$exclude     = array( 'php' );
		foreach ( $directories as $key => $value ) {
			$ext = pathinfo( $value, PATHINFO_EXTENSION );
			if ( in_array( $ext, $exclude, true ) ) {
				unset( $directories[ $key ] );
			}

			if ( in_array( $value, $ignore, true ) ) {
				unset( $directories[ $key ] );
			}
		}

		return array_values( $directories );
	}

	public function additional_headers() {
		if ( ! is_admin() ) {
			global $wp_version;
			header( 'X-WP-Version: ' . $wp_version );
			header( 'X-CDP-Version: ' . CDP_VERSION );
			if ( helpers::company_id() ) {
				header( 'X-CDP-Company-ID: ' . helpers::company_id() );
			}

			if ( isset( $this->theme_options['theme']['general']['name'] ) ) {
				header( 'X-CDP-Theme-Name: ' . $this->theme_options['theme']['general']['name'] );
			}
		}
	}

	public function display_admin_register_notice() {
		if ( is_admin() ) {
			$notice  = '<div class="error" style="display: block; font-weight:bold; font-size: 120%; padding: 3px 5px;">';
			$notice .= '<span>CarDealerPress requires a Company ID prior to use. </span>';
			$notice .= '<span style="display: inline-block; padding: 0 5px; background-color: #fcf9f9;">';
			$notice .= '<a target="_blank" href="https://cardealerpress.com/request-cardealerpress-demo-account/">Request a Demo ID</a>';
			$notice .= '</span>';
			$notice .= '<span style="display: inline-block; padding: 0 5px; background-color: #fcf9f9;">';
			$notice .= '<a target="_blank" href="https://cardealerpress.com">Purchase Subscription</a>';
			$notice .= '</span>';
			$notice .= '<span>or</span>';
			$notice .= "<span style='display: inline-block; padding: 0 5px; background-color: #fcf9f9;'>";
			$notice .= "<a href='" .get_admin_url() . "admin.php?page=cardealerpress_admin'>Add</a> your Company ID.";
			$notice .= '</span>';
			$notice .= '</div>';
			helpers::output_wp_kses( $notice);
		}
	}//end display_admin_register_notice()

	public function cdp_post_handler() {
		if ( isset( $_POST['cdp_Admin_post_action'], $_REQUEST['nonce'] ) && wp_verify_nonce( sanitize_key( $_REQUEST['nonce'] ), 'cdp-nonce' ) ) {
			$company_id = isset($_POST['cdp_Admin_post_previous_id']) ? sanitize_text_field( wp_unslash( $_POST['cdp_Admin_post_previous_id'] ) ) : '';
			switch ( $_POST['cdp_Admin_post_action'] ) {
				case 'addCDPCronJob':
					$this->cardealerpress_activation();
					break;
				case 'companyRefresh':
					$this->append_log( array( 'message' => 'CDP Message: Manually updating Company ' . $company_id . ' on blog: ' . self::$blog ) );
					$this->company_handler->init_company_handler( array( 'purge' => true ) );
					break;
				case 'dealerAdd':
					// Adds Dealer to CDP Data table.
					// Run Company handler to add and populate inventory for new dealer.
					if ( isset( $_POST['cdp_Admin_post_previous_id'] ) && ! empty( $_POST['cdp_Admin_post_add_new_dealer_value'] ) ) {
						$added_company_id = sanitize_text_field( wp_unslash( $_POST['cdp_Admin_post_add_new_dealer_value'] ) );
						$this->get_and_populate_dealer_data(
							array(
								'company_id'       => $company_id,
								'added_company_id' => $added_company_id,
								'action'           => 'dealerAdd',
							)
						);
					}

					break;
				case 'dealerDelete':
						// Remove Dealer from CDP Data, Companies and Inventory table.
					( new Update_Delete() )->remove_dealer_id_from_cdp_tables( $company_id );
					break;
				case 'dealerChange':
					if ( isset( $_POST['cdp_Admin_post_previous_id'] ) && ! empty( $_POST['cdp_Admin_post_new_value'] ) ) {
						$company_id  = sanitize_text_field( wp_unslash( $_POST['cdp_Admin_post_new_value'] ) );
						$previous_id = sanitize_text_field( wp_unslash( $_POST['cdp_Admin_post_previous_id'] ) );
						$this->get_and_populate_dealer_data(
							array(
								'company_id'  => $company_id,
								'action'      => 'dealerChange',
								'previous_id' => $previous_id,
							)
						);
					}
					break;
				case '':
					break;
			}

			// Allows for Manual Imports to bypass Auto Import Check.
			if ( ( ! empty( sanitize_text_field( wp_unslash( $_POST['cdp_Admin_post_data'] ) ) ) ) && ! get_transient( 'cdp_manual_update_handler_processing' ) ) {
				$cdp_admin_post_data = sanitize_text_field( wp_unslash( $_POST['cdp_Admin_post_data'] ) );
				set_transient( 'cdp_manual_update_handler_processing_' . self::$blog, 'Running', 60 );
				switch ( $_POST['cdp_Admin_post_action'] ) {
					case 'fullImport':
						$this->append_log( array( 'message' => 'CDP Message: Manual Import - Full | Company - ' . sanitize_text_field( wp_unslash( $_POST['cdp_Admin_post_previous_id'] ) ) ) );
						$this->inventory_handler->init_inventory_handler( 0 );
						break;
					case 'dealerImportPurge':
						$this->append_log( array( 'message' => 'CDP Message: Manual Import - Purge | Dealer - ' . $cdp_admin_post_data ) );
						$this->inventory_handler->init_inventory_handler( $cdp_admin_post_data, true );
						break;
					case 'dealerImport':
						$this->append_log( array( 'message' => 'CDP Message: Manual Import | Dealer - ' . $cdp_admin_post_data ) );
						$this->inventory_handler->init_inventory_handler( $cdp_admin_post_data, false );
						break;
				}

				delete_transient( 'cdp_manual_update_handler_processing_' . self::$blog );
			}
		}
	}

	public function get_and_populate_dealer_data( $args ) {
		$company_id       = $args['company_id'];
		$added_company_id = $args['added_company_id'] ?? '';
		$previous_id      = $args['previous_id'] ?? '';
		$action = $args['action'] ?? '';
		if ( $added_company_id ) {
			$company_id = $added_company_id;
		}

		$response = Remote_Requests::check_for_valid_company_id( $company_id );
		if ( ! $response['error'] ) {
			if ( 'dealerChange' === $action ) {
				( new Update_Delete() )->reset_tables( $previous_id );
			}
			// Run Company handler to add and populate inventory for new dealer.
			$this->company_handler->init_company_handler( array( 'company_id' => $company_id ) );
			$this->inventory_handler->init_inventory_handler( $company_id );
		} else {
			$this->append_log( array( 'message' => 'CDP Message: Invalid Company Id: ' . $company_id ) );
		}
	}
	public function cardealerpress_activation() {
		$this->append_log( array( 'message' => 'CDP Message: Activation Check' ) );
		$this->add_wp_cron_job();
	}

	function add_wp_cron_job() {
		if ( ! wp_next_scheduled( 'cdp_cron_inventory_update' ) ) {
			$this->append_log( array( 'message' => 'CDP Cron Job Created' ) );
			wp_schedule_event( time(), 'hourly', 'cdp_cron_inventory_update' );
		}
	}

	public function init_cdp_cron_inventory_update() {
		$this->append_log( array( 'message' => 'CDP Message: Inventory Cron Update - starting.' ) );
		$this->inventory_handler->init_inventory_handler();
		$this->append_log( array( 'message' => 'CDP Message: Inventory Cron Update - finished.' ) );
	}

	public function add_rewrite_rules( $existing_rules ) {
		$new_rules = array();
		if ( $this->admin_options['admin']['help']['host'] && helpers::company_id() ) {
			$new_rules['^(inventory)']                   = 'index.php?taxonomy=inventory';
			$new_rules['^(new-vehicle-sitemap\.xml$)']   = 'index.php?taxonomy=new-vehicle-sitemap';
			$new_rules['^(used-vehicle-sitemap\.xml$)']  = 'index.php?taxonomy=used-vehicle-sitemap';
			$new_rules['^(video-vehicle-sitemap\.xml$)'] = 'index.php?taxonomy=video-vehicle-sitemap';
		}

		return ( $new_rules + $existing_rules );
	}

	/** TODO, look up register_sidebar, and refactor split up into smaller functions. **/
	public function create_taxonomies() {
		if ( $this->admin_options['admin']['help']['host'] && helpers::company_id() ) {
			add_filter( 'widget_text', 'do_shortcode' );
			register_sidebar(
				array(
					'name'          => 'Inventory Vehicle Detail Page',
					'id'            => 'vehicle-detail-page',
					'description'   => 'Widgets in this area will show up on the Vehicle Detail Page.',
					'before_title'  => '<h1>',
					'after_title'   => '</h1>',
					'before_widget' => '<div id="%1$s" class="inventory widget %2$s">',
					'after_widget'  => '</div>',
				)
			);
			register_sidebar(
				array(
					'name'          => 'Inventory Vehicle List Page',
					'id'            => 'vehicle-listing-page',
					'description'   => 'Widgets in this area will show up on the Vehicle List Page.',
					'before_title'  => '<h1>',
					'after_title'   => '</h1>',
					'before_widget' => '<div id="%1$s" class="inventory-list widget %2$s">',
					'after_widget'  => '</div>',
				)
			);
			$labels = array(
				'name' => _x( 'Inventory', 'taxonomy general name', 'cardealerpress' ),
			);
			register_taxonomy(
				'inventory',
				array( 'page' ),
				array(
					'hierarchical'      => false,
					'labels'            => $labels,
					'show_ui'           => false,
					'query_var'         => true,
					'rewrite'           => array( 'slug' => 'inventory' ),
					'show_in_nav_menus' => false,
					'show_tagcloud'     => false,
				)
			);

			$saleclass = ( $this->theme_options['theme']['overrides']['saleclass'] ?? 'all' );
			$saleclass_check = self::$db_request->cdp_db_init('saleclass');
			if (empty($saleclass_check)){
				$saleclass_check = array(array('saleclass' => 'used'));
			}
			if ( ('all' === $saleclass || 'new' === $saleclass) && 'new' === $saleclass_check[0]['saleclass'] ) {
				$labels = array(
					'name' => _x( 'New Inventory Sitemap', 'taxonomy general name', 'cardealerpress' ),
				);
				register_taxonomy(
					'new-vehicle-sitemap',
					array( 'page' ),
					array(
						'hierarchical'      => false,
						'labels'            => $labels,
						'show_ui'           => false,
						'query_var'         => true,
						'rewrite'           => array( 'slug' => 'new-vehicle-sitemap' ),
						'show_in_nav_menus' => false,
						'show_tagcloud'     => false,
					)
				);
			}

			if ( 'all' === $saleclass || 'used' === $saleclass || 'certified' === $saleclass ) {
				$labels = array(
					'name' => _x( 'Used Inventory Sitemap', 'taxonomy general name', 'cardealerpress' ),
				);
				register_taxonomy(
					'used-vehicle-sitemap',
					array( 'page' ),
					array(
						'hierarchical'      => false,
						'labels'            => $labels,
						'show_ui'           => false,
						'query_var'         => true,
						'rewrite'           => array( 'slug' => 'used-vehicle-sitemap' ),
						'show_in_nav_menus' => false,
						'show_tagcloud'     => false,
					)
				);
			}

			$video_check = self::$db_request->cdp_inventory_video_check();
			if ( ! empty( $video_check ) && 0 !== $video_check[0]['Total'] ) {
				$labels = array(
					'name' => _x( 'Video Inventory Sitemap', 'taxonomy general name', 'cardealerpress' ),
				);
				register_taxonomy(
					'video-vehicle-sitemap',
					array( 'page' ),
					array(
						'hierarchical'      => false,
						'labels'            => $labels,
						'show_ui'           => false,
						'query_var'         => true,
						'rewrite'           => array( 'slug' => 'video-vehicle-sitemap' ),
						'show_in_nav_menus' => false,
						'show_tagcloud'     => false,
					)
				);
			}
		}
	}

	/** Routing. */
	public function add_custom_sitemap_link() {
		/*
		 * Filter to add custom link to index sitemap for wpseo by yoast
		 *
		 * @return string $custom_link
		 */
		$date_raw     = gmdate( 'Y-m-d H:i P', current_time( 'timestamp', 0 ) );
		$utc_timezone = new DateTimeZone( 'UTC' );
		$datetime     = new DateTime( $date_raw, $utc_timezone );
		$last_mod     = $datetime->format( 'c' );

		$saleclass = ( $this->theme_options['theme']['overrides']['saleclass'] ?? 'all' );

		$custom_link = '';

		$saleclass_check = self::$db_request->cdp_db_init('saleclass');
		if ( ('all' === $saleclass || 'new' === $saleclass) && 'new' === $saleclass_check[0]['saleclass'] ) {
			$custom_link .= '<sitemap>' . "\n";
			$custom_link .= '<loc>' . home_url( 'new-vehicle-sitemap.xml' ) . '</loc>' . "\n";
			$custom_link .= '<lastmod>' . htmlspecialchars( $last_mod ) . '</lastmod>' . "\n";
			$custom_link .= '</sitemap>' . "\n";
		}

		if ( 'all' === $saleclass || 'used' === $saleclass || 'certified' === $saleclass ) {
			$custom_link .= '<sitemap>' . "\n";
			$custom_link .= '<loc>' . home_url( 'used-vehicle-sitemap.xml' ) . '</loc>' . "\n";
			$custom_link .= '<lastmod>' . htmlspecialchars( $last_mod ) . '</lastmod>' . "\n";
			$custom_link .= '</sitemap>' . "\n";
		}

		$video_check = self::$db_request->cdp_inventory_video_check();
		if ( 0 !== intval($video_check[0]['Total']) ) {
			$custom_link .= '<sitemap>' . "\n";
			$custom_link .= '<loc>' . home_url( 'video-vehicle-sitemap.xml' ) . '</loc>' . "\n";
			$custom_link .= '<lastmod>' . htmlspecialchars( $last_mod ) . '</lastmod>' . "\n";
			$custom_link .= '</sitemap>' . "\n";
		}

		return $custom_link;
	}

	public function stop_canonical( $redirect ) {
		$sitemap = get_query_var( 'taxonomy' );
		if ( ! empty( $sitemap ) && ( 'new-vehicle-sitemap' === $sitemap || 'used-vehicle-sitemap' === $sitemap || 'video-vehicle-sitemap' === $sitemap ) ) {
			return false;
		}

		return $redirect;
	}

	public function cdp_change_notification_format( $notification ) {
		if ( 'Admin Notification - ADF' === $notification['name'] || 'Admin Notification ADF' === $notification['name'] ) {
			// Change notification format to text from the default html.
			$notification['message_format'] = 'text';
		} else {
			$notification['message_format'] = 'html';
		}

		return $notification;
	}

	public function add_vms_link() {
		global $wp_admin_bar;
		if ( ! is_super_admin() || ! is_admin_bar_showing() ) {
			return;
		}

		$wp_admin_bar->add_menu(
			array(
				'id'    => 'vms_link',
				'meta'  => array( 'target' => '_blank' ),
				'title' => 'Manage Inventory',
				'href'  => 'https://manager.dealertrend.com',
			)
		);
	}

	public function add_meta_viewport() {
		echo '<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">';
	}
}
