<?php

namespace Inspire_Labs\Alsendo_Connect;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

use Inspire_Labs\Alsendo_Connect\Ecolet;

/**
 * Ajax
 */
class Ajax {

	/**
	 * Add ajax handler
	 */
	public function init() {
		add_action( 'wp_ajax_alsendo_connect', array( $this, 'ajax_callback' ) );
	}


	/**
	 * Ajax handler
	 */
	public function ajax_callback() {

		check_ajax_referer( 'alsendo_connect_order_metabox', 'security' );

		if ( isset( $_REQUEST['alsendo_connect_action'] ) ) {
			$action = sanitize_text_field( wp_unslash( $_REQUEST['alsendo_connect_action'] ) );
			if ( 'create_package' === $action ) {
				$this->create_package();
			}
			if ( 'calculate' === $action ) {
				$this->calculate();
			}
			if ( 'cancel_package' === $action ) {
				$this->cancel();
			}
			if ( 'create_package_pickup_self' === $action ) {
				$this->create_package();
			}
			if ( 'download_turn_in' === $action ) {
				$this->download_turn_in();
			}
			if ( 'ecolet_auth' === $action ) {
				$this->ecolet_auth();
			}
			if ( 'ecolet_get_awb' === $action ) {

				if ( ! empty( $_POST['ecolet_id'] ) ) {
					$ecolet_id = sanitize_text_field( wp_unslash( $_POST['ecolet_id'] ) );
					$order_id  = ! empty( $_POST['order_id'] ) ? sanitize_text_field( wp_unslash( $_POST['order_id'] ) ) : null;
					$this->get_awb_id( $ecolet_id, $order_id );
				}
			}

			if ( 'ecolet_cancel_order' === $action || 'ecolet_bulk_cancel_shipments' === $action ) {

				if ( ! empty( $_POST['ecolet_id'] ) ) {
					$ecolet_id = sanitize_text_field( wp_unslash( $_POST['ecolet_id'] ) );
					$order_id  = ! empty( $_POST['order_id'] ) ? sanitize_text_field( wp_unslash( $_POST['order_id'] ) ) : null;
					$this->ecolet_cancel_order( $ecolet_id, $order_id );
				}
			}
			if ( 'ecolet_get_waybill' === $action ) {

				if ( ! empty( $_POST['ecolet_id'] ) ) {
					$ecolet_id = sanitize_text_field( wp_unslash( $_POST['ecolet_id'] ) );
					$order_id  = ! empty( $_POST['order_id'] ) ? sanitize_text_field( wp_unslash( $_POST['order_id'] ) ) : '';
					$this->ecolet_get_waybill( $ecolet_id, $order_id );
				}
			}

			if ( 'ecolet_bulk_create_labels' === $action ) {

				$ecolet          = new Ecolet();
				$ecolet_services = $ecolet->get_service_structure_ecolet();
				if ( 'on' !== get_option( 'alsendo_connect_ecolet_not_connected' ) || empty( $ecolet_services ) ) {
					$response = array(
						'error'         => 1,
						'error_details' => 'Check connection',
					);
					echo wp_json_encode( $response );
					wp_die();
				}

				$uuid = '';
				if ( ! empty( $_POST['uuid'] ) ) {
					$uuid = sanitize_text_field( wp_unslash( $_POST['uuid'] ) );
				}

				$order_id = ! empty( $_POST['order_id'] ) ? sanitize_text_field( wp_unslash( $_POST['order_id'] ) ) : '';

				$result = $ecolet->get_waybill( $uuid, $order_id );

				header( 'Content-Type: application/json' );
				if ( empty( $result ) || ( is_array( $result ) && ! empty( $result['exception'] ) ) ) {
					$response = array(
						'error'         => 1,
						'error_details' => $result,
					);

				} else {
					$pdf_data = base64_encode( $result );
					$response = array( 'pdf' => $pdf_data );
				}
				echo wp_json_encode( $response );
				wp_die();

			}

			if ( 'ecolet_bulk_create_shipments' === $action ) {

				$ecolet          = new Ecolet();
				$ecolet_services = $ecolet->get_service_structure_ecolet();
				if ( 'on' !== get_option( 'alsendo_connect_ecolet_not_connected' ) || empty( $ecolet_services ) ) {
					$response = array(
						'error'         => 1,
						'error_details' => 'Check connection',
					);
					echo wp_json_encode( $response );
					wp_die();
				}

				$order_id     = ! empty( $_POST['order_id'] ) ? sanitize_text_field( wp_unslash( $_POST['order_id'] ) ) : '';
				$carrier_id   = ! empty( $_POST['carrier_id'] ) ? sanitize_text_field( wp_unslash( $_POST['carrier_id'] ) ) : '';
				$use_template = ! empty( $_POST['use_template'] ) ? sanitize_text_field( wp_unslash( $_POST['use_template'] ) ) : '';

				$order = wc_get_order( $order_id );
				if ( ! $order || is_wp_error( $order ) ) {
					$response = array(
						'error'         => 1,
						'error_details' => 'No order',
					);
					echo wp_json_encode( $response );
					wp_die();
				}
				$helper = new Helper();
				$helper->ecolet_create_order_bulk( $order_id, $carrier_id, $use_template );

			}

			if ( 'apaczka_bulk_create_shipments' === $action ) {

				$order_id     = ! empty( $_POST['order_id'] ) ? sanitize_text_field( wp_unslash( $_POST['order_id'] ) ) : '';
				$carrier_id   = ! empty( $_POST['carrier_id'] ) ? sanitize_text_field( wp_unslash( $_POST['carrier_id'] ) ) : '';
				$use_template = ! empty( $_POST['use_template'] ) ? sanitize_text_field( wp_unslash( $_POST['use_template'] ) ) : '';

				$order = wc_get_order( $order_id );
				if ( ! $order || is_wp_error( $order ) ) {
					$response = array(
						'error'         => 1,
						'error_details' => 'No order',
					);
					wp_send_json_error( $response );
				}
				$helper = new Helper();
				$helper->apaczka_create_order_bulk( $order_id, $carrier_id, $use_template );

			}

			if ( 'apaczka_bulk_cancel_shipments' === $action ) {
				$this->cancel();
			}

			if ( 'apaczka_bulk_create_labels' === $action ) {

				$uuid = '';
				if ( ! empty( $_POST['uuid'] ) ) {
					$uuid = sanitize_text_field( wp_unslash( $_POST['uuid'] ) );
				}
				$order_id = ! empty( $_POST['order_id'] ) ? sanitize_text_field( wp_unslash( $_POST['order_id'] ) ) : '';

				$this->get_waybill_apaczka( $uuid, $order_id );

			}

			if ( 'apaczka_get_waybill' === $action ) {

				if ( ! empty( $_POST['apaczka_order_id'] ) ) {
					$apaczka_id = sanitize_text_field( wp_unslash( $_POST['apaczka_order_id'] ) );
					$order_id   = ! empty( $_POST['order_id'] ) ? sanitize_text_field( wp_unslash( $_POST['order_id'] ) ) : '';
					$this->get_waybill_apaczka( $apaczka_id, $order_id );
				}
			}

			if ( 'ecolet_get_order' === $action ) {

				if ( ! empty( $_POST['ecolet_id'] ) ) {
					$ecolet_id = sanitize_text_field( wp_unslash( $_POST['ecolet_id'] ) );
					$this->ecolet_get_order( $ecolet_id );
				}
			}

			if ( 'zaslat_get_order' === $action ) {

				if ( ! empty( $_POST['zaslat_id'] ) ) {
					$zaslat_id = sanitize_text_field( wp_unslash( $_POST['zaslat_id'] ) );
					$this->zaslat_get_order( $zaslat_id );
				}
			}

			if ( 'zaslat_cancel_order' === $action ) {

				if ( ! empty( $_POST['zaslat_id'] ) ) {
					$zaslat_id = sanitize_text_field( wp_unslash( $_POST['zaslat_id'] ) );
					$order_id  = ! empty( $_POST['order_id'] ) ? sanitize_text_field( wp_unslash( $_POST['order_id'] ) ) : null;
					$this->zaslat_cancel_order( $zaslat_id, $order_id );
				}
			}

			if ( 'zaslat_get_waybill' === $action ) {

				if ( ! empty( $_POST['zaslat_id'] ) ) {
					$zaslat_id = sanitize_text_field( wp_unslash( $_POST['zaslat_id'] ) );
					$order_id  = ! empty( $_POST['order_id'] ) ? sanitize_text_field( wp_unslash( $_POST['order_id'] ) ) : '';
					$this->zaslat_get_waybill( $zaslat_id, $order_id );
				}
			}

			if ( 'zaslat_get_manifest' === $action ) {

				if ( ! empty( $_POST['zaslat_id'] ) ) {
					$zaslat_id = sanitize_text_field( wp_unslash( $_POST['zaslat_id'] ) );
					$order_id  = ! empty( $_POST['order_id'] ) ? sanitize_text_field( wp_unslash( $_POST['order_id'] ) ) : '';
					$this->zaslat_get_manifest( $zaslat_id, $order_id );
				}
			}
		}
	}


