<?php

namespace PostenBringCheckout\admin\api\models;

use PostenBringCheckout\admin\WeightUtils;
use WC_Order;
use WC_Order_Item;
use WC_Order_Item_Product;

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

class OrderMapper {
	public static function mapToOrder( $wc_order, array $mybring_bookings, array $order_validation_errors ): Order {
		$order_shipping_option = self::getOrderShippingOption( $wc_order );
		$total_weight          = self::getTotalWeight( $wc_order );
		$to_country            = $wc_order->get_shipping_country();
		$from_country          = get_option( 'woocommerce_default_country' );
		$items                 = self::get_items( $wc_order );

		$recipientName    = $wc_order->get_billing_first_name() . ' ' . $wc_order->get_billing_last_name();
		$shippingAddress1 = $wc_order->get_shipping_address_1();
		$shippingCity     = $wc_order->get_shipping_city();
		$shippingPostcode = $wc_order->get_shipping_postcode();

		return new Order(
			$wc_order->get_id(),
			$from_country,
			$to_country,
			$order_shipping_option,
			$total_weight,
			$mybring_bookings,
			$order_validation_errors,
			$items,
			$recipientName,
			$shippingAddress1,
			$shippingPostcode,
			$shippingCity,
		);
	}

	private static function getOrderShippingOption( $wcOrder ): string {
		$shipping_method = current( $wcOrder->get_shipping_methods() );
		if ( $shipping_method ) {
			$shippingMetaData = $shipping_method->get_meta_data();
			$result           = array_filter(
				$shippingMetaData,
				function ( $item ) {
					return $item->key === 'service_id';
				}
			);
			$firstMatch       = reset( $result );

			return $firstMatch ? $firstMatch->value : '';
		}
		return '';
	}

	private static function getTotalWeight( $wc_order ) {
		$total_weight = 0;
		foreach ( $wc_order->get_items() as $item ) {
			$product = $item->get_product();
			if ( $product ) {
				$total_weight += WeightUtils::getWeightInGrams( $product->get_weight() ) * $item->get_quantity();
			}
		}

		return $total_weight;
	}
	private static function get_items( $wc_order ): array {
		return array_values(
			array_map(
				function ( $item ) {
					$product = $item->get_product();

					return new OrderItem(
						$item->get_quantity(),
						WeightUtils::getWeightInGrams($product->get_weight()),
						$product->get_name(),
					);
				},
				array_filter( $wc_order->get_items(), function ( $item ) {
					return $item instanceof WC_Order_Item_Product && $item->get_product() != false;
				} )
			)
		);
	}
}
