<?php

namespace CarDealerPress\Includes\Functions;

use CarDealerPress\Includes\Cron\Cron;
use CarDealerPress\Includes\Database\{Alter_Tables, Create_Tables, Requests, Truncate, Update_Delete};
use CarDealerPress\includes\helpers\{Multi_Request};
use CarDealerPress\Includes\Helpers\Generic;
use CarDealerPress\includes\helpers\helpers as helpers;
use CarDealerPress\includes\helpers\Http_Request;
use CarDealerPress\Includes\Helpers\Option;
use CarDealerPress\Includes\Helpers\Remote_Requests;
use CarDealerPress\Includes\Uninstall\Uninstall;

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

class Admin_Ajax {
	use Logger;

	public $theme_options;
	public $admin_options;
	private $vms;
	private $admin_db;
	public $update_delete;

	public function __construct() {
		$this->update_delete = new Update_Delete();
		$this->theme_options = Option::get_cdp_theme_options();
		$this->admin_options = Option::get_cdp_admin_options();
		$this->vms           = '$vms';
	}

	public function additional_dealer_check( $manual_id = 0 ) {
		$results = array();
		if ( $manual_id ) {
			$results = Multi_Request::manual_dealer_check( $manual_id );
		}

		return $results;
	}

	public function admin_handle_request() {
		$output = array(
			'id'      => '',
			'content' => '',
			'key'     => '',
		);
		$data_request = array();
		$nonce_check = isset( $_REQUEST['nonce'] ) && wp_verify_nonce( sanitize_key($_REQUEST['nonce']), 'cdp_nonce' );
		if ($nonce_check ){
			$data_request = $_REQUEST;
		}
		switch ( $data_request['fn'] ) {
			case 'dealerChange':
				$response = Remote_Requests::check_for_valid_company_id( $data_request['params']['company_id'] );
				if ( ! $response ) {
					$output['key']     = 'error';
					$output['content'] = 'Invalid Company id. ';
				}
				break;
			case 'removeTableRow':
				$page      = $data_request['params']['page'] ?? '' ;
				$option    = $data_request['params']['option'] ?? '';
				$tab       = $data_request['params']['tab'] ?? '';
				$row_id    = $data_request['params']['rowId'] ?? '';
				$section   = $data_request['params']['section'] ?? '';
				$section1  = $data_request['params']['section1'] ?? '';
				$section2  = $data_request['params']['section2'] ?? '';
				$dealer_id = $data_request['params']['dealerId'] ?? '';
				if ( 'cardealerpress_theme' === $page ) {
					switch ( true ) {
						case $section2:
							unset( $this->theme_options[ $option ][ $tab ][ $section ][ $section1 ][ $section2 ][ $row_id ] );
							$current    = $this->theme_options[ $option ][ $tab ][ $section ][ $section1 ][ $section2 ];
							$re_indexed = array_values( $current );
							$this->theme_options[ $option ][ $tab ][ $section ][ $section1 ][ $section2 ] = array_filter( $re_indexed );
							break;
						case $section1:
							if ( 'maps' === $section1 ) {
								unset( $this->theme_options[ $option ][ $tab ][ $section ][ $section1 ]['custom'][ $row_id ] );
								$current    = $this->theme_options[ $option ][ $tab ][ $section ][ $section1 ]['custom'];
								$re_indexed = array_values( $current );
								$this->theme_options[ $option ][ $tab ][ $section ][ $section1 ]['custom'] = array_filter( $re_indexed );
							} else {
								unset( $this->theme_options[ $option ][ $tab ][ $section ][ $section1 ][ $row_id ] );
								$current    = $this->theme_options[ $option ][ $tab ][ $section ][ $section1 ];
								$re_indexed = array_values( $current );
								$this->theme_options[ $option ][ $tab ][ $section ][ $section1 ] = array_filter( $re_indexed );
							}
							break;
						default:
							unset( $this->theme_options[ $option ][ $tab ][ $section ][ $row_id ] );
							$current    = $this->theme_options[ $option ][ $tab ][ $section ];
							$re_indexed = array_values( $current );
							$this->theme_options[ $option ][ $tab ][ $section ] = array_filter( $re_indexed );
							break;
					}
					$this->cdp_update_option( 'theme' );
				} else {
					unset( $this->admin_options[ $option ][ $tab ][ $section ][ $row_id ] );
					$current    = $this->admin_options[ $option ][ $tab ][ $section ];
					$re_indexed = array_values( $current );
					$this->admin_options[ $option ][ $tab ][ $section ] = $re_indexed;
					if ( $dealer_id ) {
						$this->update_delete->remove_dealer_id_from_cdp_tables( $dealer_id );
						$filters = $this->admin_options[ $option ][ $tab ]['import_filters'];
						// todo future clear sort,tags.. legacy does not remove on dealer change
						if ( $filters ) {
							foreach ( $filters as $key => $filter ) {
								if ( $filter['dealer_id'] === $dealer_id ) {
									unset( $this->admin_options[ $option ][ $tab ]['import_filters'][ $key ] );
									$this->append_log( array( 'message' => 'CDP Message: Removing dealer ' . $dealer_id . 'from import filters.' ) );
								}
							}
							$current    = $this->admin_options[ $option ][ $tab ]['import_filters'];
							$re_indexed = array_values( $current );
							$this->admin_options[ $option ][ $tab ]['import_filters'] = array_filter( $re_indexed );
						}
						// todo future add a dealer_id field to banners, probably sort/tags as well.
						// $banners = $this->theme_options['theme']['inventory_display']['banners'];
						// if ($banners) {
						// foreach ($banners as $key => $banner) {
						// if ($banner['dealer_id'] == $dealer_id) {
						// unset($this->theme_options['theme']['inventory_display']['banners'][$key]);
						// error_log("CDP Message: Removing dealer " . $dealer_id . "from banners.");
						// }
						// }
						// $current = $this->theme_options['theme']['inventory_display']['banners'];
						// $re_indexed = array_values($current);
						// $this->theme_options['theme']['inventory_display']['banners'] = $re_indexed;
						// $this->cdp_update_option('theme');
						// }
						// $sort
						// $tags
						// reindex array
					}
					$this->cdp_update_option( 'admin' );
				}
				break;
			case 'fullImport':
				break;
			case 'refresh_Imports':
				if ( ! empty( $data_request['params']['dealer'] ) ) {
					$dealer            = ( new Requests() )->cdp_company_dealer_request( $data_request['params']['dealer'] );
					$output['content'] = admin_get_custom_dealers( $dealer[0] );
				}
				// admin_get_custom_dealers.
				break;
			case 'delete_Custom_Import':
				if ( ! empty( $data_request['params']['data_id'] ) ) {
					// Remove Dealer.
					( new Requests() )->delete_custom_import( $data_request['params']['data_id'] );
				}
				break;
			case 'delete_Dealer':
				if ( ! empty( $data_request['params']['dealer'] ) ) {
					// Remove Dealer.
					( new Requests() )->delete_manual_dealer( $data_request['params']['dealer'] );
				}
				break;
			case 'manual_dealer_check':
				$check = ( new Multi_Request() )->manual_dealer_check( $data_request['params']['value'] );
				if ( ! empty( $check['error'] ) ) {
					$output['key']     = 'error';
					$output['content'] = $check['error'];
				} else {
					$output['key']     = 'found';
					$output['content'] = $check['found'];
				}
				break;
			case 'check_for_dealer':
				$dealer_id = $data_request['params']['dealer_id'] ?? '0';
				$dealer    = ( new Requests() )->cdp_company_dealer_request( $dealer_id );
				$option    = Option::check_for_option(
					'cdp_theme_options',
					array(
						'theme',
						'inventory_display',
						'detail',
						'maps',
						'custom',
					)
				);
				$count     = Generic::get_count_of( $option );
				for ( $row_id = 0; $row_id <= $count; $row_id ++ ) {
					$dealer_ids[] = Option::check_for_option(
						'cdp_theme_options',
						array(
							'theme',
							'inventory_display',
							'detail',
							'maps',
							'custom',
							$row_id,
							'dealer',
							'dealer_id',
						)
					);
				}
				if ( empty( $dealer ) ) {
					$output['error']         = true;
					$output['error_message'] = "Dealer Id: $dealer_id does not exist";
				} elseif ( in_array( $dealer_id, $dealer_ids, true ) ) {
					$output['error']         = true;
					$output['error_message'] = 'Dealer Id already added';
				}
				break;
			case 'map_population':
				$option    = $data_request['params']['option'] ?? 'theme';
				$tab       = $data_request['params']['tab'] ?? '';
				$section   = $data_request['params']['section'] ?? '';
				$section1  = $data_request['params']['section1'] ?? '';
				$row_id    = $data_request['params']['rowId'] ?? '0';
				$dealer_id = $data_request['params']['dealer_id'] ?? '';
				$key       = $data_request['params']['key'] ?? '';
				$this->theme_options[ $option ][ $tab ][ $section ][ $section1 ]['key'] = $key;
				$geocodes = ( new Maps() )->map_population( $dealer_id, $key );
				foreach ( $geocodes as $index => $data ) {
					$dealer_geo = array(
						'dealer'  => array(
							'dealer_id' => $data['dealer']['dealer_id'],
							'name'      => $data['dealer']['name'],
						),
						'geocode' => $data['geocode'],
					);
					if ( 0 !== $row_id ) { // Indicates adding a dealer.
						$this->theme_options[ $option ][ $tab ][ $section ][ $section1 ]['custom'][ $row_id ] = $dealer_geo;
					} else {
						$this->theme_options[ $option ][ $tab ][ $section ][ $section1 ]['custom'][ $index ] = $dealer_geo;
					}
				}
				$this->cdp_update_option( 'theme' );
				if ( ! empty( $geocodes[0]['geocode']['error_message'] ) ) {
					$output['error']         = true;
					$output['error_message'] = $geocodes[0]['geocode']['error_message'];
				}
				$output['status'] = $geocodes[0]['geocode']['status'];

				break;
			case 'update_map_address':
				$option              = $data_request['params']['option'] ?? 'theme';
				$tab                 = $data_request['params']['tab'] ?? '';
				$section             = $data_request['params']['section'] ?? '';
				$section1            = $data_request['params']['section1'] ?? '';
				$row_id              = $data_request['params']['row_id'] ?? '0';
				$dealer_id           = $data_request['params']['dealer_id'] ?? '';
				$name                = $data_request['params']['name'] ?? '';
				$street              = $data_request['params']['street'] ?? '';
				$city                = $data_request['params']['city'] ?? '';
				$state               = $data_request['params']['state'] ?? '';
				$zip                 = $data_request['params']['zip'] ?? '';
				$zoom                = $data_request['params']['zoom'] ?? '';
				$user_edited_address = rawurlencode( $data_request['params']['address'] ) ?? '';
				$geocode             = ( new Maps() )->extender_map_get_geocode(
					array(
						'address' => $user_edited_address,
					)
				);
				$dealer_geo          = array(
					'dealer'  => array(
						'dealer_id' => $dealer_id,
						'name'      => $name,
						'street'    => $street,
						'city'      => $city,
						'state'     => $state,
						'zip'       => $zip,
						'zoom'      => $zoom,
					),
					'geocode' => $geocode,
				);
				$this->theme_options[ $option ][ $tab ][ $section ][ $section1 ]['custom'][ $row_id ] = $dealer_geo;
				$this->cdp_update_option( 'theme' );
				if ( ! empty( $geocode['error_message'] ) ) {
					$output['error']         = true;
					$output['error_message'] = $geocode['error_message'];
					$output['status']        = $geocode['status'];
				} else {
					$output['status'] = $geocode['status'];
				}
				break;
			case 'dbGetCount':
				$filters           = $data_request['params']['filters'];
				$output['id']      = '';
				$output['content'] = ( new Requests() )->cdp_admin_sort_count( $filters );
				break;
//			case 'getCurrentTheme': // not used???
//				$output['id']      = $data_request['params']['id'];
//				$output['content'] = get_admin_theme_view( $this->theme_options['vehicle_management_system']['theme'] );
//				break;
			case 'runFlush': // Help page.
				$this->append_log( array( 'message' => 'CDP Message: ###### Flush Rewrite Rules ######' ) );
				flush_rewrite_rules( true );
				break;
			case 'clearTransient': // Help page.
				$this->append_log( array( 'message' => 'CDP Message: ###### Clear Transients ######' ) );
				$blog_id = get_current_blog_id();
				delete_transient( 'cdp_manual_update_handler_processing_' . $blog_id );
				delete_transient( 'cdp_auto_update_handler_processing_' . $blog_id );
				break;
			case 'deleteCDPCronJob': // Help page.
				( new Cron() )->remove_cron_schedule();
				break;
			case 'resetInventory': // Help page.
				( new Truncate() )->cdp_inventory();
				break;
			case 'createCompanyAndInventoryTables': // Help page.
				(new Create_Tables())->all_tables();
				break;
			case 'alterTables': // Help page.
				( new Alter_Tables( array( 'force' => true ) ) );
				break;
			case 'showCompaniesTableColumns': // Help page.
				$results = ( new Requests() )->cdp_show_companies_table_columns();
				foreach ( $results as $result ) {
					$column[] = $result['Field'];
				}
				$this->append_log( array( 'message' => 'CDP Message: Companies table Columns ' . wp_json_encode( $column ) ) );
				//$this->append_log( array( 'message' => 'CDP Message: Companies table ' . wp_json_encode( $results ) ) );
				break;
			case 'showCompaniesTable': // Help page.
				$results = ( new Requests() )->cdp_cdp_companies_request();
//				foreach ( $results as $result ) {
//					$column[] = $result['Field'];
//				}
				//$this->append_log( array( 'message' => 'CDP Message: Companies table ' . wp_json_encode( $column ) ) );
				$this->append_log( array( 'message' => 'CDP Message: Companies table ' . wp_json_encode( $results ) ) );
				break;
			case 'showGrants': // Help page.
				$results = ( new Requests() )->cdp_show_grants();
				$this->append_log( array( 'message' => 'CDP Message: Show Grants ' . wp_json_encode( $results ) ) );
				break;
			case 'runCleanReset': // Help page, used for development purposes.
				$this->append_log( array( 'message' => 'CDP Message: ###### Clean Reset ######' ) );
				( new Update_Delete() )->reset_tables( helpers::company_id() );
				$blog_id = get_current_blog_id();
				Option::delete_options(
					array(
						'blog_id'     => $blog_id,
						'clean_reset' => true,
					)
				);
				// FIXME
				// Works as long as plugin isn't network active.
				// If plugin is network active, then says it deactivates on site, but still stays its active.
				deactivate_plugins( 'cardealerpress/cardealerpress.php', false, false );
				break;
			case 'generateKeywordPot':
				$keywords_array = array();
				$content        = $keywords = '';
				$output['id']   = $data_request['params']['id'];

				$keywords_array = $this->get_default_keywords();
				$this->remove_unwanted_keywords( $keywords_array );
				$this->append_additonal_keywords( $keywords_array );
				if ( ! empty( $keywords_array ) ) {
					$keywords = implode( ',', $keywords_array );
				}

				$this->theme_options['theme']['inventory_display']['list']['keywords']['pot'] = $keywords;
				$this->cdp_update_option( 'theme' );

				if ( $keywords_array ) {
					$content .= '<select class="basic-multiple keyword-list" name="cdp_theme_options[theme][inventory_display][list][keywords][pot][]" multiple="multiple">';
					foreach ( $keywords_array as $word ) {
						$content .= '<label for=' . $word . '>';
						$content .= '<option value="' . $word . '"/>' . $word . '</option>';
					}
					$content .= '</select>';
				}

				$output['content'] = $content;
				break;
			default:
				$output['error'] = 'That is not a valid FN parameter. Please check your string and try again.';
				break;
		}

		echo wp_json_encode( $output );
		wp_die();
	}

