<?php
/**
 * GurmeCargo için sipariş niteliklerini eşleştiren GCARGO_Shipment_Map_WC_Order sınıfını barındıran dosya.
 *
 * @package GurmeHub
 */

/**
 * GCARGO_Map_WC_Order sınıfı
 */
class GCARGO_Shipment_Map_WC_Order extends GCARGO_Mappers {

	/**
	 * WC siparişi.
	 *
	 * @var WC_Order $order
	 */
	protected $order;

	/**
	 * Eklenti Prefix
	 *
	 * @var string $prefix
	 */
	protected $prefix = GCARGO_PREFIX;

	/**
	 * Depolar.
	 *
	 * @var array
	 */
	public $warehouses;

	/**
	 * Kargo entegrasyonları.
	 *
	 * @var array
	 */
	public $cargo_integrations;

	/**
	 * Varsayılan gönderi ayarları.
	 *
	 * @var array
	 */
	public $shipment_setting;

	/**
	 * Kurucu method
	 *
	 * @param int|string $order_id WC sipariş kimliği.
	 * @param array|null $warehouses Depolar.
	 * @param array|null $cargo_integrations Kargo entegrasyonları.
	 * @param array|null $shipment_setting Varsayılan ayarlar.
	 */
	public function __construct( $order_id, $warehouses = null, $cargo_integrations = null, $shipment_setting = null ) {
		parent::__construct( $order_id, $warehouses, $cargo_integrations );
		$this->settings = $shipment_setting ? $shipment_setting : gcargo_saas_shipment_settings()->get_settings(); // phpcs:ignore
	}


	/**
	 * Geri dönüş URL tespit eden fonskiyon.
	 */
	protected function get_notification_url() {
		return home_url( "/{$this->prefix}-notification" );
	}

	/**
	 * Ürünlerin verileri hazırlayan fonksiyon.
	 *
	 * @param object $item WC sipariş kimliği.
	 */
	protected function prepare_line_item( $item ) {
		return array(
			'action_qty' => (int) wc_get_order_item_meta( $item->get_id(), '_gcargo_shipped_qty', true ),
		);
	}

	/**
	 * Gönderi durumunu getiren fonksiyon.
	 *
	 * @return string
	 */
	public function get_status() {

		$shipments = gcargo_shipments()->get_shipments_by_order_id( $this->order->get_id() );
		if ( empty( $shipments ) ) {
			return 'ready_for_shipment';
		}

		$unpackaged_item_qty = 0;

		foreach ( $this->order->get_items() as $item ) {
			$sold_qty             = $item->get_quantity();
			$shipped_qty          = (int) wc_get_order_item_meta( $item->get_id(), '_gcargo_shipped_qty', true );
			$unpackaged_item_qty += $sold_qty - $shipped_qty;
		}

		if ( $unpackaged_item_qty ) {
			return 'partial_shipped';
		}

		return 'all_shipped';
	}

	/**
	 * Doğrudan istek oluşturma methodu.
	 *
	 * @return array
	 */
	public function create_request() {

		$request = array_merge(
			$this->get_payment(),
			[ 'lines' => array_values( array_filter( $this->get_lines(), fn( $line ) => $line['quantity'] ) ) ],
			[ 'customer' => $this->get_customer() ],
			[ 'need_shipment' => $this->get_status() !== 'all_shipped' ],
			[
				'current_shipments' => array_map(
					fn( $shipment ) => $shipment->id,
					gcargo_shipments()->get_shipments_by_order_id( $this->order->get_id() )
				),
			],
			$this->get_default(),
		);

		$gate    = new GCARGO_Gate();
		$request = $gate->apply_gate_rules_to_shipment_properties( $request, $this->order );

		return apply_filters( "{$this->prefix}_shipment_map_wc_order_request", $request, $this->order );
	}

	/**
	 * Varsayılan değerleri getirir ve gate kurallarını uygular.
	 *
	 * @return array
	 */
	protected function get_default() {
		$default = array_merge(
			$this->settings,
			array(
				'cargo_integration_id' => array_column( $this->cargo_integrations, 'id', 'is_default' )[ true ] ?? null,
				'warehouse_id'         => array_column( $this->warehouses, 'id', 'is_default' )[ true ] ?? null,
			),
			array(
				'platform_id'      => $this->order->get_id(),
				'platform_d_id'    => $this->order->get_id(),
				'note'             => $this->order->get_customer_note(),
				'platform'         => 'woocommerce',
				'notification_url' => $this->get_notification_url(),
				'desi'             => 1,
				'kg'               => $this->total_weight,
				'package_count'    => 1,
			)
		);

		$package_settings = gcargo_package_settings()->get_settings();
		if ( ! empty( $package_settings ) && ! empty( $package_settings['package_count_enabled'] ) ) {
			$total_packages   = 0;
			$per_product_pack = (int) ( $package_settings['package_count'] ?? 1 );
			foreach ( array_filter( $this->get_lines(), fn( $line ) => $line['quantity'] ) as $line ) {
				$total_packages += ( (int) $line['quantity'] ) * $per_product_pack;
			}

			$default['package_count'] = max( 1, $total_packages );
		}

		return $default;
	}
}
