<?php

namespace CarDealerPress\Includes\Database;

use CarDealerPress\includes\functions\Logger;
use CarDealerPress\includes\helpers\helpers as helpers;
use CarDealerPress\Includes\Helpers\Remote_Requests;
use CarDealerPress\Includes\Helpers\Transients;
use Exception;

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


class Inserts {
	use Logger;

	private static $blog_id;
	private static $wpdb;
	/**
	 * @var int|mixed
	 */
	public $company_id = 0;

	public function __construct() {
		global $wpdb;
		self::$wpdb    = $wpdb;
		self::$blog_id = get_current_blog_id();
	}

	public function cdp_data_and_cdp_companies( $dealer_id = 0 ) { // just in Transfer
		if ( $dealer_id ) {
			$this->company_id     = $dealer_id;
			$query_prepare        = 'select * from ' . CDP_DATA . ' where blog_id = %d and data_key = %s and dealer_id = %d';
			$query_params_prepare = array( self::$blog_id, 'dealer', $dealer_id );
			// @codingStandardsIgnoreStart
			$query       = self::$wpdb->prepare( $query_prepare, $query_params_prepare );
			$data_dealer = self::$wpdb->get_results( $query, ARRAY_A );
			// @codingStandardsIgnoreEnd
			// This should be empty so duplicates are not added.
			if ( empty( $data_dealer ) ) {
				$api_params    = '/api/companies/' . $dealer_id;
				$response      = Remote_Requests::http_get_file( $api_params );
				$response_code = $response['status_code'];
				if ( 200 === $response_code ) {
					$response_body = isset( $response['body'] ) ? json_decode( wp_kses_data( $response['body'] ) ) : array();
					$this->add_single_dealer_to_cdp_data_table( $dealer_id );
					$this->populate_companies_table(
						array(
							'data'       => $response_body,
							'company_id' => $dealer_id,
						)
					);
					if ( $response_body->automall_ids ?? false ) {
						$this->add_automalls_dealer_to_cdp_table( $response_body->automall_ids );
						foreach ( $response_body->automall_ids as $dealer_id ) {
							$response_body = $this->call_api_company_for( $dealer_id );
							$this->populate_companies_table(
								array(
									'data'       => $response_body,
									'company_id' => helpers::company_id(),
								)
							);
						}
					}
					Transients::delete_cdp_company_processing( self::$blog_id );
				}
			}
		}
	}

	public function cdp_data( $new_dealer = 0 ) {
		if ( $new_dealer ) {
			$query_prepare        = 'select * from ' . CDP_DATA . ' where blog_id = %d and data_key = %s and dealer_id = %d';
			$query_params_prepare = array( self::$blog_id, 'dealer', $new_dealer );
			// @codingStandardsIgnoreStart
			$query       = self::$wpdb->prepare( $query_prepare, $query_params_prepare );
			$data_dealer = self::$wpdb->get_results( $query, ARRAY_A );
			// @codingStandardsIgnoreEnd
			// This should be empty so duplicates are not added.
			if ( empty( $data_dealer ) ) {
				$api_params    = '/api/companies/' . $new_dealer;
				$response      = Remote_Requests::http_get_file( $api_params );
				$response_code = $response['status_code'];
				if ( 200 === $response_code ) {
					$response_body = isset( $response['body'] ) ? json_decode( wp_kses_data( $response['body'] ) ) : array();
					$this->add_single_dealer_to_cdp_data_table( $new_dealer );
					if ( $response_body->automall_ids ?? false ) {
						$this->add_automalls_dealer_to_cdp_table( $response_body->automall_ids );
					}
					Transients::delete_cdp_company_processing( self::$blog_id );
				}
			}
		}
	}

	public function cdp_check_for_valid_company_id_and_populate_companies_table( $new_dealer = 0 ) {
		if ( 0 !== $new_dealer ) {
			$api_params    = '/api/companies/' . $new_dealer;
			$response      = Remote_Requests::http_get_file( $api_params );
			$response_code = $response['status_code'];
			if ( 200 === $response_code ) {
				$response_body = isset( $response['body'] ) ? json_decode( wp_kses_data( $response['body'] ) ) : array();
				$this->populate_companies_table(
					array(
						'data'       => $response_body,
						'company_id' => $new_dealer,
					)
				);
				if ( $response_body->automall_ids ?? false ) {
					foreach ( $response_body->automall_ids as $dealer ) {
						$response_body = $this->call_api_company_for( $dealer );
						$this->populate_companies_table(
							array(
								'data'       => $response_body,
								'company_id' => $dealer,
							)
						);
					}
				}
				Transients::delete_cdp_company_processing( self::$blog_id );
			}
		}
	}