	/**
	 * Creates a shipping package by delegating to the shipping method's AJAX handler.
	 *
	 * @return void
	 */
	public function create_package() {
		Shipping_Method_Alsendo_Connect::ajax_create_package();
	}


	/**
	 * Calculates a shipping package by delegating to the shipping method's AJAX handler.
	 *
	 * @return void
	 */
	public function calculate() {
		Shipping_Method_Alsendo_Connect::ajax_calculate_package();
	}

	/**
	 * Cancel a shipping package by delegating to the shipping method's AJAX handler.
	 *
	 * @return void
	 */
	public function cancel() {
		Shipping_Method_Alsendo_Connect::ajax_cancel_package();
	}

	/**
	 * Download turn_in by delegating to the shipping method's AJAX handler.
	 *
	 * @return void
	 */
	public function download_turn_in() {
		Shipping_Method_Alsendo_Connect::download_turn_in();
	}


	/**
	 * Handles Ecolet authentication and sends JSON response.
	 *
	 * Attempts to authenticate with Ecolet API and returns appropriate JSON response.
	 * Sends error response if authentication fails, success response otherwise.
	 *
	 * @return void Outputs JSON response and terminates execution.
	 */
	public function ecolet_auth() {
		$connection = ( new Ecolet() )->ecolet_auth();
		if ( ! empty( $connection['error'] ) ) {
			wp_send_json_error( $connection );
		} else {
			wp_send_json_success();
		}
	}


