<?php //phpcs:ignore WordPress.Files.FileName.InvalidClassFileName
/**
 * GurmeCargo shipment ve returned için abstract sınıfını barındırır.
 *
 * @package GurmeHub
 */

/**
 * GurmeCargo GCARGO_Mappers abstract sınıfı.
 */
abstract class GCARGO_Mappers {
	/**
	 * WC siparişi.
	 *
	 * @var WC_Order
	 */
	protected $order;

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

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

	/**
	 * Toplam ağırlık.
	 *
	 * @var int
	 */
	public $total_weight = 0;

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

	/**
	 * Varsayılan ayarlar.
	 *
	 * @var array
	 */
	protected $settings;

	/**
	 * Kurucu method.
	 *
	 * @param int        $order_id           WooCommerce sipariş kimliği.
	 * @param array|null $warehouses         Depolar.
	 * @param array|null $cargo_integrations Kargo entegrasyonları.
	 */
	public function __construct( $order_id, $warehouses = null, $cargo_integrations = null ) {
		$this->order              = wc_get_order( $order_id );
		$this->warehouses         = $warehouses ? $warehouses : gcargo_saas_warehouses_settings()->get_settings();
		$this->cargo_integrations = $cargo_integrations ? $cargo_integrations : gcargo_saas_cargo_integrations_settings()->get_settings();
	}

	/**
	 * Depoları getirir.
	 *
	 * @return array Depo listesi.
	 */
	public function get_warehouses() {
		return $this->warehouses;
	}

	/**
	 * Kargo entegrasyonlarını getirir.
	 *
	 * @return array Kargo entegrasyonları.
	 */
	public function get_cargo_integrations() {
		return $this->cargo_integrations;
	}

	/**
	 * Ödeme bilgilerini getirir.
	 *
	 * @return array Ödeme bilgileri.
	 */
	protected function get_payment() {
		$payment = [
			'total'          => $this->order->get_total(),
			'currency'       => $this->order->get_currency(),
			'invoice_number' => (string) $this->order->get_id(),
			'waybill_number' => (string) $this->order->get_id(),
		];

		if ( get_class( $this ) === 'GCARGO_Shipment_Map_WC_Order' ) {
			$payment['is_pay_at_door'] = $this->order->get_payment_method() === 'cod';
		}

		return $payment;
	}

	/**
	 * Müşteri bilgilerini getirir.
	 *
	 * @return array Müşteri bilgileri.
	 */
	protected function get_customer() {
		$shipping = [];
		$billing  = [
			'name'         => $this->order->get_billing_first_name(),
			'surname'      => $this->order->get_billing_last_name(),
			'phone'        => $this->order->get_billing_phone(),
			'email'        => $this->order->get_billing_email(),
			'city'         => $this->get_state( $this->order->get_billing_state(), $this->order->get_billing_country() ),
			'district'     => $this->order->get_billing_city(),
			'address'      => $this->order->get_billing_address_1() . ' ' . $this->order->get_billing_address_2(),
			'postcode'     => $this->order->get_billing_postcode(),
			'country'      => $this->get_country( $this->order->get_billing_country() ),
			'country_code' => $this->order->get_billing_country(),
			'tax_number'   => '',
			'tax_office'   => '',
		];

		$state        = $this->order->get_billing_state();
		$country_code = $this->order->get_billing_country();

		$states = WC()->countries->get_states( $country_code );
		if ( ! empty( $states ) && isset( $states[ $state ] ) ) {
			$billing['city']      = $this->get_state( $state, $country_code );
			$billing['city_code'] = $state;
		} else {
			$billing['city'] = $state;
		}

		if ( $this->order->has_shipping_address() ) {
			$shipping_state   = $this->order->get_shipping_state();
			$shipping_country = $this->order->get_shipping_country();

			$shipping = [
				'name'         => $this->order->get_shipping_first_name(),
				'surname'      => $this->order->get_shipping_last_name(),
				'city'         => $this->get_state( $this->order->get_shipping_state(), $this->order->get_shipping_country() ),
				'district'     => $this->order->get_shipping_city(),
				'phone'        => $this->order->get_shipping_phone(),
				'address'      => $this->order->get_shipping_address_1() . ' ' . $this->order->get_shipping_address_2(),
				'postcode'     => $this->order->get_shipping_postcode(),
				'country'      => $this->get_country( $this->order->get_shipping_country() ),
				'country_code' => $this->order->get_shipping_country(),
			];

			$shipping_states = WC()->countries->get_states( $shipping_country );
			if ( ! empty( $shipping_states ) && isset( $shipping_states[ $shipping_state ] ) ) {
				$shipping['city']      = $this->get_state( $shipping_state, $shipping_country );
				$shipping['city_code'] = $shipping_state;
			} else {
				$shipping['city'] = $shipping_state;
			}

			$shipping = array_filter(
				$shipping,
				function ( $value ) {
					return ! empty( $value );
				}
			);
		}

		return apply_filters( "{$this->prefix}_receiver_data", wp_parse_args( $shipping, $billing ) );
	}