	public function call_api_company_for( $dealer ) {
		// TODO: future possible move to another class, maybe remote_requests.
		$api_params    = '/api/companies/' . $dealer;
		$response      = Remote_Requests::http_get_file( $api_params );
		$response_code = $response['status_code'];
		if ( 200 === $response_code ) {
			return isset( $response['body'] ) ? json_decode( wp_kses_data( $response['body'] ) ) : array();
		}

	}

	public function add_automalls_dealer_to_cdp_table( $dealers ) {
		foreach ( $dealers as $dealer ) {
			$this->append_log( array( 'message' => 'CDP Message: Automall Dealer (' . $dealer . ') added to CDP Data table' ) );
			$data   = array(
				'blog_id'    => self::$blog_id,
				'dealer_id'  => $dealer,
				'data_key'   => 'dealer',
				'data_value' => 'automall',
			);
			$format = array( '%d', '%d', '%s', '%s' );
			// @codingStandardsIgnoreStart
			self::$wpdb->insert( CDP_DATA, $data, $format );
			// @codingStandardsIgnoreEnd
		}
	}

	public function add_single_dealer_to_cdp_data_table( $dealer ) {
		$data   = array(
			'blog_id'    => self::$blog_id,
			'dealer_id'  => $dealer,
			'data_key'   => 'dealer',
			'data_value' => $dealer,
		);
		$format = array( '%d', '%d', '%s', '%s' );
		// @codingStandardsIgnoreStart
		self::$wpdb->insert( CDP_DATA, $data, $format );
		// @codingStandardsIgnoreEnd
	}

	public function populate_companies_table( $args ) {
		$response_body = $args['data'] ?? '';
		$type          = $args['type'] ?? 'insert';
		$company_id    = $args['company_id'] ?? helpers::company_id();

		if ( $response_body ) {
			$table_data = array();

			$dealer_id    = $response_body->id ?? 0;
			$name         = $response_body->name ?? '';
			$street       = $response_body->street ?? '';
			$city         = $response_body->city ?? '';
			$state        = $response_body->state ?? '';
			$zip          = $response_body->zip ?? '';
			$phone        = $response_body->phone ?? '';
			$country_code = $response_body->country_code ?? '';
			$automalls    = $response_body->automall_ids ?? '';
			$created      = ( $response_body->created ?? '2017-04-01' );
			$updated      = ( $response_body->updated ?? wp_date( 'Y-m-d H:i', time() ) );
			$seo_response = $response_body->seo ?? '';
			$seo          = serialize( json_decode( wp_json_encode( $seo_response ), true ) );
			$runtime      = 0;

			$table_data[] = array(
				'blog_id'                     => self::$blog_id,
				'company_id'                  => $company_id,
				'dealer_id'                   => $dealer_id,
				'name'                        => $name,
				'street'                      => $street,
				'city'                        => $city,
				'state'                       => $state,
				'zip'                         => $zip,
				'phone'                       => $phone,
				'country_code'                => $country_code,
				'automalls'                   => serialize( $automalls ),
				'created'                     => $created,
				'last_updated'                => $updated,
				'inventory_last_updated'      => $runtime,
				'inventory_api_last_modified' => 0,
				'seo'                         => $seo,
			);

			if ( $table_data && 'insert' === $type ) {
				// @codingStandardsIgnoreStart
				self::$wpdb->insert( CDP_COMPANIES, $table_data[0] );
				// @codingStandardsIgnoreEnd
			}
			if ( $table_data && 'update' === $type ) {
				$where       = array( 'dealer_id' => $dealer_id );
				$update_data = array_diff_key( $table_data[0], array_flip( [ 'inventory_last_updated', 'inventory_api_last_modified' ] ) );
				// @codingStandardsIgnoreStart
				self::$wpdb->update( CDP_COMPANIES, $update_data, $where );
				// @codingStandardsIgnoreEnd
			}
		} else {
			$this->append_log( array( 'message' => 'CDP Error response body: ' . wp_json_encode($response_body) . ' empty' ) );
		}
	}

