<?php

namespace Wetail\Shipping\Engine;

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

if ( class_exists( __NAMESPACE__ . '\Wetail_Shipping_Return_Portal' ) ) {
	return;
}


/**
 * End-user-initiated returns
 *
 * @since 1.0.6
 * @clickup https://app.clickup.com/t/8696gbw5w
 * @clickup https://app.clickup.com/t/8695ugfzk
 */
class Wetail_Shipping_Return_Portal {
	private static string $return_prefix = 'wetail_shipping_return_portal_';

	/**
	 * Bootstrap the class and hooks required actions & filters
	 *
	 * @return void
	 */
	public static function init(): void {
		add_shortcode( 'wetail_return_portal', [ __CLASS__, 'wetail_return_portal_shortcode_handler' ] );

		add_action( 'wp_ajax_wetail_shipping_portal', array( __CLASS__, 'wp_ajax_wetail_shipping_portal_handler' ) );
		add_action( 'wp_ajax_nopriv_wetail_shipping_portal', array(
			__CLASS__,
			'wp_ajax_wetail_shipping_portal_handler'
		) );
	}

	/**
	 * Sends a JSON response with an error message and terminates execution.
	 *
	 * @param string $message The error message to send in the JSON response.
	 *
	 * @return void
	 */
	private static function wss_send_json_error( $message ) {
		wp_send_json_error( array( 'error' => $message ) );
	}

	/**
	 * Get error message for minimum order value validation
	 *
	 * @param float $min_value The minimum required value
	 * @return string Localized error message
	 */
	private static function get_min_order_value_error_message( $min_value ) {
		return sprintf(
			__( 'A return label could not be created because the order value was below %s SEK.', 'wetail-shipping' ),
			number_format( $min_value, 2 )
		);
	}

	/**
	 * Get error message for days since purchase validation
	 *
	 * @param int $max_days The maximum allowed days
	 * @return string Localized error message
	 */
	private static function get_days_since_purchase_error_message( $max_days ) {
		return sprintf(
			__( 'A return label could not be created because the purchase was made more than %s days ago.', 'wetail-shipping' ),
			$max_days
		);
	}

	/**
	 * Validate order for return label creation
	 *
	 * @param \WC_Order $wc_order The WooCommerce order object
	 * @return array|true Returns true if valid, array with error message if invalid
	 */
	private static function validate_order_for_return( $wc_order ) {
		$min_order_value = get_option( 'ws_min_order_value_for_return', '' );
		$max_days_since_purchase = get_option( 'ws_max_days_since_purchase', '30' );

		if ( ! empty( $min_order_value ) ) {
			$order_total = $wc_order->get_total();
			if ( $order_total < floatval( $min_order_value ) ) {
				return array(
					'error' => 'min_order_value',
					'message' => self::get_min_order_value_error_message( floatval( $min_order_value ) )
				);
			}
		}

		if ( ! empty( $max_days_since_purchase ) ) {
			$order_date = $wc_order->get_date_created();
			if ( $order_date ) {
				$days_since = floor( ( time() - $order_date->getTimestamp() ) / DAY_IN_SECONDS );
				if ( $days_since > intval( $max_days_since_purchase ) ) {
					return array(
						'error' => 'max_days_since_purchase',
						'message' => self::get_days_since_purchase_error_message( intval( $max_days_since_purchase ) )
					);
				}
			}
		}

		return true;
	}

	/** Formats order items
	 * @return array
	 * @since 1.2.0
	 */
	public static function format_order_items() {
		$order_items           = $_REQUEST[ 'order_items' ]; // {"product_id":1, "quantity":1}
		$order_items_formatted = array();
		foreach ( $order_items as $order_item ) {
			if (
				( $item_id = filter_var( $order_item[ 'product_id' ], FILTER_SANITIZE_NUMBER_INT ) )
				&&
				( $quantity = filter_var( $order_item[ 'quantity' ], FILTER_SANITIZE_NUMBER_INT ) )
			) {
				$order_items_formatted[ intval( $item_id ) ] = $quantity;
			}
		}
		wetail_shipping_write_log( $order_items_formatted );
		wetail_shipping_write_log( $order_items );

		return $order_items_formatted;
	}