	/**
	 * Cancels an Ecolet order and updates WooCommerce order status.
	 *
	 * Attempts to cancel the order via Ecolet API. On successful cancellation,
	 * resets the package_send flag and updates the order status based on payment
	 * status (processing if paid, on-hold if unpaid). Sends appropriate JSON response.
	 *
	 * @param int $ecolet_id The Ecolet order ID to cancel.
	 * @param int $order_id  The WooCommerce order ID to update.
	 *
	 * @return void Outputs JSON response and terminates execution.
	 */
	public function ecolet_cancel_order( $ecolet_id, $order_id ) {

		$cancellation = ( new Ecolet() )->cancel_order( $ecolet_id );
		if ( ! empty( $cancellation['status_code'] ) && 200 === $cancellation['status_code'] ) {
			$meta_data                 = alsendo_connect()->get_order_meta_data( $order_id );
			$meta_data['package_send'] = 0;
			unset( $meta_data['alsendo_order'] );
			$order = wc_get_order( $order_id );
			if ( $order && ! is_wp_error( $order ) ) {
				$order->update_meta_data( 'alsendo_connect_wc_order', $meta_data );

				$current_order_status = $order->get_status();
				if ( $order->get_date_paid() ) {
					if ( 'processing' !== $current_order_status ) {
						$order->update_status( 'wc-processing' );
					}
				} elseif ( 'on-hold' !== $current_order_status ) {
					$order->update_status( 'wc-on-hold' );
				}

				$order->save();
			}
			wp_send_json_success( $cancellation );
		} else {
			wp_send_json_error( $cancellation );
		}
	}


	/**
	 * Retrieves an Ecolet order and sends JSON success response.
	 *
	 * Fetches order details from Ecolet API and returns them as a JSON success response.
	 *
	 * @param int $ecolet_id The Ecolet order ID to retrieve.
	 *
	 * @return void Outputs JSON response and terminates execution.
	 */
	public function ecolet_get_order( $ecolet_id ) {
		$ecolet_order = ( new Ecolet() )->get_order( $ecolet_id );
		wp_send_json_success( $ecolet_order );
	}