	public function populate_inventory_import_tables( $args ) {
		$data       = $args['data'] ?? '';
		$dealer_id  = $args['dealer_id'] ?? 0;
		$company_id = $args['company_id'] ?? 0;
		$type       = $args['type'] ?? 'insert';
		if ( $data ) {
			$table_data   = array();
			$vehicle_keys = array_keys( INVENTORY_DB_COLUMNS );
			foreach ( $data as $vehicle ) {
				$individual_vehicle = array();
				foreach ( $vehicle_keys as $key ) {
					$individual_vehicle[ $key ] = $vehicle[ $key ];
				}
				$table_data[] = $individual_vehicle;
			}
			if ( $table_data && 'insert' === $type ) {
				$chunk_size = 100; // Process in batches of 100 records for memory efficiency

				// Start a transaction for better performance and consistency
				// @codingStandardsIgnoreStart
				self::$wpdb->query( 'START TRANSACTION' );
				// @codingStandardsIgnoreEnd
				try {
					foreach ( array_chunk( $table_data, $chunk_size ) as $chunk ) {
						foreach ( $chunk as $vehicle ) {
							$sanitized_vehicle = array_map( function ( $value ) {
								return wp_kses( $value, 'post' );
							}, $vehicle );

							// @codingStandardsIgnoreStart
							$result = self::$wpdb->insert( CDP_INVENTORY_IMPORT_TABLE, $sanitized_vehicle );
							// @codingStandardsIgnoreEnd

							if ( false === $result ) {
								$this->append_log( array( 'message' => 'CDP Message: Failed to insert vehicle data: ' . self::$wpdb->last_error ) );
							}

							// Free up memory
							unset( $vehicle );
						}

						// Commit after each chunk to keep the transaction shorter
						// @codingStandardsIgnoreStart
						self::$wpdb->query( 'COMMIT' );
						self::$wpdb->query( 'START TRANSACTION' );
						// @codingStandardsIgnoreEnd
					}

					// Final commit
					// @codingStandardsIgnoreStart
					self::$wpdb->query( 'COMMIT' );
					// @codingStandardsIgnoreEnd

				} catch ( Exception $e ) {
					// Rollback on error
					// @codingStandardsIgnoreStart
					self::$wpdb->query( 'ROLLBACK' );
					// @codingStandardsIgnoreEnd
					$this->append_log( array( 'message' => 'CDP Message: Error during vehicle data import: ' . $e->getMessage() ) );
				}
			}
			if ( $table_data && 'update' === $type ) {
				$where = array( 'dealer_id' => $dealer_id );
				// @codingStandardsIgnoreStart
				$result = self::$wpdb->update( CDP_INVENTORY_IMPORT_TABLE, $table_data[0], $where );
				#= self::$wpdb->insert( CDP_INVENTORY_IMPORT_TABLE, $table_data[0] );
				// @codingStandardsIgnoreEnd
			}
		}
	}

	public function copy_import_to_inventory_table( $company_id, $dealer_id ) {
		$select_columns = implode( ",", array_keys( INVENTORY_DB_COLUMNS ) );
		$table_name     = CDP_INVENTORY_IMPORT_TABLE;
		$sql           = "SELECT $select_columns FROM $table_name WHERE blog_id = %d AND company_id = %d AND dealer_id = %d";
		$query_params  = array( self::$blog_id, $company_id, $dealer_id );
		// @codingStandardsIgnoreStart
		$prepared_query = self::$wpdb->prepare( $sql, $query_params );
		$results        = self::$wpdb->get_results( $prepared_query, ARRAY_A );
		// @codingStandardsIgnoreEnd

		if ( empty( $results ) ) {
			return false;
		}

		// Use transactions for better performance and data integrity
		// @codingStandardsIgnoreStart
		self::$wpdb->query( 'START TRANSACTION' );
		// @codingStandardsIgnoreEnd

		try {
			$chunk_size = 100;
			foreach ( array_chunk( $results, $chunk_size ) as $chunk ) {
				// Build bulk insert query
				$values       = array();
				$placeholders = array();

				foreach ( $chunk as $row ) {
					$sanitized_row = array_map( function ( $value ) {
						return wp_kses( $value, 'post' );
					}, $row );

					$placeholders[] = '(' . implode( ',', array_fill( 0, count( $sanitized_row ), '%s' ) ) . ')';
					$values         = array_merge( $values, array_values( $sanitized_row ) );
				}

				// Bulk insert
				$columns = implode( ',', array_keys( INVENTORY_DB_COLUMNS ) );
				$sql     = "INSERT INTO " . CDP_INVENTORY_TABLE . " ( $columns ) VALUES " . implode( ',', $placeholders );
				// @codingStandardsIgnoreStart
				self::$wpdb->query( self::$wpdb->prepare( $sql, $values ) );
				// @codingStandardsIgnoreEnd
			}
			// @codingStandardsIgnoreStart
			self::$wpdb->query( 'COMMIT' );
			// @codingStandardsIgnoreEnd

		} catch ( Exception $e ) {
			// @codingStandardsIgnoreStart
			self::$wpdb->query( 'ROLLBACK' );
			// @codingStandardsIgnoreStart

			$this->append_log([
				'message' => "CDP Message: Copy import failed: {$e->getMessage()}",
				'type' => 'ERROR'
			]);

			return false;
		}

		// Clear cache
		wp_cache_flush();

		return true;
	}
}