	/**
	 * Ülke adını getirir.
	 *
	 * @param string $country Ülke kodu.
	 * @return string Ülke adı.
	 */
	protected function get_country( $country ) {
		return WC()->countries->get_countries()[ $country ];
	}

	/**
	 * Şehir bilgilerini getirir.
	 *
	 * @param string $state   Şehir kodu.
	 * @param string $country Ülke kodu.
	 * @return string Şehir adı.
	 */
	protected function get_state( $state, $country ) {
		return WC()->countries->get_states( $country )[ $state ];
	}

	/**
	 * Varsayılan değerleri getirir.
	 *
	 * @return array Varsayılan değerler.
	 */
	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,
			)
		);

		if ( get_class( $this ) === 'GCARGO_Returned_Map_WC_Order' ) {
			$default['return_at'] = gmdate( 'Y-m-d', strtotime( '+1 day' ) );
		}

		return $default;
	}

	/**
	 * Ürün bilgilerini getirir.
	 *
	 * @var WC_Order_Item_Product $item
	 */
	public function get_lines() {
		$lines = array();
		foreach ( $this->order->get_items() as $item ) {
			if ( ! ( $item instanceof WC_Order_Item_Product ) ) {
				continue;
			}

			$line       = $this->prepare_line_item( $item );
			$product_id = $item->get_variation_id() ? $item->get_variation_id() : $item->get_product_id();

			if ( $product_id ) {
				$product = wc_get_product( $product_id );

				$line = array_merge(
					$line,
					array(
						'platform_id' => $item->get_id(),
						'title'       => wp_strip_all_tags( $item->get_name() ),
						'sold_qty'    => (int) $item->get_quantity(),
						'quantity'    => (int) $item->get_quantity() - $line['action_qty'],
						'image'       => wp_get_attachment_image_url( $product->get_image_id(), 'single-post-thumbnail' ),
						'sku'         => $product->get_sku(),
						'weight'      => (float) $product->get_weight() * $item->get_quantity(),
						'base_weight' => (float) $product->get_weight(),
						'price'       => $product->get_price(),
					)
				);

				$this->total_weight += $line['weight'];
				// Add return-specific fields
				if ( get_class( $this ) === 'GCARGO_Returned_Map_WC_Order' ) {
					$line['reason']   = '';
					$line['selected'] = false;
				}
			}

			$lines[] = $line;
		}
		return $lines;
	}

	/**
	 * İşlem durumunu getirir.
	 *
	 * @return string İşlem durumu.
	 */
	abstract protected function get_status();

	/**
	 * Bildirim URL'sini getirir.
	 *
	 * @return string Bildirim URL'si.
	 */
	abstract protected function get_notification_url();

	/**
	 * Satır verilerini hazırlar.
	 *
	 * @param object $item WC sipariş kimliği.
	 */
	abstract protected function prepare_line_item( $item );

	/**
	 * İstek oluşturur
	 *
	 * @return array İstek verileri.
	 */
	abstract protected function create_request();
}
