<?php

namespace CarDealerPress\Includes\Database;

use CarDealerPress\Includes\Functions\Fn_Inventory;
use CarDealerPress\Includes\Functions\Logger;
use CarDealerPress\Includes\Functions\Dealertrend_API;
use CarDealerPress\Includes\Helpers\{Generic, Option, Remote_Requests};
use WpOrg\Requests\Exception;
use WpOrg\Requests\Requests;

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

class Inventory_Handler {
	use Logger;

	private $purge;
	private static $wpdb;
	private static $blog;
	public $page_count;
	public $table_data;
	public $sort_data;
	public $dealer;
	public $company_id;
	public $theme_options;
	public $admin_options;
	private int $total_count;
	private array $vehicle_data;
	public Fn_Inventory $fn_inventory;

	public function __construct() {
		global $wpdb;
		self::$wpdb          = $wpdb;
		self::$blog          = get_current_blog_id();
		$this->theme_options = Option::get_cdp_theme_options();
		$this->admin_options = Option::get_cdp_admin_options();
		$this->fn_inventory  = new Fn_Inventory();
		add_action( 'process_single_dealer_event', array( $this, 'process_dealer' ), 10, 2 );
		add_action( 'cdp_process_page_batch_event', array( $this, 'process_page_batch' ), 10, 7 );
	}

	public function init_inventory_handler( $dealer_id = 0, $purge = false ) {
		$transient_key = 'cdp_auto_dealer_processing_' . self::$blog;

		if ( get_transient( $transient_key ) ) {
			$this->append_log( [ 'message' => 'CDP Message: Auto Updater is already running' ] );

			return;
		}

		set_transient( $transient_key, 'Running', 120 );

		$sql_query = "SELECT * FROM " . CDP_COMPANIES . " WHERE blog_id = %d";
		$params    = [ self::$blog ];

		if ( $dealer_id !== 0 ) {
			$sql_query .= " AND dealer_id = %d";
			$params[]  = $dealer_id;
		}

		// @codingStandardsIgnoreStart
		$prepared = self::$wpdb->prepare( $sql_query, ...$params );
		$dealers  = self::$wpdb->get_results( $prepared, ARRAY_A );
		// @codingStandardsIgnoreEnd
		$delay = 0;
		foreach ( $dealers as $dealer ) {
			if ( ! empty( unserialize($dealer['automalls'], ['allowed_classes' => false]) ) ) {
				$this->append_log( [ 'message' => 'CDP Message: Auto Update has dealer ' . $dealer['dealer_id'] . ' as a main automall account. Will not update.' ] );
				continue;
			}
			if ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ) {
				// FALLBACK: Cron is disabled.
				$this->append_log( [ 'message' => 'CDP Message: WP Cron disabled or not found. Can cause issues with large automalls.' ] );
				$this->process_dealer( $dealer, $purge );
			} else {
				// NORMAL: Schedule as background task
				wp_schedule_single_event( time() + $delay, 'process_single_dealer_event', array( $dealer, $purge ) );
			}

			$delay += 10;
		}