	public function cdp_remove_cookies() {
		foreach ( $_COOKIE as $key => $value ) {
			if ( strpos( $key, 'vehicleSave' ) !== false ) {
				setcookie( $key, $value, time() - 3600, '/' );
			}
		}
	}

	public function set_options_value( $path, $value ) {
		if ( ! $path ) {
			return null;
		}

		$segments = is_array( $path ) ? $path : explode( '/', $path );
		$cur      =& $this->theme_options;
		foreach ( $segments as $segment ) {
			if ( strpos( $segment, '[]' ) ) {
				$segmentR = str_replace( '[]', '', $segment );
				$cur      =& $cur[ $segmentR ][];
			} else {
				if ( ! isset( $cur[ $segment ] ) ) {
					$cur[ $segment ] = array();
				}
				$cur =& $cur[ $segment ];
			}
		}
		$cur = $value;
	}

	private function cdp_update_option( $option ) {
		$full_option_name = $option . '_options';
		wp_cache_delete( 'alloptions', 'options' );
		update_option( 'cdp_' . $option . '_options', $this->$full_option_name );
	}

	public function flexDefaults() {
		$flex = array();

		// Cobra.
		$flex = array(
			'containers' => array(
				'one'   => array(
					'order'     => 1,
					'max-width' => 590,
				),
				'two'   => array(
					'order'     => 1,
					'max-width' => 590,
				),
				'three' => array(
					'order'     => 1,
					'max-width' => 590,
				),
				'four'  => array(
					'order'     => 1,
					'max-width' => 590,
				),
				'five'  => array(
					'order'     => 1,
					'max-width' => 590,
				),
				'six'   => array(
					'order'     => 1,
					'max-width' => 590,
				),
			),
		);

		return $flex;
	}