	/**
	 * Downloads waybill PDF for an Ecolet shipment.
	 *
	 * Retrieves the waybill from Ecolet service and outputs it as a downloadable
	 * PDF file with appropriate headers, or returns JSON error on failure.
	 *
	 * @param string $ecolet_id The Ecolet shipment identifier.
	 * @param int    $order_id The WooCommerce order ID.
	 * @return void Outputs PDF content or JSON error response.
	 */
	public function ecolet_get_waybill( $ecolet_id, $order_id ) {

		$ecolet          = new Ecolet();
		$ecolet_services = $ecolet->get_service_structure_ecolet();
		if ( 'on' !== get_option( 'alsendo_connect_ecolet_not_connected' ) || empty( $ecolet_services ) ) {
			header( 'Content-Type: application/json' );
			$response = array(
				'error'         => 1,
				'error_details' => esc_html__( 'Check connection with API in plugin settings', 'alsendo-connect' ),
			);
			wp_send_json_error( $response );

		}

		$result = $ecolet->get_waybill( $ecolet_id, $order_id );

		if ( is_array( $result ) && ! empty( $result['exception'] ) ) {
			wp_send_json_error( $result );
		} else {

			// Assuming you have the PDF content in a variable called $pdf_content.
			$filename = 'ecolet_woo_order_' . $order_id . '.pdf';

			// Set headers for PDF download.
			header( 'Content-Type: application/pdf' );
			header( 'Content-Disposition: attachment; filename="' . $filename . '"' );
			header( 'Content-Length: ' . strlen( $result ) );

			// Output the PDF string.
			echo $result; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			exit;
		}
	}


	/**
	 * Retrieves Apaczka waybill and sends PDF response.
	 *
	 * Fetches waybill from Apaczka API and either sends JSON error response on failure
	 * or outputs the PDF file directly with appropriate headers for download.
	 *
	 * @param string $apaczka_id The Apaczka shipment ID to get waybill for.
	 * @param int    $order_id   The WooCommerce order ID for filename generation.
	 *
	 * @return void Outputs JSON response or PDF file and terminates execution.
	 */
	public function get_waybill_apaczka( $apaczka_id, $order_id ) {

		$apaczka_api = new Alsendo_API();

		$result = $apaczka_api->waybill( $apaczka_id );

		if ( is_array( $result ) && ( ! empty( $result['exception'] ) || ! empty( $result['error'] ) ) ) {

			if ( function_exists( 'wc_get_logger' ) ) {
				\wc_get_logger()->debug( 'SOME_ERROR_ON_REQUEST: APACZKA GET WAYBILL', array( 'source' => 'alsendo-connect-order-' . $order_id ) );
				\wc_get_logger()->debug( 'APACZKA ID:', array( 'source' => 'alsendo-connect-order-' . $order_id ) );
				\wc_get_logger()->debug( print_r( $apaczka_id, true ), array( 'source' => 'alsendo-connect-order-' . $order_id ) );
				\wc_get_logger()->debug( 'API RESPONSE:', array( 'source' => 'alsendo-connect-order-' . $order_id ) );
				\wc_get_logger()->debug( print_r( $result, true ), array( 'source' => 'alsendo-connect-order-' . $order_id ) );
			}

			wp_send_json_error( $result );

		} else {
			$pdf = is_object( $result ) && property_exists( $result, 'waybill' ) ? $result->waybill : '';
			wp_send_json_success( array( 'pdf' => $pdf ) );
		}
	}


	/**
	 * Retrieves and updates AWB ID for an Ecolet order.
	 *
	 * Fetches the AWB (Air Waybill) ID from Ecolet API and updates the order
	 * metadata with the retrieved AWB ID. Sends JSON success response with AWB ID
	 * on success, or JSON error response on failure.
	 *
	 * @param int $ecolet_id The Ecolet order ID to get AWB ID for.
	 * @param int $order_id  The WooCommerce order ID to update with AWB ID.
	 *
	 * @return void Outputs JSON response and terminates execution.
	 */
	public function get_awb_id( $ecolet_id, $order_id ) {
		$awb_id = ( new Ecolet() )->get_awb_id( $ecolet_id );
		if ( $awb_id ) {
			( new Ecolet() )->update_awb_id( $awb_id, $order_id );
			wp_send_json_success( $awb_id );
		}
		wp_send_json_error();
	}