	/**
	 * Handles the AJAX request for the wetail shipping portal.
	 *
	 * @return void
	 */
	public static function wp_ajax_wetail_shipping_portal_handler() {
		header( 'Content-Type: application/json' );
		header( 'Cache-Control: no-cache, must-revalidate' );
		header( 'Pragma: no-cache' );

		if ( ! wp_verify_nonce( $_REQUEST[ 'nonce' ], 'wetail-shipping-return-portal-nonce' ) ) {
			self::wss_send_json_error( __( 'Invalid nonce', SLUG ) );
		}

		$order_number = filter_var( $_REQUEST[ 'order_number' ], FILTER_SANITIZE_NUMBER_INT );
		if ( ! $order_number ) {
			self::wss_send_json_error( __( 'Invalid order number', SLUG ) );
		}
		$wc_order = wc_get_order( $order_number );

		$sub_action = $_REQUEST[ 'do' ];
		switch ( $sub_action ) {
			case 'order_verification':
				$order_email = filter_var( $_REQUEST[ 'order_email' ], FILTER_SANITIZE_EMAIL );
				if ( ! $order_email ) {
					self::wss_send_json_error( __( 'Invalid email', SLUG ) );
				}
				if ( ( ! $wc_order ) || ( $order_email !== $wc_order->get_billing_email() ) ) {
					self::wss_send_json_error( __( 'Cannot find order', SLUG ) );
				}

				// Validate order for return label creation
				$validation_result = self::validate_order_for_return( $wc_order );
				if ( is_array( $validation_result ) && isset( $validation_result[ 'error' ] ) ) {
					self::wss_send_json_error( $validation_result[ 'message' ] );
				}

				$return_data = array(
					'order_password' => $wc_order->get_order_key(),
					'order_items'    => self::get_ajax_return_order_items( $wc_order ),
				);
				wp_send_json_success( $return_data );
			case 'order_return_items':
				$order_password = filter_var( $_REQUEST[ 'order_password' ], FILTER_SANITIZE_STRING );
				if ( ( ! $wc_order ) || ( $order_password !== $wc_order->get_order_key() ) ) {
					self::wss_send_json_error( __( 'Cannot find order', SLUG ) );
				}

				$order_items_formatted   = self::format_order_items();
				$qr_phone_number         = sanitize_text_field( $_REQUEST[ 'qr_phone_number' ] );

				try {

					$response_data = Wetail_Shipping_Shipping_Label::create_return_shipping_label(
						$wc_order,
						self::get_shipping_service_id(),
						$qr_phone_number,
						self::get_return_carrier(),
						$order_items_formatted
					);

					if ( isset( $response_data[ 'qr_code' ] ) && ! empty( $response_data[ 'qr_code' ] ) ){

						if ( isset( $response_data[ 'qr_code' ][ 'qr_code_data' ] ) ) {
							wp_send_json_success( array(
								'qr_code_data' => $response_data[ 'qr_code' ][ 'qr_code_data' ]
							) );
						}
						else if ( isset( $response_data[ 'qr_code' ][ 'qr_code_image_url' ] ) ) {
							wp_send_json_success( array(
								'qr_code_image_url' => $response_data[ 'qr_code' ][ 'qr_code_image_url' ]
							) );
						}
						else if ( isset( $response_data[ 'qr_code' ][ 'label_free_code' ] ) ) {
							wp_send_json_success( array(
								'bring_return_number' => $response_data[ 'qr_code' ][ 'label_free_code' ]
							) );
						}
						self::add_order_note( $wc_order->get_id() );
					}
					else if ( isset( $response_data[ 'shipping_label' ] ) && isset( $response_data[ 'shipping_label' ][ 'data' ] ) ) {
						self::add_order_note( $wc_order->get_id() );
						$chosen_return_carrier  = self::get_return_carrier();
						if ( 'dhl' === $chosen_return_carrier ){
							if ( isset( $response_data[ 'shipping_label' ][ 'shipment' ] ) && isset( $response_data[ 'shipping_label' ][ 'shipment' ]['shipping_company_shipment_id'] ) ) {
								wp_send_json_success( array(
									'link' => 'https://hamta.dhl.com/' . $response_data[ 'shipping_label' ][ 'shipment' ]['shipping_company_shipment_id'],
								) );
							}
						}
						else{
							wp_send_json_success( array(
								'pdf' => 'data:application/pdf;base64,' . $response_data[ 'shipping_label' ][ 'data' ],
							) );
						}

					} else {
						self::wss_send_json_error( __( 'Unknown error', SLUG ) );
					}
				} catch ( \Throwable $t ) {
					Wetail_Shipping_Order_Controller::handle_sync_error( $wc_order, $t->getMessage() );
					self::wss_send_json_error( $t->getMessage() );
				}
				break;
			default:
				self::wss_send_json_error( __( 'Unknown action', SLUG ) );
		}
		wp_die();
	}