	public function get_default_keywords() {
		$keyword_request = 'https://api.dealertrend.com/api/companies/' . helpers::company_id() . '/vehicles.json';
		$keyword_handler = new Http_Request( $keyword_request, 'vehicle_keyword' );
		$response        = $keyword_handler->get_file();
		$keyword_data    = isset( $response['body'] ) ? json_decode( $response['body'] ) : array();

		$keyword_array = array();
		$item_array    = array( 'make', 'model', 'trim' );
		if ( ! empty( $keyword_data ) ) {
			foreach ( $item_array as $item ) {
				foreach ( $keyword_data as $data ) {
					if ( ! in_array( $data->$item, $keyword_array, true ) && ! empty( $data->$item ) ) {
						$keyword_array[] = trim( $data->$item );
					}
				}
			}
		}

		return $keyword_array;
	}

	public function remove_unwanted_keywords( &$keywords ) {
		if ( ! empty( $keywords ) && is_array( $keywords ) ) {
			$exclude_string = ! empty( $this->theme_options['theme']['inventory_display']['list']['keywords']['exclude'] ) ? $this->theme_options['theme']['inventory_display']['list']['keywords']['exclude'] : '';
			if ( ! empty( $exclude_string ) ) {
				$exclude = explode( ',', $exclude_string );
				foreach ( $keywords as $key => $word ) {
					foreach ( $exclude as $unwanted ) {
						if ( $word === $unwanted ) {
							unset( $keywords[ $key ] );
						}
					}
				}
			}
		}
	}

	public function append_additonal_keywords( &$keywords ) {
		if ( ! empty( $keywords ) && is_array( $keywords ) ) {
			$add_string = ! empty( $this->theme_options['theme']['inventory_display']['list']['keywords']['add'] ) ? $this->theme_options['theme']['inventory_display']['list']['keywords']['add'] : '';
			if ( ! empty( $add_string ) ) {
				$add = explode( ',', $add_string );
				foreach ( $add as $new ) {
					$keywords[] = trim( $new );
				}
			}
		}
	}
}
