<?php
/**
 * Class API.
 * includes/class/API.php
 * Handles the API requests
 *
 * @package OrderSyncWithGoogleSheetForWooCommerce
 */

namespace OrderSyncWithGoogleSheetForWooCommerce;

defined( 'ABSPATH' ) || die( 'No script kiddies please!' );

if ( ! class_exists( '\OrderSyncWithGoogleSheetForWooCommerce\API' ) ) {
	/**
	 * API Class Handles the API requests.
	 *
	 * @version 1.0.0
	 */
	class API extends Base {

		/**
		 * Singleton mode
		 *
		 * @var bool
		 */
		public static $instance = null;
		/**
		 * API init for singleton instance.
		 *
		 * @var bool
		 * @version 1.0.0
		 * @return void
		 */
		public static function init() {
			if ( ! self::$instance ) {
				self::$instance = new self();
			}
			self::$instance->register_routes();
		}

		/**
		 * Register API  routes.
		 *
		 * @version 1.0.0
		 * @return void
		 */
		public function register_routes() {
			add_action( 'rest_api_init', [ $this, 'add_api_routes' ] );
		}
		/**
		 * Add API routes.
		 *
		 * @version 1.0.0
		 * @return void
		 */
		public function add_api_routes() {
			$routes = [
				'action' => [
					'methods'             => [ 'GET', 'POST' ],
					'callback'            => [ $this, 'action_api_callback' ],
					'permission_callback' => [ $this, 'permission_callback' ],
				],

				'update' => [
					'methods'             => [ 'GET', 'POST' ],
					'callback'            => [ $this, 'update_api_callback' ],
					'permission_callback' => [ $this, 'permission_callback' ],
				],

				'columns' => [
					'methods'             => [ 'POST' ],
					'callback'            => [ $this, 'columns_api_callback' ],
					'permission_callback' => [ $this, 'permission_callback' ],

				],

				'search-products' => [
					'methods'             => [ 'GET', 'POST' ],
					'callback'            => [ $this, 'search_products_callback' ],
					'permission_callback' => [ $this, 'permission_callback' ],
				],

				'payment-methods' => [
					'methods'             => [ 'GET', 'POST' ],
					'callback'            => [ $this, 'payment_methods_callback' ],
					'permission_callback' => [ $this, 'permission_callback' ],
				],

				'create-order' => [
					'methods'             => [ 'POST' ],
					'callback'            => [ $this, 'create_order_callback' ],
					'permission_callback' => [ $this, 'permission_callback' ],
				],

				'plugin-status' => [
					'methods'             => [ 'GET', 'POST' ],
					'callback'            => [ $this, 'plugin_status_callback' ],
					'permission_callback' => [ $this, 'permission_callback' ],
				],

			];
			foreach ( $routes as $route => $args ) {
				register_rest_route( 'osgsw/v1', $route, $args );
			}
		}


		/**
		 * Permission callback.
		 *
		 * @version 1.0.0
		 * @return bool
		 */
		public function permission_callback() {
			if ( defined( 'OSGSW_DEBUG' ) && OSGSW_DEBUG ) {
				return true;
			}
			$bearer2 = isset($_SERVER['HTTP_AUTHORIZATION']) ? sanitize_text_field( wp_unslash($_SERVER['HTTP_AUTHORIZATION'] ) ) : '';
			$bearer3 = isset($_SERVER['HTTP_OSGSWKEY']) ? sanitize_text_field( wp_unslash($_SERVER['HTTP_OSGSWKEY'] ) ) : '';
			$bearer = '';
			if ( empty($bearer3) ) {
				$bearer = $bearer2;
			}
			if ( empty($bearer2) ) {
				$bearer = $bearer3;
			}
			if ( empty($bearer) ) {
				return false;
			}

			$bearer      = str_replace('Bearer ', '', $bearer);
			$saved_token = osgsw_get_option('token');

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

			if ( $bearer !== $saved_token ) {
				return false;
			}

			return true;
		}
		/**
		 * Responses for API.
		 *
		 * @param bool  $success Success status.
		 * @param mixed $data Data to return.
		 * @return \WP_REST_Response
		 */
		public function response( $success = true, $data = null ) {
			$response = [
				'success' => $success,
			];

			if ( $data ) {
				if ( is_object( $success ) || is_array( $success ) ) {
					$response['data'] = $data;
				} else {
					$response['message'] = $data;
				}
			}

			return new \WP_REST_Response( $response );
		}

		/**
		 * Request callback
		 *
		 * @param object $request response.
		 *
		 * @return array
		 * @version 1.0.0
		 */
		public function action_api_callback( $request ) {
			$params = $request->get_params();
			$action = $params['action'] ?? null;
			if ( ! $action ) {
				return $this->response(
					false,
					__( 'No action specified', 'order-sync-with-google-sheets-for-woocommerce' )
				);
			}

			$action = strtolower( $action );

			if ( ! method_exists( $this, 'action_' . $action ) ) {
				return $this->response(
					false,
					__( 'Action not found', 'order-sync-with-google-sheets-for-woocommerce' )
				);
			}
			try {
				return $this->{'action_' . $action}( $request );
			} catch ( \Exception $e ) {
				return $this->response( false, $e->getMessage() );
			}
		}
		/**
		 * Callback for action sync.
		 *
		 * @param \WP_REST_Request $request Request.
		 * @return mixed Response.
		 */
		public function action_sync( $request ) {
			$params  = $request->get_params();
			$message = $params['message'] ?? __('Order synced successfully', 'order-sync-with-google-sheet-for-woocommerce');
			$osgsw_items = isset( $params['osgsw_items'] ) ? $params['osgsw_items'] : false;
			$osgsw_offset = isset( $params['osgsw_offset'] ) ? $params['osgsw_offset'] : 0;
			$osgsw_batch_size = isset( $params['osgsw_batch_size'] ) ? $params['osgsw_batch_size'] : 0;
			$order = new Order();
			$google_sheet = new Sheet();

			try {
				if ( isset($params['osgsw_items']) ) {
					if ( $osgsw_items ) {
						$response = osgsw_order_count();
						if ( $response ) {
							return $this->response(
								true,
								$response
							);
						} else {
							return $this->response(
								false,
								__('Something went wrong', 'order-sync-with-google-sheet-for-woocommerce')
							);
						}
					} else {
						update_option('osgsw_license_sync', false);
						$update = $order->sync_batch_all($osgsw_offset, $osgsw_batch_size);

						// Fix: Clear batch cache when sync is complete.
						$total_orders = osgsw_order_count();
						if ( $osgsw_offset + $osgsw_batch_size >= $total_orders ) {
							$message = __('All orders synced successfully', 'order-sync-with-google-sheet-for-woocommerce');
							$order->clear_batch_cache();
						}

						if ( $update ) {
							$google_sheet->update_google_sheet_sorting();
							return $this->response(
								true,
								$message
							);
						} else {
							return $this->response(
								true,
								$message
							);
						}
					}
				} else {
					$order = new Order();
					$response = $order->sync_all( true );
					if ( $response ) {
						$google_sheet->update_google_sheet_sorting();
						return $this->response(
							true,
							$message
						);
					} else {
						return $this->response(
							false,
							__( 'Something went wrong', 'order-sync-with-google-sheets-for-woocommerce' )
						);
					}
				}
			} catch ( \Exception $e ) {
				return $this->response(false, $e->getMessage());
			}
		}
		/**
		 * Callback for action update.
		 *
		 * @param \WP_REST_Request $request Request.
		 * @return mixed Response.
		 */
		public function update_api_callback( $request ) {
			$body = $request->get_params();
			$orders = $body['orders'] ?? null;
			$order_length = isset( $body['arrayLength'] ) ? $body['arrayLength'] : 1;
			$first_index = isset( $body['firstIndex'] ) ? $body['firstIndex'] : 0;
			$last_index = isset( $body['lastIndex'] ) ? $body['lastIndex'] : 0;
			$new_app = isset( $body['newapp'] ) ? $body['newapp'] : 0;

			if ( $orders && is_array( $orders ) && ! empty( $orders ) ) {
				try {
					$order = new Order();
					$google_sheet = new Sheet();

					// Determine update type based on the data present.
					$update_type = $this->determine_update_type( $orders[0] );

					// Store order IDs for filter checking after update.
					$order_ids_to_check = [];
					foreach ( $orders as $order_data ) {
						// Check for the most common order ID field names.
						$order_id = null;
						$possible_order_id_fields = [
							'order_Id',      // Based on the log, this is the correct field.
							'order_id',
							'id',
							'Order ID',
							'show_order_id',
						];

						foreach ( $possible_order_id_fields as $field ) {
							if ( isset( $order_data[ $field ] ) && ! empty( $order_data[ $field ] ) ) {
								$order_id = $order_data[ $field ];
								break;
							}
						}

						if ( $order_id ) {
							$order_ids_to_check[] = $order_id;
						}
					}

					if ( $new_app ) {
						switch ( $update_type ) {
							case 'order_status':
								$response = $order->bulk_chank_update( $orders, $first_index, $last_index );
								break;

							case 'billing_shipping':
								$response = $order->bulk_billing_shipping_update( $orders, $first_index, $last_index );
								break;

							default:
								$response = $order->bulk_chank_update( $orders, $first_index, $last_index );
								break;
						}
					} else {
						switch ( $update_type ) {
							case 'order_status':
								$response = $order->bulk_update( $orders );
								break;

							case 'billing_shipping':
								$response = $order->bulk_billing_shipping_update_simple( $orders );
								break;

							default:
								$response = $order->bulk_update( $orders );
								break;
						}
					}

					// After successful update, check filters and delete rows if needed.
					$this->check_and_delete_filtered_orders( $order_ids_to_check, $google_sheet );

					// Update sheet sorting.
					$google_sheet->update_google_sheet_sorting();

					// Return appropriate response based on update type.
					switch ( $update_type ) {
						case 'order_status':
							return $this->response(
								true,
								$response,
								__( 'Order status updated successfully', 'order-sync-with-google-sheets-for-woocommerce' )
							);

						case 'billing_shipping':
							return $this->response(
								true,
								$response,
								__( 'Billing/Shipping information updated successfully', 'order-sync-with-google-sheets-for-woocommerce' )
							);

						default:
							return $this->response(
								true,
								$response,
								__( 'Order synced with WooCommerce successfully', 'order-sync-with-google-sheets-for-woocommerce' )
							);
					}
				} catch ( \Exception $e ) {
					return $this->response( false, $e->getMessage() );
				}
			} else {
				return $this->response(
					false,
					__( 'No orders specified', 'order-sync-with-google-sheets-for-woocommerce' )
				);
			}

			return $this->response( true, $orders );
		}

		/**
		 * Check updated orders against filters and delete rows from sheet if they no longer match
		 *
		 * @param array $order_ids Array of order IDs to check
		 * @param Sheet $google_sheet Google Sheet instance
		 * @return void
		 */
		private function check_and_delete_filtered_orders( $order_ids, $google_sheet ) {
			// Only proceed if ultimate license is active and filtering is enabled
			$is_license_active = osgsw_is_ultimate_license_activated();
			if ( ! $is_license_active ) {
				return;
			}

			// Check if filtering is enabled
			$enable_google_sheets_filtering = wp_validate_boolean( osgsw_get_option( 'enable_google_sheets_filtering', false ) );
			if ( ! $enable_google_sheets_filtering ) {
				return;
			}

			// Check if the ultimate filter class exists
			if ( ! class_exists( '\OrderSyncWithGoogleSheetForWooCommerceUltimate\FilterExtension' ) ) {
				return;
			}

			$filter_extension = new \OrderSyncWithGoogleSheetForWooCommerceUltimate\FilterExtension();
			$orders_to_delete = [];

			// Check each order against the filters
			foreach ( $order_ids as $order_id ) {
				if ( ! $order_id ) {
					continue;
				}

				// Use the filter extension to check if order matches current filters
				$matches_filters = $filter_extension->order_matches_filters( true, $order_id );

				if ( ! $matches_filters ) {
					$orders_to_delete[] = $order_id;
				}
			}

			// If no orders need to be deleted, return early
			if ( empty( $orders_to_delete ) ) {
				return;
			}

			// Get row numbers for orders that need to be deleted
			// Get the current sheet data to build the index
			$sheets_info = $google_sheet->get_first_columns();
			$sheet_index = osgsw_format_index_number( $sheets_info );
			$row_numbers_to_delete = [];

			foreach ( $orders_to_delete as $order_id ) {
				$row_number = osgsw_get_index_number_option( $order_id, $sheet_index );
				if ( $row_number ) {
					$row_numbers_to_delete[] = $row_number;
				}
			}

			// Delete rows from Google Sheet
			if ( ! empty( $row_numbers_to_delete ) ) {
				try {
					if ( count( $row_numbers_to_delete ) === 1 ) {
						// Single row deletion
						$row_number = $row_numbers_to_delete[0];
						$google_sheet->delete_single_row( $row_number, $row_number );
					} else {
						// Batch row deletion
						$google_sheet->delete_batch_rows( $row_numbers_to_delete );
					}
				} catch ( \Exception $e ) {
					// Log error but don't fail the entire update process
					error_log( 'Error deleting filtered orders from sheet: ' . $e->getMessage() );
				}
			}
		}

		/**
		 * Determine the type of update based on the order data
		 *
		 * @param array $order_data The order data array
		 * @return string The update type: 'order_status', 'billing_shipping', or 'general'
		 */
		private function determine_update_type( $order_data ) {
			// Define billing/shipping field keys
			$billing_shipping_fields = [
				'show_billing_first_name',
				'show_billing_last_name',
				'show_billing_address_1',
				'show_billing_city',
				'show_billing_postcode',
				'show_billing_country',
				'show_billing_address_2',
				'show_billing_company',
				'show_billing_state',
				'show_billing_email',
				'show_billing_phone',
				'show_shipping_first_name',
				'show_shipping_last_name',
				'show_shipping_address_1',
				'show_shipping_city',
				'show_shipping_postcode',
				'show_shipping_country',
				'show_shipping_address_2',
				'show_shipping_company',
				'show_shipping_state',
				'show_shipping_email',
				'show_shipping_phone',
			];

			// Check if any billing/shipping fields are present
			$has_billing_shipping = false;
			foreach ( $billing_shipping_fields as $field ) {
				if ( isset( $order_data[ $field ] ) ) {
					$has_billing_shipping = true;
					break;
				}
			}

			// Check if order_status is present
			$has_order_status = isset( $order_data['order_status'] );

			// Determine update type based on what fields are present
			if ( $has_billing_shipping && ! $has_order_status ) {
				return 'billing_shipping';
			} elseif ( $has_order_status && ! $has_billing_shipping ) {
				return 'order_status';
			} else {
				// If both are present or neither, default to general update
				return 'general';
			}
		}


		/**
		 * API callback for saving column preferences.
		 *
		 * @param WP_REST_Request $request The request object.
		 * @return WP_REST_Response The response.
		 */
		public function columns_api_callback( $request ) {
			$params = $request->get_params();
			$column_mapping = isset( $params['columnMapping'] ) ? $params['columnMapping'] : null;

			if ( empty( $column_mapping ) ) {
				return $this->response(
					false,
					__( 'No column mapping data provided', 'order-sync-with-google-sheets-for-woocommerce' )
				);
			}

			try {
				// Validate column mapping data.
				if ( ! is_array( $column_mapping ) ) {
					return $this->response(
						false,
						__( 'Invalid column mapping format', 'order-sync-with-google-sheets-for-woocommerce' )
					);
				}

				// Store the column mapping in WordPress options.
				$success = update_option( 'osgsw_column_preferences', $column_mapping, false );

				update_option( 'osgsw_column_preferences_updated', current_time( 'timestamp' ), false );

				return $this->response(
					true,
					__( 'Column preferences saved successfully', 'order-sync-with-google-sheets-for-woocommerce' )
				);
			} catch ( \Exception $e ) {
				return $this->response(
					false,
					$e->getMessage()
				);
			}
		}

		/**
		 * Retrieve saved column preferences.
		 *
		 * @return array|false Column preferences or false if not set.
		 */
		public function get_column_preferences() {
			$preferences = get_option( 'osgsw_column_preferences', false );
			return $preferences;
		}

		/**
		 * Get the timestamp when column preferences were last updated.
		 *
		 * @return int|false Timestamp or false if not set.
		 */
		public function get_column_preferences_updated_time() {
			return get_option( 'osgsw_column_preferences_updated', false );
		}


		/**
		 * Callback for Pro Plugin status check.
		 *
		 * @param \WP_REST_Request $request Request.
		 * @return mixed Response.
		 */
		public function plugin_status_callback( $request ) {

			try {
				$is_license_active = osgsw_is_ultimate_license_activated();
				$is_active_bool = (bool) $is_license_active;

				$license_data = [
					'is_active' => $is_active_bool,
					'status' => $is_active_bool ? 'active' : 'inactive',
					'message' => __( 'Plugin status retrieved successfully', 'order-sync-with-google-sheets-for-woocommerce' ),
				];

				return $this->response( true, $license_data );

			} catch ( \Exception $e ) {
				return $this->response( false, $e->getMessage() );
			}
		}


		/**
		 * Product search callback.
		 *
		 * @param \WP_REST_Request $request Request.
		 * @return \WP_REST_Response Response.
		 */
		public function search_products_callback( $request ) {
			$is_license_active = osgsw_is_ultimate_license_activated();

			if ( $is_license_active ) {
				if ( class_exists( '\OrderSyncWithGoogleSheetForWooCommerceUltimate\Hooks' ) ) {
					$ultimate_hooks = new \OrderSyncWithGoogleSheetForWooCommerceUltimate\Hooks();
					return $ultimate_hooks->search_products_callback( $request, $this );
				}

				return $this->response(
					false,
					__( 'Ultimate plugin required', 'order-sync-with-google-sheets-for-woocommerce' )
				);
			} else {
				return $this->response(
					false,
					__( 'This feature requires the Pro version. Please upgrade to access advanced product search functionality.', 'order-sync-with-google-sheets-for-woocommerce' )
				);
			}
		}

		/**
		 * Payment methods callback.
		 *
		 * @param \WP_REST_Request $request Request.
		 * @return \WP_REST_Response Response.
		 */
		public function payment_methods_callback( $request ) {
			$is_license_active = osgsw_is_ultimate_license_activated();

			if ( $is_license_active ) {
				if ( class_exists( '\OrderSyncWithGoogleSheetForWooCommerceUltimate\Hooks' ) ) {
					$ultimate_hooks = new \OrderSyncWithGoogleSheetForWooCommerceUltimate\Hooks();
					return $ultimate_hooks->payment_methods_callback( $request, $this );
				}

				return $this->response(
					false,
					__( 'Ultimate plugin required', 'order-sync-with-google-sheets-for-woocommerce' )
				);
			} else {
				return $this->response(
					false,
					__( 'This feature requires the Pro version. Please upgrade to access payment methods functionality.', 'order-sync-with-google-sheets-for-woocommerce' )
				);
			}
		}

		/**
		 * Order create callback.
		 *
		 * @param \WP_REST_Request $request Request.
		 * @return \WP_REST_Response Response.
		 */
		public function create_order_callback( $request ) {
			$is_license_active = osgsw_is_ultimate_license_activated();

			if ( $is_license_active ) {
				if ( class_exists( '\OrderSyncWithGoogleSheetForWooCommerceUltimate\Hooks' ) ) {
					$ultimate_hooks = new \OrderSyncWithGoogleSheetForWooCommerceUltimate\Hooks();

					return $ultimate_hooks->create_order_callback( $request, $this );
				}

				return $this->response(
					false,
					__( 'Ultimate plugin required', 'order-sync-with-google-sheets-for-woocommerce' )
				);
			} else {
				return $this->response(
					false,
					__( 'This feature requires the Pro version. Please upgrade to access Order create functionality.', 'order-sync-with-google-sheets-for-woocommerce' )
				);
			}
		}
	}
	/**
	 * Kick out the API Class.
	 *
	 * @version 1.0.0
	 */
	API::init();
}