	/** Adds a note on the order
	 *
	 * @param $wc_order_id
	 * @since 1.1.5
	 */
	public static function add_order_note( $wc_order_id ){
		$tracking_link = isset( $response_data[ 'shipping_label' ][ 'shipment' ], $response_data[ 'shipping_label' ][ 'shipment' ][ 'tracking_url' ] ) ? $response_data[ 'shipping_label' ][ 'shipment' ][ 'tracking_url' ] : false;

		$order_note = __( "Return labels has been created. Tracking not provided", SLUG );

		if ( $tracking_link ) {
			$tracking_link = sprintf( '<a href="%s" target="_blank">%s</a>', $tracking_link, __( 'Tracking link', SLUG ) );
			$order_note    = sprintf( __( "Customer has returned items. Return labels have been created with %s.", SLUG ), $tracking_link );
		}

		wc_create_order_note( $wc_order_id, nl2br( $order_note ) );
	}

	/** Extracts carrier name from service
	 * @return string
	 * @since  1.2.0
	 */
	public static function get_return_carrier(): string {

		$value = self::get_shipping_service_id();
		if ( str_starts_with( $value, 'db_schenker' ) ) {
			return 'db_schenker';
		} else {
			$parts = explode( '_', $value );

			return $parts[ 0 ];
		}
	}

