<?php

namespace PostenBringCheckout\checkout\integrations\vipps;

use PostenBringCheckout\checkout\PostenBringCheckoutPublic;
use WC_Order;
use WC_Shipping_Method;
use WC_Shipping_Rate;

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

/**
 * Vipps integration
 *
 * Class responsible for handling all Vipps integration specifics
 *
 * @since 0.1.19
 */
class VippsIntegration {

	/**
	 * Registers our pickup points with Vipps/MobilePay if this plugin is active.
	 *
	 * @param array              $pickup_points The pickup points.
	 * @param WC_Shipping_Rate   $shipping_rate The relevant shipping rate.
	 * @param WC_Shipping_Method $shipping_method The relevant shipping method.
	 * @param WC_Order           $order WooCommerce order.
	 * @return array The pickup points.
	 * @since 0.1.19
	 */
	public function add_pickup_points_to_vipps( array $pickup_points, $shipping_rate, $shipping_method, $order ): array {
		if ( $shipping_rate->get_id() === 'posten-bring-checkout-pickup-point' || $shipping_rate->get_id() === 'posten-bring-checkout-parcel-locker' ) {
			$meta_data     = $shipping_rate->get_meta_data();
			$pickup_points = $meta_data['pickup_points'];
			$to_country    = $order->get_shipping_country();

			if ( isset( $pickup_points ) && is_array( $pickup_points ) ) {
				$pickup_points = array_map(
					function ( $pickup_point ) use ( $to_country ) {
						$address = explode( ', ', $pickup_point['address'] );
						preg_match( '/^(\d{4,5})\s*(.*)$/', $address[1], $addressParts );

						if ( ! empty( $pickup_point['leadTime'] ) ) {
							$lead_time = array(
								'earliest' => $pickup_point['leadTime']['deliveryDate'],
								'latest'   => $pickup_point['leadTime']['deliveryDate'],
							);
						}

						return array(
							'address'      => $address[0],
							'postalCode'   => $addressParts[1],
							'city'         => $addressParts[2],
							'country'      => $to_country,
							'id'           => $pickup_point['id'],
							'name'         => $pickup_point['displayName'],
							'openingHours' => explode( ', ', $pickup_point['openingHours'] ),
							'leadTime'     => $lead_time ?? null,
						);
					},
					$pickup_points
				);
			}
		}
		return $pickup_points;
	}

	/**
	 * Registers the selected pickup point and delivery date from Vipps/MobilePay.
	 *
	 * @param WC_Order $order WooCommerce order.
	 * @param array    $shipping Vipps shipping object.
	 * @param array    $user Vipps user.
	 * @since 0.1.19
	 */
	public function register_order_meta_data_from_vipps( $order, $shipping, $user ) {
		$shipping_methods            = $order->get_shipping_methods();
		$selected_shipping_method    = current( $order->get_shipping_methods() );

		if ( !$selected_shipping_method ) {
			return;
		}

		$selected_shipping_method_id = $selected_shipping_method->get_method_id();
		if ( isset( $shipping_methods ) && ! empty( $selected_shipping_method_id ) ) {
			if ( isset( $shipping['pickupPoint'] ) ) {
				if ( $selected_shipping_method_id === 'posten-bring-checkout-pickup-point' || $selected_shipping_method_id === 'posten-bring-checkout-parcel-locker' ) {
					$selected_pickup_point_id = $shipping['pickupPoint']['id'];

					PostenBringCheckoutPublic::enrich_order_with_selected_pickup_point( $order, $selected_pickup_point_id );
				}
			} elseif ( isset( $shipping['timeslot']['date'] ) ) {
				if ( $selected_shipping_method_id === 'posten-bring-checkout-home-delivery' && $selected_shipping_method->meta_exists( 'lead_time' ) ) {
					$selected_delivery_date = $shipping['timeslot']['date'];
					$lead_time              = $selected_shipping_method->get_meta( 'lead_time' );
					$delivery_alternatives  = $lead_time['deliveryDateAlternatives'];

					if ( isset( $delivery_alternatives ) ) {
						$delivery_date = array_values(
							array_filter(
								$delivery_alternatives,
								function ( $delivery_alternative ) use ( $selected_delivery_date ) {
									return $delivery_alternative['deliveryDate'] == $selected_delivery_date;
								}
							)
						);

						if ( count( $delivery_date ) == 1 ) {
							PostenBringCheckoutPublic::enrich_order_with_selected_delivery_date( $order, $selected_delivery_date, $delivery_date[0]['shippingDate'] );
						}
					}
				}
			}
		}
	}

