<?php

namespace PostenBringCheckout\checkout\integrations\dintero;

use WC_Order;

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

/**
 * Dintero integration
 *
 * Class responsible for handling all Dintero integration specifics
 *
 * @since 1.1.33
 */
class DinteroIntegration {

	/**
	 * Adds meta_data in a format Dintero can read
	 *
	 * @param array  $rate The shipping rate.
	 * @param array  $bring_rate The raw rate details received Bring APIs.
	 * @param string $to_country The destination country code.
	 * @return array The updated rate
	 * @since 1.1.37
	 */
	public static function add_dintero_meta_data($rate, $bring_rate, $to_country ) {
		$dintero_settings = get_option( 'woocommerce_dintero_checkout_settings' );
		if ( ! isset( $dintero_settings ) || ! wc_string_to_bool( $dintero_settings['enabled'] ?? 'no' ) ) {
			return $rate;
		}

		$brand = strtolower($rate['meta_data']['brand']);
		$rate['meta_data']['carrier'] = $brand;

		$rate = self::add_pickup_point_details( $rate, $bring_rate, $to_country, $brand );
		return self::add_description( $rate, $bring_rate );
	}

	/**
	 * Adds the available pickup points to the rate as meta_data in a format Dintero can read
	 *
	 * @param array  $rate The shipping rate.
	 * @param array  $bring_rate The raw rate details received Bring APIs.
	 * @param string $to_country The destination country code.
	 * @param string $brand The brand to apply
	 * @return array The updated rate
	 * @since 1.1.33
	 */
	private static function add_pickup_point_details($rate, $bring_rate, $to_country, $brand ) {
		if ( empty( $bring_rate['pickupPoints'] ) ) {
			return $rate;
		}

		try {
			$rate['meta_data']['krokedil_pickup_points'] = wp_json_encode(
				array_map(function($pickupPoint) use ($to_country, $brand) {
					$address = explode(', ', $pickupPoint['address']);
					preg_match( '/^(\d{4,5})\s*(.*)$/', $address[1], $addressParts );
					$eta = $pickupPoint['leadTime'] ?? [];
					$distance = $brand === 'bring' ? ' • (' . $pickupPoint['distance'] . 'km)' : '';

					return array(
						'id' => $pickupPoint['id'],
						'name' => $pickupPoint['displayName'],
						'description' => $eta['description'] ?? '',
						'address' => array(
							'street' => $pickupPoint['address'] . $distance,
							'city' => $addressParts[2],
							'postcode' => $addressParts[1],
							'country' => $to_country
						)
					);
				}, $bring_rate['pickupPoints'] )
			);

			return $rate;
		} catch (\Exception $e) {
			wc_get_logger()->error( 'Failed to enrich Dintero rates with pickup points - ' . $e->getMessage(), array( 'source' => 'posten-bring-checkout' ) );
			return $rate;
		}
	}

	/**
	 * Adds dummy settings to shipping options in order to make Dintero look for a description to display
	 *
	 * @param string  $id The shipping option id.
	 * @param int  $instance_id The shipping option instance id.
	 *
	 * @since 1.1.37
	 */
	public static function add_shipping_rate_settings($id, $instance_id ) {
		$dintero_settings = get_option( 'woocommerce_dintero_checkout_settings' );
		$option_key = "woocommerce_{$id}_{$instance_id}_settings";
		$existing = get_option( $option_key, null );

		if ( ! isset( $dintero_settings ) || ! wc_string_to_bool( $dintero_settings['enabled'] ?? 'no' ) ) {
			return;
		}

		if ( null === $existing ) {
			update_option( $option_key, array( 'initialized' => 1 ) );
		}
	}

	/**
	 * Adds a description to shipping options displayed via Dintero
	 *
	 * @param array  $rate The shipping rate.
	 * @param array  $bring_rate The raw rate data.
	 * @return array The updated rate
	 * @since 1.1.37
	 */
	private static function add_description( $rate, $bring_rate ) {
		if ( isset( $bring_rate['leadTime']['description'] ) ) {
			$rate['meta_data']['krokedil_description'] = $bring_rate['leadTime']['description'];
		}

		return $rate;
	}

	/**
	 * Attempts to locate the selected pickup point id if set by Dintero
	 *
	 * @param WC_Order $order The order.
	 * @return string|null The selected pickup point id
	 * @since 1.1.33
	 */
	public static function get_selected_pickup_point( $order ) {
        $shipping_methods = $order->get_shipping_methods();
        if ( ! is_array( $shipping_methods ) || count( $shipping_methods ) == 0 ) {
            return null;
        }

		$shipping_option = current( $shipping_methods );
		return $shipping_option->get_meta( 'krokedil_selected_pickup_point_id' );
	}
}