	public static function wetail_return_portal_shortcode_handler(): string {
		$link_html              = sprintf( '<a target="_blank" class="wetail-return-portal__policy" href="%s">%s</a>',
			apply_filters( self::$return_prefix . 'return_policy_url', get_option( 'wetail_shipping_returns_url' ) ? get_option( 'wetail_shipping_returns_url' ) : get_permalink( wc_terms_and_conditions_page_id() ) ),
			apply_filters( self::$return_prefix . 'return_policy_text', esc_html__( 'Return policy', 'wetail-shipping' ) )
		);
		$chosen_return_carrier  = self::get_return_carrier();
		$final_step_button_text = '';

		switch ( $chosen_return_carrier ) {
			case 'postnord':
				$final_step_text = __( 'Your return label will be sent to you via SMS. Show the QR code at the Postnord service point to complete your return.', 'wetail-shipping' );
				break;
			case 'bring':
				$final_step_text = __( 'Your return label will be sent to you via SMS. Show the QR code at the Bring service point to complete your return.', 'wetail-shipping' );
				break;
			case 'db_schenker':
				$final_step_text        = __( 'Your return label will be sent to you on email', 'wetail-shipping' );
				$final_step_button_text = __( 'Download return label', 'wetail-shipping' );
				break;
			case 'dhl':
				$final_step_text        = __( 'Go to DHL portal to complete your return', 'wetail-shipping' );
				$final_step_button_text = __( 'GO TO DHL', 'wetail-shipping' );
				break;
			default:
				$final_step_text        = __( 'Download and print your return label to complete your return', 'wetail-shipping' );
				$final_step_button_text = __( 'Download return label', 'wetail-shipping' );
		}

		wp_enqueue_style(
			'wetail-shipping-portal',
			URL . '/assets/css/return-portal.css',
			[],
			VERSION . '-' . filemtime( PATH . '/assets/css/return-portal.css' )
		);

		wp_enqueue_script(
			'wetail-shipping-portal',
			URL . '/assets/js/return-portal.js',
			[ 'jquery', 'wp-util' ],
			VERSION . '-' . filemtime( PATH . '/assets/js/return-portal.js' )
		);

		wp_localize_script( 'wetail-shipping-portal', '__wetail_shipping_return_portal', array(
			'nonce'          => wp_create_nonce( 'wetail-shipping-return-portal-nonce' ),
			'ajaxurl'        => admin_url( 'admin-ajax.php' ),
			'order_number'   => 0,
			'order_password' => '',
			'return_carrier' => self::get_return_carrier(),
			'i18n'           => array(
				'order_verification_error' => apply_filters( self::$return_prefix . 'order_verification_error_message', esc_html__( 'We could not find a match. Please check your order number or email again', 'wetail-shipping' ) ),
				'email_error'              => __( 'Please enter a valid email address', 'wetail-shipping' ),
				'field_empty_error'        => sprintf( __( 'This field %s is required', 'wetail-shipping' ), '[field]' ),
				'phone_error'              => __( 'Please enter a valid phone number', 'wetail-shipping' ),
				'bring_return_number_message' => sprintf(__('Write this number on the package: %s. Learn more about Bring\'s label-free solution here: %s', SLUG), '[bring_return_number]', '<a href="https://www.bring.se/privat/ta-emot/etikettfri-retur">https://www.bring.se/privat/ta-emot/etikettfri-retur</a>'),
			)
		) );

		ob_start(); ?>
		<div id="wetail-return-portal" class="wetail-return-portal">
			<div class="wetail-return-portal__content">
				<div class="wetail-return-portal__steps">
					<!-- Step 1 -->
					<div
						class="wetail-return-portal__step wetail-return-portal__step--order-verification wetail-return-portal__step--current"
						data-step="1">
						<h2><?php echo apply_filters( self::$return_prefix . 'order_verification_title', esc_html__( 'Return portal', 'wetail-shipping' ) ); ?></h2>
						<p><?php echo apply_filters( self::$return_prefix . 'order_verification_subtitle', esc_html__( 'Submit your order number and email to find your order.', 'wetail-shipping' ) ); ?> </p>
						<ul class="wetail-return-portal__error"></ul>
						<form novalidate class="wetail-return-portal__form">
							<div class="wetail-return-portal__form-field">
								<label
									for="order-number"><?php echo apply_filters( self::$return_prefix . 'order_verification_number_label_text', esc_html__( 'Order number', 'wetail-shipping' ) ); ?></label>
								<input type="text" autocomplete="order-number" id="order-number" name="order-number"
								       required>
							</div>
							<div class="wetail-return-portal__form-field">
								<label
									for="order-email"><?php echo apply_filters( self::$return_prefix . 'order_verification_email_label_text', esc_html__( 'Email', 'wetail-shipping' ) ); ?></label>
								<input type="email" autocomplete="email" id="order-email" name="email" required>
							</div>
							<?php
							// Mobiltelefon för returfraktsedel
							if ( $chosen_return_carrier === 'postnord' || $chosen_return_carrier === 'bring' ): ?>
								<div class="wetail-return-portal__form-field">
									<label
										for="qr_code_to_phonenumber"><?php echo apply_filters( self::$return_prefix . 'order_verification_qr_code_to_phonenumber_label_text', esc_html__( 'Mobile phone for return label', 'wetail-shipping' ) ); ?></label>
									<input type="tel" autocomplete="tel" id="qr_code_to_phonenumber"
									       name="qr_code_to_phonenumber"
									       required>
								</div>
							<?php endif; ?>

							<button type="submit"
							        class="wetail-return-portal__button--continue wetail-return-portal__button">
								<?php echo apply_filters( self::$return_prefix . 'order_verification_button_text', esc_html__( 'Continue', 'wetail-shipping' ) ); ?>
								<div class="spinner"></div>
							</button>
							<?php echo $link_html; ?>
						</form>
					</div>

					<!-- Step 2 -->
					<div
						class="wetail-return-portal__step wetail-return-portal__step--items-return wetail-return-portal__step--hidden"
						data-step="2">
						<h2><?php echo apply_filters( self::$return_prefix . 'items_return_title', esc_html__( 'Select items to return', 'wetail-shipping' ) ); ?></h2>
						<form novalidate class="wetail-return-portal__form" id="order_items">
							<ul class="order-items"></ul>

							<button type="submit"
							        class="wetail-return-portal__button--continue wetail-return-portal__button">
								<?php echo apply_filters( self::$return_prefix . 'items_return_button_text', esc_html__( 'Continue', 'wetail-shipping' ) ); ?>
								<div class="spinner"></div>
							</button>
							<?php echo $link_html; ?>
						</form>
					</div>

					<!-- Step 3 -->
					<div
						class="wetail-return-portal__step wetail-return-portal__step--pdf wetail-return-portal__step--hidden"
						data-step="3">
						<h2><?php echo apply_filters( self::$return_prefix . 'pdf_title', esc_html__( 'Complete return', 'wetail-shipping' ) ); ?></h2>
						<?php if ( $chosen_return_carrier === 'postnord' || $chosen_return_carrier === 'bring' ): ?>
							<div id="wetail-return-portal__qr"></div>
						<?php endif; ?>
						<p class="wetail-return-portal__pdf-subtitle">
							<?php echo apply_filters( self::$return_prefix . 'pdf_subtitle', $final_step_text ); ?>
						</p>
						<?php if ( $chosen_return_carrier === 'db_schenker' ) : ?>
							<div class="wetail-return-portal__or">
								<span><?php echo __('or', SLUG) ?></span>
							</div>
						<?php endif; ?>
						<?php if ( $chosen_return_carrier !== 'postnord' && $chosen_return_carrier !== 'bring' ): ?>
							<a id="print-label"
								<?php echo $chosen_return_carrier !== 'dhl' ? "download=\"\"" : ""; ?>
                               href=""
                               class="wetail-return-portal__button--print-label wetail-return-portal__button wetail-return-portal__button--last-step">
								<?php if ( $chosen_return_carrier !== 'dhl' ): ?>
									<svg width="15" height="13" viewBox="0 0 15 13" fill="none" xmlns="http://www.w3.org/2000/svg">
										<path d="M10.4028 0.130859C10.5835 0.130967 10.7329 0.271796 10.7437 0.452148L10.9858 4.57031H12.4517C12.5877 4.57039 12.7111 4.6515 12.7651 4.77637L14.1313 7.93555C14.1484 7.97498 14.1551 8.01683 14.1567 8.05859C14.1576 8.0683 14.1597 8.07797 14.1597 8.08789V12.5273C14.1597 12.716 14.0065 12.8691 13.8179 12.8691H1.18213C0.993513 12.8691 0.840332 12.716 0.840332 12.5273V8.08789C0.840335 8.08032 0.841797 8.07288 0.842285 8.06543C0.843157 8.02135 0.850661 7.97717 0.868652 7.93555L2.23486 4.77637C2.28898 4.65149 2.41222 4.57031 2.54834 4.57031H4.01416L4.25635 0.452148C4.26706 0.271729 4.4164 0.13086 4.59717 0.130859H10.4028ZM1.52295 12.1865H13.4771V8.42969H1.52295V12.1865ZM2.89014 9.35156C3.07854 9.35182 3.23096 9.50491 3.23096 9.69336C3.23083 9.8817 3.07846 10.0339 2.89014 10.0342C2.7016 10.0342 2.54847 9.88186 2.54834 9.69336C2.54834 9.50475 2.70152 9.35156 2.89014 9.35156ZM1.70166 7.72949H13.2983L12.228 5.25391H11.0259L11.0659 5.93652H11.5991C11.7875 5.93683 11.9399 6.0899 11.9399 6.27832C11.9398 6.46661 11.7874 6.61883 11.5991 6.61914H3.23193C3.04341 6.61914 2.89029 6.4668 2.89014 6.27832C2.89014 6.08971 3.04332 5.93652 3.23193 5.93652H3.93408L3.97412 5.25391H2.77197L1.70166 7.72949ZM4.61768 5.93652H10.3823L10.3022 4.57031H4.69775L4.61768 5.93652ZM4.71826 4.22852H10.2817L10.0806 0.813477H4.91943L4.71826 4.22852ZM9.55029 3.0332C9.64432 3.03343 9.72006 3.11007 9.72021 3.2041C9.72021 3.29827 9.64441 3.37477 9.55029 3.375H7.32959C7.23547 3.37478 7.15967 3.29827 7.15967 3.2041C7.15982 3.11006 7.23556 3.03342 7.32959 3.0332H9.55029ZM9.55029 2.35059C9.64441 2.35081 9.72021 2.42732 9.72021 2.52148C9.7202 2.61564 9.6444 2.69216 9.55029 2.69238H7.32959C7.23548 2.69217 7.15968 2.61564 7.15967 2.52148C7.15967 2.42731 7.23547 2.3508 7.32959 2.35059H9.55029ZM6.64502 1.66797C6.73927 1.66804 6.81592 1.7446 6.81592 1.83887C6.81567 1.93292 6.73912 2.00872 6.64502 2.00879H5.62061C5.52645 2.00879 5.44996 1.93296 5.44971 1.83887C5.44971 1.74456 5.5263 1.66797 5.62061 1.66797H6.64502ZM9.55029 1.66797C9.64441 1.66819 9.72021 1.7447 9.72021 1.83887C9.71996 1.93282 9.64425 2.00856 9.55029 2.00879H7.32959C7.23562 2.00857 7.15992 1.93282 7.15967 1.83887C7.15967 1.7447 7.23547 1.66819 7.32959 1.66797H9.55029Z" fill="white"/>
									</svg>
								<?php endif; ?>
								<?php echo apply_filters( self::$return_prefix . 'pdf_button_text', $final_step_button_text ); ?>
							</a>
						<?php endif; ?>
						<?php echo $link_html; ?>
					</div>
				</div>
			</div>
		</div>
		<?php include_once PATH . '/templates/return-item.php'; ?>
		<?php return ob_get_clean();
	}

	/**
	 * Retrieves order items from a WooCommerce order and returns them in a formatted array.
	 *
	 * @param \WC_Order $wc_order The WooCommerce order object.
	 *
	 * @return array An array of formatted order items, each containing product details like ID, image, name, SKU, and quantity.
	 */
	private static function get_ajax_return_order_items( $wc_order ) {
		$return_data = array();
		foreach ( $wc_order->get_items() as $order_item ) {
			if ( is_a( $order_item, 'WC_Order_Item_Product' ) ) {
				$product       = $order_item->get_product();
				$image         = wp_get_attachment_image_src( $product->get_image_id() );
				$image         = $image ? $image[ 0 ] : '';
				$return_data[] = array(
					'product_id'       => $order_item->get_id(),
					'product_src'      => $image,
					'product_name'     => $order_item->get_name(),
					'product_sku'      => $product->get_sku(),
					'product_quantity' => $order_item->get_quantity(),
				);
			}
		}

		return $return_data;
	}

	private static function get_shipping_service_id() {
		return get_option( 'wetail_shipping_return_carrier_service', Wetail_Shipping_Order_Admin::get_return_service_options_data()[ 0 ][ 'service_id' ] );
	}
}