		delete_transient( $transient_key );
	}

	public function process_dealer( $dealer, $purge ): void {
		$this->append_log( [ 'message' => 'CDP Message: Inventory Handler | Checking dealer: ' . $dealer['name'] . '-' . $dealer['dealer_id'] ] );

		$this->dealer     = $dealer;
		$this->company_id = $dealer['company_id'];

		$api_params = Generic::api_vehicles_params( [ 'dealer_id' => $dealer['dealer_id'] ] );
		$this->append_log( [ 'message' => 'CDP Message: Auto Update Checking Update for Dealer - ' . $dealer['dealer_id'] . ' - params: ' . $api_params ] );

		$response      = Remote_Requests::http_get_file( $api_params, $purge );
		$response_code = $response['status_code'] ?? 0; // sometimes the status code doesn't exist???

		if ( $response_code === 200 ) {
			$current_inventory_api_last_modified = isset( $response['last_modified'] ) ? wp_date( 'c', strtotime( $response['last_modified'] ) ) : 0;

			if ( strtotime( $dealer['inventory_api_last_modified'] ) < strtotime( $current_inventory_api_last_modified ) || $purge ) {
				$message = 'CDP Message: API Last Modified change | Dealer - ';
				$message .= $dealer['dealer_id'] . ' | ';
				$message .= 'Previous API Last Modified - ' . $dealer['inventory_api_last_modified'] . ', | ';
				$message .= 'Current API Last Modified - ' . wp_date( 'Y-m-d H:i', strtotime( $response['last_modified'] ) ) . ' | ';
				$this->append_log( [ 'message' => $message ] );
				$this->process_vehicles( [
					'response'                            => $response,
					'dealer'                              => $dealer,
					'current_inventory_api_last_modified' => $current_inventory_api_last_modified,
					'purge'                               => $purge
				] );
			} else {
				$this->append_log( [ 'message' => 'CDP Message: Inventory Handler | No changes to inventory for dealer: ' . $dealer['name'] . '-' . $dealer['dealer_id'] ] );
				( new Update_Delete() )->update_companies_table_with_last_modified( array(
					'dealer_id'              => $dealer['dealer_id'],
					'inventory_last_checked' => wp_date( "c" ), //Last Checked API
				) );
			}
		} elseif ( $response_code === 304 ) {
			$this->append_log( [ 'message' => 'CDP Message: Auto Update Response 304: Not Modified, nothing to do.' ] );
		} elseif ( $response_code === 403 ) {
			$this->append_log( [ 'message' => 'CDP Message: Dealer id: ' . $dealer['dealer_id'] . ' Suspended, removing inventory' ] );
			( new Update_Delete() )->remove_company_id_from_table( [
				'dealer_id' => $dealer['dealer_id'],
				'table'     => CDP_INVENTORY_TABLE
			] );
		} else {
			$this->append_log( [
				'message' => 'CDP Message: Auto Update check failed | ' . $dealer['dealer_id'] . ' | response code: ' . $response_code . '| url: ' . $api_params
			] );
		}

	}

	public function process_vehicles( $args ) {
		$dealer_id                           = $args['dealer']['dealer_id'] ?? 0;
		$response                            = $args['response'] ?? array();
		$current_inventory_api_last_modified = $args['current_inventory_api_last_modified'] ?? 0;
		$purge                               = $args['purge'] ?? false;
		$response_data                       = isset( $response['body'] ) ? json_decode( $response['body'] ) : array();
		$this->total_count                   = is_array( $response_data ) && isset( $response_data[0] ) && count( $response_data ) > 0 ? $response_data[0]->pagination->total : 0;
		$this->page_count                    = ( $this->total_count > 0 ? $this->total_count : 0 );

		if ( $this->page_count === 0 ) {
			return;
		}

		// Clear the import table once before scheduling page batches.
		self::$wpdb->delete(CDP_INVENTORY_IMPORT_TABLE, ['dealer_id' => $dealer_id], ['%d']);

		// Schedule the first page batch. Each batch will chain to the next, and the
		// final batch will run finalize — same pattern used for per-dealer scheduling.
		wp_schedule_single_event( time(), 'cdp_process_page_batch_event', array(
			$dealer_id,
			1,
			$this->page_count,
			$purge,
			$this->company_id,
			$this->dealer,
			$current_inventory_api_last_modified,
		) );
	}

	public function process_page_batch( $dealer_id, $current_page, $total_pages, $purge, $company_id, $dealer, $last_modified ): void {
		// phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged
		set_time_limit( 60 );

		$this->dealer     = $dealer;
		$this->company_id = $company_id;

		// Fetch this batch of pages in parallel.
		$batch_size   = 5;
		$page_end     = min( $current_page + $batch_size - 1, $total_pages );
		$page_numbers = range( $current_page, $page_end );
		$urls         = array_map(
			fn( $page ) => Dealertrend_API::api_vehicles_url( [ 'dealer_id' => $dealer_id, 'page' => $page ] ),
			$page_numbers
		);

		$headers = [ 'Referer' => site_url() ];
		if ( $purge ) {
			$headers['fastly-soft-purge'] = 1;
		}
		$options  = [ 'headers' => $headers, 'type' => $purge ? 'PURGE' : 'GET' ];
		$vehicles = [];

		try {
			$requests  = array_map( fn( $url ) => [ 'url' => $url ], $urls );
			$responses = Requests::request_multiple( $requests, $options );

			foreach ( $responses as $i => $response ) {
				$page_num = $page_numbers[ $i ];
				if ( ! empty( $response ) && is_a( $response, 'WpOrg\\Requests\\Response' ) && $response->status_code === 200 ) {
					$decoded = json_decode( $response->body, true );
					if ( is_array( $decoded ) && ! empty( $decoded ) ) {
						$vehicles = array_merge( $vehicles, $decoded );
						$this->append_log( [ 'message' => "CDP Message: Page Batch Success | page: $page_num" ] );
					} else {
						$this->append_log( [ 'message' => "CDP Message: Page Batch Empty | page: $page_num" ] );
					}
				} else {
					$status = is_a( $response, 'WpOrg\\Requests\\Response' ) ? $response->status_code : 'empty';
					$this->append_log( [ 'message' => "CDP Message: Page Batch Failed | code: $status | page: $page_num" ] );
					$this->retry_page( $page_num, $dealer_id, $vehicles );
				}
				unset( $response->body, $response );
			}
		} catch ( Exception $e ) {
			$this->append_log( [ 'message' => "CDP Page Batch Exception: {$e->getMessage()}" ] );
		}

		// Insert this batch into the import table.
		if ( ! empty( $vehicles ) ) {
			$flattened = array_map( [ $this, 'flatten_vehicle' ], $vehicles );
			unset( $vehicles );
			$this->build_inventory_table_data( $flattened );
			unset( $flattened );
			( new Inserts() )->populate_inventory_import_tables( array(
				'dealer_id'  => $dealer_id,
				'data'       => $this->table_data,
				'company_id' => $company_id,
			) );
			$this->table_data = [];
		}

		$next_page = $page_end + 1;
		if ( $next_page <= $total_pages ) {
			// Chain to the next batch.
			wp_schedule_single_event( time(), 'cdp_process_page_batch_event', array(
				$dealer_id,
				$next_page,
				$total_pages,
				$purge,
				$company_id,
				$dealer,
				$last_modified,
			) );
			$this->append_log( [ 'message' => "CDP Message: Page Batch scheduled next | page: $next_page of $total_pages" ] );
		} else {
			// All pages fetched and inserted — finalize.
			$this->finalize_dealer_import( $dealer_id, $company_id, $last_modified );
		}
	}

	private function retry_page( int $page_num, $dealer_id, array &$vehicles ): void {
		sleep( 1 );
		$retry_url      = Dealertrend_API::api_vehicles_url( [ 'page' => $page_num, 'dealer_id' => $dealer_id ] );
		$retry_response = wp_remote_get( $retry_url, [ 'headers' => [ 'Referer' => site_url() ], 'timeout' => 30 ] );
		$retry_code     = wp_remote_retrieve_response_code( $retry_response );
		if ( $retry_code === 200 ) {
			$decoded = json_decode( wp_remote_retrieve_body( $retry_response ), true );
			if ( is_array( $decoded ) ) {
				$vehicles = array_merge( $vehicles, $decoded );
				$this->append_log( [ 'message' => "CDP Message: Page Batch Retry SUCCESS | page: $page_num" ] );
			}
		} else {
			$this->append_log( [ 'message' => "CDP Message: Page Batch Retry FAILED | code: $retry_code | page: $page_num" ] );
		}
		unset( $retry_response );
	}

	private function finalize_dealer_import( $dealer_id, $company_id, $last_modified ): void {
		// phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged
		set_time_limit( 60 );
		$this->append_log( [ 'message' => "CDP Message: Finalizing import for dealer: $dealer_id" ] );
		( new Update_Delete() )->remove_inventory_import_duplicates( array(
			'dealer_id'  => $dealer_id,
			'company_id' => $company_id,
		) );
		( new Update_Delete() )->remove_company_id_from_table( array(
			'dealer_id' => $dealer_id,
			'table'     => CDP_INVENTORY_TABLE,
		) );
		( new Inserts() )->copy_import_to_inventory_table( $company_id, $dealer_id );
		$this->update_live_table();
		( new Update_Delete() )->update_companies_table_with_last_modified( array(
			'dealer_id'                   => $dealer_id,
			'inventory_api_last_modified' => $last_modified,
			'inventory_last_updated'      => wp_date( 'c' ),
			'inventory_last_checked'      => wp_date( 'c' ),
		) );
		$this->append_log( [ 'message' => "CDP Message: Import finalized for dealer: $dealer_id" ] );
	}

	public function flatten_vehicle( $vehicle ) {
		$result = [];

		$split_keys = [ 'contact_info', 'carfax' ];
		$skip_keys  = array_flip( [ 'icons', 'pricing', 'pagination' ] ); // Flip for faster lookup

		foreach ( $vehicle as $key => $value ) {
			if ( isset( $skip_keys[ $key ] ) ) {
				continue;
			}

			if ( is_array( $value ) && in_array( $key, $split_keys, true ) ) {
				foreach ( $value as $sub_key => $sub_value ) {
					$result_key            = ( $key === 'carfax' ) ? "carfax_$sub_key" : $sub_key;
					$result[ $result_key ] = $sub_value ?? ''; // Use `??` instead of ternary
				}
				continue;
			}

			if ( $key === 'photos' && ! empty( $value[0] ) ) {
				$result['image_medium'] = $value[0]['medium'] ?? '';
				$result['thumbnail']    = $value[0]['small'] ?? '';
				continue;
			}

			if ( $key === 'id' ) {
				$result['vms_id'] = $value;
				continue;
			}

			$result[ $key ] = $value ?? '';
		}

		return $result;
	}


	public function build_inventory_table_data( $flattened_vehicles ) {
		$this->table_data = array();
		if ( ! empty( $flattened_vehicles ) ) {
			foreach ( $flattened_vehicles as $index => $vehicle ) {
				$dealer_id        = ( $vehicle['company_id'] ?? '' );
				$vms_id           = ( $vehicle['vms_id'] ?? 0 );
				$stock            = ( $vehicle['stock_number'] ?? '' );
				$vin              = ( $vehicle['vin'] ?? '' );
				$saleclass        = ( isset( $vehicle['saleclass'] ) ? strtolower( $vehicle['saleclass'] ) : '' );
				$make             = ( preg_replace( "/[^A-Za-z0-9\- ]/", '', $vehicle['make'] ) ?? '' );
				$model            = ( preg_replace( "/[^A-Za-z0-9\- ]/", '', $vehicle['model_name'] ) ?? '' );
				$model_code       = ( $vehicle['model_code'] ?? '' );
				$trim             = ( $vehicle['trim'] ?? '' );
				$year             = ( $vehicle['year'] ?? '' );
				$exterior         = ( $vehicle['exterior_color'] ?? '' );
				$interior         = ( $vehicle['interior_color'] ?? '' );
				$color_map        = '';
				$body             = ( $vehicle['body_style'] ?? '' );
				$vehicleclass     = ( $vehicle['vehicleclass'] ?? '' );
				$tags             = ( ! empty( $vehicle['tags'] ) ? implode( ',', $vehicle['tags'] ) : '' );
				$prices           = ( $vehicle['prices'] ?? array() );
				$drivetrain       = ( $vehicle['drive_train'] ?? '' );
				$video            = ( $vehicle['video_url'] ?? '' );
				$doors            = ( $vehicle['doors'] ?? '' );
				$engine           = ( $vehicle['engine'] ?? '' );
				$transmission     = ( $vehicle['transmission'] ?? '' );
				$fuel             = ( isset( $vehicle['fuel_type'] ) ? ( 'N/A' == $vehicle['fuel_type'] ? '' : $vehicle['fuel_type'] ) : '' );
				$fuel_economy     = ( $vehicle['fuel_economy'] ?? array() );
				$odometer         = ( $vehicle['odometer'] ?? '' );
				$carfax           = ( $vehicle['carfax_url'] ?? '' );
				$carfax_image_url = ( $vehicle['carfax_image_url'] ?? '' );
				$autocheck        = ( $vehicle['auto_check_url'] ?? '' );
				$photos           = ( $vehicle['photos'] ?? array() );
				$headline         = ( isset( $vehicle['headline'] ) ? substr( $vehicle['headline'], 0, 512 ) : '' );
				$description      = ( $vehicle['description'] ?? '' );
				$certified        = ( isset( $vehicle['certified_bool'] ) && true == $vehicle['certified_bool'] ? 1 : 0 );
				$created          = ( $vehicle['created_at'] ?? '' );
				$updated          = ( $vehicle['updated_at'] ?? '' );
				$sold_on          = ( $vehicle['sold_on'] ?? null );
				$acode            = ( $vehicle['ads_acode'] ?? '' );
				$location         = ( $vehicle['vehicle_location'] ?? '' );
				$blog_id          = get_current_blog_id();
				$payment          = 0;
				$sortprice        = 0;
				// Find sortprice lowest value.
				if ( ! empty( $prices ) ) {
					if ( isset( $prices['sale_price'] ) ) {
						$sortprice = ( 0 !== $prices['sale_price'] && $prices['sale_price'] < $prices['asking_price'] ? $prices['sale_price'] : $prices['asking_price'] );
					} elseif ( isset( $prices['asking_price'] ) ) {
						$sortprice = $prices['asking_price'];
					}
					$payment_calculator = Option::check_for_option( 'cdp_theme_options', array(
						'theme',
						'inventory_display',
						'payment_calculator'
					) );
					if ( 'on' === $payment_calculator[ $saleclass ]['default']['display_payment'] ) {
						$loan_parameters = array(
							'make'      => $make,
							'model'     => $model,
							'trim'      => $trim,
							'year'      => $year,
							'saleclass' => $saleclass,
						);
						$all_prices      = $this->fn_inventory->get_prices( array(
							'saleclass'   => $saleclass,
							'retailprice' => $prices['retail_price'],
							'askingprice' => $prices['asking_price'],
							'saleprice'   => $prices['sale_price']
						) );
						$payment         = $this->fn_inventory->get_payment( $payment_calculator, $all_prices['main_price'], $loan_parameters );
					}
				}

				// Edge Case.
				$extra = ( 'sport utility' === strtolower( $vehicleclass ) ? 'SUV ' : '' );
				$extra .= ( 'chevrolet' === strtolower( $make ) ? 'Chevy ' : '' );
				$extra .= ( 'f-150' === strtolower( $model ) ? 'F150 ' : '' );

				$vehicle_url = ( $vehicle['vehicle_url'] ?? '' );

				$askingprice  = ( $prices['asking_price'] ?? 0 );
				$saleprice    = ( $prices['sale_price'] ?? 0 );
				$retailprice  = ( $prices['retail_price'] ?? 0 );
				$msrp         = ( $prices['msrp'] ?? 0 );
				$invoice      = ( $prices['invoice'] ?? 0 );
				$sale_expire  = ( $prices['sale_expire'] ?? 0 );
				$highway      = ( $fuel_economy['highway'] ?? 0 );
				$city         = ( $fuel_economy['city'] ?? 0 );
				$thumbnail    = ( $vehicle['thumbnail'] ?? '' );
				$image_medium = ( $vehicle['image_medium'] ?? '' );

				$this->table_data[] = array(
					'blog_id'          => $blog_id,
					'vms_id'           => $vms_id,
					'company_id'       => $this->company_id,
					'dealer_id'        => $dealer_id,
					'dealer'           => ( $this->dealer['name'] ?? '' ),
					'stock'            => $stock,
					'vin'              => $vin,
					'saleclass'        => $saleclass,
					'certified'        => $certified,
					'make'             => $make,
					'model'            => $model,
					'model_code'       => $model_code,
					'trim'             => $trim,
					'year'             => $year,
					'askingprice'      => $askingprice,
					'saleprice'        => $saleprice,
					'retailprice'      => $retailprice,
					'msrp'             => $msrp,
					'invoice'          => $invoice,
					'sortprice'        => $sortprice,
					'pricesort'        => 0,
					'sale_expire'      => $sale_expire,
					'headline'         => $headline,
					'description'      => $description,
					'exterior'         => $exterior,
					'interior'         => $interior,
					'color_map'        => '', // Gets set on own update.
					'color_map_int'    => '', // Gets set on own update.
					'body'             => $body,
					'vehicleclass'     => $vehicleclass,
					'tags'             => ( empty( $tags ) ? '' : $tags ),
					'drivetrain'       => $drivetrain,
					'doors'            => $doors,
					'engine'           => $engine,
					'transmission'     => $transmission,
					'fuel_type'        => $fuel,
					'highway'          => $highway,
					'city'             => $city,
					'odometer'         => $odometer,
					'carfax'           => $carfax,
					'carfax_image_url' => $carfax_image_url,
					'autocheck'        => $autocheck,
					'video'            => $video,
					'acode'            => $acode,
					'thumbnail'        => $thumbnail,
					'image_medium'     => $image_medium,
					'geo_state'        => ( $this->dealer['state'] ?? '' ),
					'geo_city'         => ( $this->dealer['city'] ?? '' ),
					'geo_zip'          => ( $this->dealer['zip'] ?? '' ),
					'location'         => $location,
					'phone'            => ( $this->dealer['phone'] ?? '' ),
					'created'          => $created,
					'updated'          => $updated,
					'sold_on'          => $sold_on,
					'sort'             => 0,
					'extra'            => $extra,
					'vehicle_url'      => $vehicle_url,
					'payment'          => $payment,
				);
			}
		}
	}

	public function update_live_table() {
		$this->run_custom_imports();
		$filters      = $this->theme_options['theme']['inventory_display']['list']['search_filters']['general']['filters'];
		$search_value = 'color';
		$search_key   = 'name';
		$column       = array_column( $filters, $search_key );
		$index        = array_search( $search_value, $column );
		// Update Color.
		if ( 'on' === $filters[ $index ]['display'] ) {
			$this->init_inventory_color_update();
		}
		// Update PriceSort
		$sql = 'UPDATE ' . CDP_INVENTORY_TABLE . ' SET pricesort = 99 WHERE sortprice = 0 AND company_id = ' . $this->company_id . ' AND blog_id = ' . self::$blog . ' AND dealer_id = ' . $this->dealer['dealer_id'];
		// @codingStandardsIgnoreStart
		self::$wpdb->query( $sql );
		// @codingStandardsIgnoreEnd
		// Reset PriceSort.
		$sql = 'UPDATE ' . CDP_INVENTORY_TABLE . ' SET pricesort = 0 WHERE pricesort = 99 and sortprice <> 0 AND company_id = ' . $this->company_id . ' AND blog_id = ' . self::$blog . ' AND dealer_id = ' . $this->dealer['dealer_id'];
		// @codingStandardsIgnoreStart
		self::$wpdb->query( $sql );
		// @codingStandardsIgnoreEnd
	}

	public function run_custom_imports() {
		$skip_custom_import = false;
		// @codingStandardsIgnoreStart
		$import_id = self::$wpdb->get_results(
			self::$wpdb->prepare(
				'SELECT dealer_id FROM ' . CDP_INVENTORY_IMPORT_TABLE . ' WHERE blog_id = %d AND dealer_id = %d GROUP BY dealer_id',
				self::$blog,
				$this->dealer['dealer_id']
			),
			ARRAY_A
		);
		// @codingStandardsIgnoreEnd
		if ( ! empty( $import_id ) ) {
			// Delete Sold Vehicles | Custom Not Needed.
			$query = 'SELECT ID FROM ' . CDP_INVENTORY_TABLE . ' WHERE ' . CDP_INVENTORY_TABLE . '.company_id = ' . $this->company_id . ' AND ' . CDP_INVENTORY_TABLE . '.blog_id = ' . self::$blog . ' AND ' . CDP_INVENTORY_TABLE . '.dealer_id = ' . $this->dealer['dealer_id'] . ' AND ' . CDP_INVENTORY_TABLE . '.vms_id NOT IN( SELECT a.vms_id FROM ' . CDP_INVENTORY_IMPORT_TABLE . ' as a WHERE ' . CDP_INVENTORY_TABLE . '.company_id = a.company_id AND a.blog_id = ' . self::$blog . ' AND ' . CDP_INVENTORY_TABLE . '.dealer_id = a.dealer_id GROUP BY a.vms_id)';
			// @codingStandardsIgnoreStart
			$remove = self::$wpdb->get_results( $query, ARRAY_A );
			// @codingStandardsIgnoreEnd
			if ( $remove ) {
				foreach ( $remove as $row ) {
					$table        = CDP_INVENTORY_TABLE;
					$where        = array( 'id' => $row['ID'] );
					$where_format = array( '%d' );
					// @codingStandardsIgnoreStart
					self::$wpdb->delete( $table, $where, $where_format );
					// @codingStandardsIgnoreEnd
				}
			}
			// Removes Out Dated Vehicles, meaning they need to be updated with new data.
			$query = 'SELECT ID FROM ' . CDP_INVENTORY_TABLE . ' WHERE ' . CDP_INVENTORY_TABLE . '.company_id = ' . $this->company_id . ' AND ' . CDP_INVENTORY_TABLE . '.blog_id = ' . self::$blog . ' AND ' . CDP_INVENTORY_TABLE . '.dealer_id = ' . $this->dealer['dealer_id'] . ' AND ' . CDP_INVENTORY_TABLE . '.vms_id IN( SELECT a.vms_id FROM (SELECT vms_id, updated FROM ' . CDP_INVENTORY_TABLE . ' WHERE company_id = ' . $this->company_id . ' AND blog_id = ' . self::$blog . ' AND dealer_id = ' . $this->dealer['dealer_id'] . ') as a JOIN ' . CDP_INVENTORY_IMPORT_TABLE . ' b ON a.vms_id = b.vms_id WHERE a.updated <> b.updated GROUP BY a.vms_id)';
			// @codingStandardsIgnoreStart
			$remove = self::$wpdb->get_results( $query, ARRAY_A );
			// @codingStandardsIgnoreEnd
			if ( $remove ) {
				foreach ( $remove as $row ) {
					$table        = CDP_INVENTORY_TABLE;
					$where        = array( 'id' => $row['ID'] );
					$where_format = array( '%d' );
					// @codingStandardsIgnoreStart
					self::$wpdb->delete( $table, $where, $where_format );
					// @codingStandardsIgnoreEnd
				}
			}

			// Get custom imports.
			$import_filters = $this->admin_options['admin']['advanced']['import_filters'];
			$import_filter  = array();

			if ( empty( $import_filters ) ) {
				$skip_custom_import = true;
			} else {
				foreach ( $import_filters as $key => $filter ) {
					if ( $filter['dealer_id'] === $import_id[0]['dealer_id'] ) {
						$import_filter = $filter;
					}
				}
			}

			$insert_columns = 'blog_id, vms_id, company_id, dealer_id, dealer, stock, vin, saleclass, certified, make,';
			$insert_columns .= ' model, model_code, trim, year, askingprice, saleprice, retailprice, msrp, invoice, sortprice, pricesort, sale_expire,';
			$insert_columns .= ' headline, description, exterior, interior, color_map, body, vehicleclass, tags, drivetrain, doors, engine,';
			$insert_columns .= ' transmission, fuel_type, highway, city, odometer, carfax, carfax_image_url, autocheck, video, acode, thumbnail, image_medium,';
			$insert_columns .= ' geo_state, geo_city, geo_zip, location, phone, created, updated, sold_on, sort, extra, vehicle_url, payment';

			$custom_query = $skip_custom_import ? '' : $this->build_custom_import_query( $import_filter );
			$query        = 'SELECT ' . $insert_columns . ' FROM ' . CDP_INVENTORY_IMPORT_TABLE;
			$query        .= ' as z WHERE z.vms_id NOT IN( SELECT a.vms_id FROM ' . CDP_INVENTORY_TABLE;
			$query        .= ' as a WHERE z.company_id = a.company_id and z.dealer_id = a.dealer_id AND a.blog_id = ' . self::$blog;
			$query        .= ' ' . $custom_query . ' GROUP BY a.vms_id ) ' . $custom_query;
			// @codingStandardsIgnoreStart
			$new_rows = self::$wpdb->get_results( $query, ARRAY_A );
			// @codingStandardsIgnoreEnd
			if ( $new_rows ) {
				$count = count( $new_rows );
				$i     = 0;
				do {
					// @codingStandardsIgnoreStart
					self::$wpdb->insert( CDP_INVENTORY_TABLE . '', $new_rows[ $i ] );
					// @codingStandardsIgnoreEnd
					$i ++;
				} while ( $i < $count );
				unset( $new_rows );
			}
		}
	}

	public function init_inventory_color_update() {
		$vehicles = ( new \CarDealerPress\Includes\Database\Requests() )->cdp_inventory_special_request( 'id,exterior' );
		if ( $vehicles ) {
			foreach ( $vehicles as $key => $values ) {
				$color = $this->exterior_color_mapping( $values['exterior'] );
				// @codingStandardsIgnoreStart
				$updated = self::$wpdb->update( CDP_INVENTORY_TABLE, array( 'color_map' => $color ), array( 'id' => $values['id'] ), array( '%s' ), array( '%d' ) );
				// @codingStandardsIgnoreEnd
				if ( false === $updated ) {
					$this->append_log(
						array(
							'message' => 'CDP Message: CDP Color Map error on ID ' . $values['id'],
							'type'    => 'ERROR',
						)
					);
				}
			}
		}
		// Copies logic for Exterior Color Map but for Interior.
		$vehicles = ( new \CarDealerPress\Includes\Database\Requests() )->cdp_inventory_special_request( 'id,interior' );
		if ( $vehicles ) {
			foreach ( $vehicles as $key => $values ) {
				$color = $this->exterior_color_mapping( $values['interior'] );
				// @codingStandardsIgnoreStart
				$updated = self::$wpdb->update( CDP_INVENTORY_TABLE, array( 'color_map_int' => $color ), array( 'id' => $values['id'] ), array( '%s' ), array( '%d' ) );
				// @codingStandardsIgnoreEnd
				if ( false === $updated ) {
					$this->append_log(
						array(
							'message' => 'CDP Message: CDP Color Map error on ID ' . $values['id'],
							'type'    => 'ERROR',
						)
					);
				}
			}
		}
	}

	public function exterior_color_mapping( $color ) {
		$default_color = ( $this->theme_options['theme']['inventory_display']['list']['search_filters']['color_mapping']['default_text'] ?? 'Unknown' );
		if ( empty( $color ) ) {
			return $default_color;
		} else {
			$color_map = '';
			$color     = strtolower( $color );
			foreach ( $this->theme_options['theme']['inventory_display']['list']['search_filters']['color_mapping']['exterior'] as $key => $values ) {
				if ( empty( $color_map ) ) {
					$color_search = explode( ',', $values );
					foreach ( $color_search as $needle ) {
						$needle = trim( $needle );
						$pos    = strpos( $color, strtolower( $needle ) );
						if ( false !== $pos ) {
							$color_map = ucfirst( $key );
							break;
						}
					}
				} else {
					break;
				}
			}
			if ( empty( $color_map ) ) {
				return $default_color;
			} else {
				return $color_map;
			}
		}
	}

	public function build_custom_import_query( $import ) {
		$custom_string = '';
		$search        = '';
		$clean_data    = array();
		if ( ! empty( $import ) ) {
			$custom = $import;
			// Build custom saleclass.
			if ( ! ( 'all' === $custom['saleclass'] ) ) {
				if ( 'certified' === $custom['saleclass'] ) {
					$custom_string .= ' AND saleclass = "used" AND certified = 1';
				} else {
					$custom_string .= ' AND saleclass = "' . $custom['saleclass'] . '"';
				}
			}
			// Build custom make.
			if ( ! empty( $custom['makes'] ) ) {
				$data   = explode( ',', $custom['makes'] );
				$symbol = $this->get_custom_import_symbol( $custom['make_qualifier'] );
				// Clean white space.
				foreach ( $data as $value ) {
					$clean_data[] = trim( $value );
				}
				$search        = ' AND make ' . $symbol . ' ("' . implode( '","', $clean_data ) . '") ';
				$custom_string .= $search;
			}
			// Build custom year.
			if ( ! empty( $custom['years'] ) ) {
				$data   = explode( ',', $custom['years'] );
				$symbol = $this->get_custom_import_symbol( $custom['year_qualifier'] );
				// Clean white space.
				foreach ( $data as $value ) {
					$clean_data[] = trim( $value );
				}
				if ( in_array( $custom['year_qualifier'], array( 2, 3 ), true ) ) {
					$search = ' AND year ' . $symbol . '"' . $clean_data[0] . '" ';
				} else {
					$search = ' AND year ' . $symbol . ' ("' . implode( '","', $clean_data ) . '") ';
				}
				$custom_string .= $search;
			}
		}

		return $custom_string;
	}

	public function get_custom_import_symbol( $key ) {
		$result = '';
		switch ( strtolower( $key ) ) {
			case 'equal':
				$result = ' IN ';
				break;
			case 'not equal':
				$result = ' NOT IN ';
				break;
			case 'greater than':
				$result = ' > ';
				break;
			case 'less than':
				$result = ' < ';
				break;
		}

		return $result;
	}

}