	/**
	 * Adds service description to shipping options presented in Vipps.
	 *
	 * @param string             $description WooCommerce order.
	 * @param WC_Shipping_Rate   $shipping_rate Shipping rate.
	 * @param WC_Shipping_Method $shipping_method Shipping method.
	 * @since 0.1.19
	 */
	public function add_rate_description_to_vipps( $description, $shipping_rate, $shipping_method ) {
		if ( str_starts_with( $shipping_rate->get_id(), 'posten-bring-checkout' ) ) {
			$meta_data = $shipping_rate->get_meta_data();
			return $meta_data['service_description'];
		}
		return $description;
	}

	/**
	 * Registers our home delivery alternatives with Vipps/MobilePay if this plugin is active.
	 *
	 * @param array              $time_slots The available time slots.
	 * @param WC_Shipping_Rate   $shipping_rate The relevant shipping rate.
	 * @param WC_Shipping_Method $shipping_method The relevant shipping method.
	 * @param WC_Order           $order WooCommerce order.
	 * @return array The pickup points.
	 * @since 0.1.19
	 */
	public function add_home_delivery_alternatives_to_vipps( array $time_slots, $shipping_rate, $shipping_method, $order ): array {
		if ( $shipping_rate->get_id() === 'posten-bring-checkout-home-delivery' ) {
			$meta_data             = $shipping_rate->get_meta_data();
			$lead_time             = $meta_data['lead_time'];
			$delivery_alternatives = $lead_time['deliveryDateAlternatives'];

			if ( isset( $delivery_alternatives ) && is_array( $delivery_alternatives ) ) {
				$time_slots = array_merge(
					...array_map(
						function ( $delivery_alternative ) {
							return array_map(
								function ( $time_window ) use ( $delivery_alternative ) {
									return array(
										'id'    => $delivery_alternative['deliveryDate'],
										'date'  => $delivery_alternative['deliveryDate'],
										'start' => $time_window['from'],
										'end'   => $time_window['to'],
									);
								},
								$delivery_alternative['deliveryWindows']
							);
						},
						$delivery_alternatives
					)
				);
			}
		}
		return $time_slots;
	}

	/**
	 * Registers delivery lead time with Vipps/MobilePay if this plugin is active.
	 *
	 * @param array              $delivery The lead time.
	 * @param WC_Shipping_Rate   $shipping_rate The relevant shipping rate.
	 * @param WC_Shipping_Method $shipping_method The relevant shipping method.
	 * @param WC_Order           $order WooCommerce order.
	 * @return array The lead time.
	 * @since 0.1.19
	 */
	public function add_lead_time( $delivery, $shipping_rate, $shipping_method, $order ) {
		if ( in_array( $shipping_rate->get_id(), array( 'posten-bring-checkout-mailbox', 'posten-bring-checkout-parcel-to-business', 'posten-bring-checkout-groupage', 'posten-bring-checkout-pallet' ), true ) ) {
			$meta_data = $shipping_rate->get_meta_data();
			$lead_time = $meta_data['lead_time'];

			if ( isset( $lead_time['deliveryDate'] ) ) {
				return array(
					'earliest' => $lead_time['deliveryDate'],
					'latest'   => $lead_time['deliveryDate'],
				);
			}
		}
		return $delivery;
	}

	public function remove_brand_from_title_in_vipps_checkout( $shipping_methods, $order ) {
		if ( $order->get_meta( '_vipps_checkout' ) ) {

			$shipping_methods['shippingDetails'] = array_values(
				array_map(
					function ( $shipping_method ) {
						$brand = $shipping_method['brand'];
						if ( $brand == 'Posten' || $brand == 'Bring' ) {
								$label_parts = explode( ' - ', $shipping_method['title'] );
							if ( count( $label_parts ) == 2 ) {
								$shipping_method['title'] = $label_parts[1];
							}
						}
						return $shipping_method;
					},
					$shipping_methods['shippingDetails']
				)
			);

		}

		//wc_get_logger()->info( 'Vipps debug ' . wp_json_encode( $shipping_methods ), array( 'source' => 'posten-bring-checkout' ) );

		return $shipping_methods;
	}
}