	/**
	 * Retrieves waybill from Zaslat API and sends JSON response.
	 *
	 * Fetches waybill data from Zaslat API and sends JSON success response with
	 * waybill data on success, or JSON error response if there's an error or
	 * non-200 status code.
	 *
	 * @param int $zaslat_id The Zaslat shipment ID to get waybill for.
	 * @param int $order_id  The WooCommerce order ID for reference.
	 *
	 * @return void Outputs JSON response and terminates execution.
	 */
	public function zaslat_get_waybill( $zaslat_id, $order_id ) {
		$result = ( new Zaslat() )->get_waybill( $zaslat_id, $order_id );
		if ( ! empty( $result['error'] ) || empty( $result['status_code'] ) || 200 !== $result['status_code'] ) {
			wp_send_json_error( $result );
		} elseif ( ! empty( $result['data'] ) ) {
			wp_send_json_success( $result );
		}
	}


	/**
	 * Cancels a Zaslat order and updates WooCommerce order metadata.
	 *
	 * Attempts to cancel the order via Zaslat API. On successful cancellation,
	 * resets the package_send flag in order metadata and saves the changes.
	 * Always sends JSON success response with cancellation result.
	 *
	 * @param int $zaslat_id The Zaslat order ID to cancel.
	 * @param int $order_id  The WooCommerce order ID to update.
	 *
	 * @return void Outputs JSON response and terminates execution.
	 */
	public function zaslat_cancel_order( $zaslat_id, $order_id ) {

		$cancellation = ( new Zaslat() )->cancel_order( $zaslat_id );

		if ( ! empty( $cancellation['status_code'] ) && 200 === $cancellation['status_code'] ) {
			$meta_data                 = alsendo_connect()->get_order_meta_data( $order_id );
			$meta_data['package_send'] = 0;
			unset( $meta_data['alsendo_order'] );
			$order = wc_get_order( $order_id );
			if ( $order && ! is_wp_error( $order ) ) {
				$order->update_meta_data( 'alsendo_connect_wc_order', $meta_data );
				$current_order_status = $order->get_status();
				if ( $order->get_date_paid() ) {
					if ( 'processing' !== $current_order_status ) {
						$order->update_status( 'wc-processing' );
					}
				} elseif ( 'on-hold' !== $current_order_status ) {
					$order->update_status( 'wc-on-hold' );
				}
				$order->save();
			}
			wp_send_json_success( $cancellation );
		} else {
			wp_send_json_error( $cancellation );
		}
	}


	/**
	 * Retrieves Zaslat order details and sends JSON success response.
	 *
	 * Fetches order details from Zaslat API and returns them as a JSON success response.
	 *
	 * @param int $zaslat_id The Zaslat order ID to retrieve details for.
	 *
	 * @return void Outputs JSON response and terminates execution.
	 */
	public function zaslat_get_order( $zaslat_id ) {
		$zaslat_order = ( new Zaslat() )->get_details( $zaslat_id );
		if ( ! empty( $zaslat_order['status'] ) && 200 === $zaslat_order['status'] ) {
			wp_send_json_success( $zaslat_order['data'] );
		} else {
			wp_send_json_error( $zaslat_order );
		}
	}


	/**
	 * Retrieves manifest from Zaslat API and sends JSON response.
	 *
	 * Fetches manifest data from Zaslat API and sends JSON success response with
	 * manifest data on success, or JSON error response if there's an error or
	 * non-200 status code.
	 *
	 * @param int $zaslat_id The Zaslat shipment ID to get manifest for.
	 * @param int $order_id  The WooCommerce order ID for reference.
	 *
	 * @return void Outputs JSON response and terminates execution.
	 */
	public function zaslat_get_manifest( $zaslat_id, $order_id ) {
		$result = ( new Zaslat() )->get_manifest( $zaslat_id, $order_id );
		if ( ! empty( $result['error'] ) || 200 !== $result['status_code'] ) {
			wp_send_json_error( $result );
		} elseif ( ! empty( $result['data'] ) ) {
			wp_send_json_success( $result );
		}
	}
}
