<?php
/**
 * GCARGO_WooCommerce sınıfını barındıran dosya.
 *
 * @package GurmeHub
 */

use Automattic\WooCommerce\Utilities\FeaturesUtil;

/**
 * Bu sınıf eklenti aktif olur olmaz çalışmaya başlar ve
 * kurucu fonksiyonu içerisindeki WooCommerce kancalarına tutunur.
 */
class GCARGO_WooCommerce {


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

	/**
	 * Otomatik gönderi oluşturma ayarları
	 *
	 * @var GCARGO_Auto_Shipment_Settings $auto_shipment_settings
	 */
	protected $auto_shipment_settings;

	/**
	 * GCARGO_WooCommerce kurucu fonksiyonu
	 *
	 * @return void
	 */
	public function __construct() {
		add_action( 'before_woocommerce_init', array( $this, 'before_woocommerce_init' ) );
		add_filter( 'woocommerce_hidden_order_itemmeta', array( $this, 'hidden_order_itemmeta' ) );
		add_filter( 'woocommerce_account_orders_columns', array( $this, 'account_orders_columns' ) );
		add_action( 'woocommerce_my_account_my_orders_column_gcargo-shipments', array( $this, 'my_orders_column' ) );
		add_action( 'woocommerce_order_details_after_order_table', array( $this, 'after_order_table' ) );
		add_filter( 'wc_order_statuses', array( gcargo_wc_status_manager(), 'callback_order_statuses' ) );
		add_action( 'woocommerce_register_shop_order_post_statuses', array( gcargo_wc_status_manager(), 'callback_shop_order_post_statuses' ) );

		add_filter( 'woocommerce_email_classes', array( $this, 'add_email_classes' ) );
		add_filter( 'woocommerce_get_settings_pages', array( $this, 'settings_pages' ), 99 );
		add_filter( 'manage_woocommerce_page_wc-orders_columns', array( $this, 'add_cargo_company_column' ), 20 );
		add_filter( 'manage_shop_order_posts_columns', array( $this, 'add_cargo_company_column_old_version' ), 20 );
		add_action( 'manage_woocommerce_page_wc-orders_custom_column', array( $this, 'cargo_company_column_data' ), 10, 2 );
		add_action( 'manage_shop_order_posts_custom_column', array( $this, 'cargo_company_column_data' ), 10, 2 );

		$this->auto_shipment_settings = gcargo_auto_shipment_settings();

		if ( true === $this->auto_shipment_settings->get_setting_by_key( 'active' ) ) {
			$status = $this->auto_shipment_settings->get_setting_by_key( 'status' );
			add_action( "woocommerce_order_status_{$status}", array( $this, 'order_status_change' ) );
		}
	}



	/**
	 *  Tüm durumlar  için WooCommerce e-posta şablonlarını ekler
	 *
	 *  @param array $email_classes E-Posta sınıfları
	 *  @return array E-Posta sınıfıları
	 *  @SuppressWarnings(UnusedLocalVariable)
	 */
	public function add_email_classes( $email_classes ) {
		require_once GCARGO_PLUGIN_DIR_PATH . 'includes/class-gcargo-email.php';

		foreach ( gcargo_get_shipment_statuses() as $key => $status ) {

			$email_classes[ $key ] = new GCARGO_Email( $key );
		}

		return $email_classes;
	}

	/**
	 * before_woocommerce_init
	 *
	 * @return void
	 *
	 * @SuppressWarnings(PHPMD.StaticAccess)
	 */
	public function before_woocommerce_init() {

		if ( class_exists( FeaturesUtil::class ) ) {
			FeaturesUtil::declare_compatibility( 'custom_order_tables', GCARGO_PLUGIN_BASEFILE, true );
		}
	}

	/**
	 * Sipariş sonrası ekranında müşteriden, WooCommerce sipariş detay sayfasında
	 * yöneticiden sipariş ürünlerinin meta bilgilerini gizler.
	 *
	 * @param  array $hidden_metas Gizli metalar.
	 * @return array $hidden_metas
	 */
	public function hidden_order_itemmeta( $hidden_metas ) {
		$hidden_metas = array_merge(
			$hidden_metas,
			array( '_gcargo_shipped_qty', '_gcargo_returned_qty' )
		);
		return $hidden_metas;
	}

	/**
	 * Müşteri sipariş tablosu kolon ekleme.
	 *
	 * @param  array $columns Kolonlar.
	 * @return array $columns
	 */
	public function account_orders_columns( $columns ) {
		$actions = $columns['order-actions'];
		unset( $columns['order-actions'] );
		$columns['gcargo-shipments'] = __( 'Cargo Tracking', 'kargo-entegrator' );
		$columns['order-actions']    = $actions;
		return $columns;
	}

	/**
	 * Kolon içeriği.
	 *
	 * @param  WC_Order $order Sipariş.
	 */
	public function my_orders_column( $order ) {
		$order     = wc_get_order( $order->get_id() );
		$order_id  = $order->get_id();
		$shipments = gcargo_shipments()->get_shipments_by_order_id( $order_id );
		$returneds = gcargo_returneds()->get_returneds_by_order_id( $order_id );
		$mapper    = gcargo_shipment_map_wc_order( $order_id );

		foreach ( $returneds as $returned ) {
			try {
				$returned->pdf = gcargo_api_requests()->print_returneds( array( $returned->id ) );
			} catch ( Exception $e ) {
				$returned->pdf = null;
			}
		}

		gcargo_vue()->create_app_div( array( 'id' => 'gcargo-order-detail-' . $order_id ) );

		add_filter(
			'gcargo_customer_order_detail_localize_data',
			function ( $localize ) use ( $order_id, $shipments, $returneds, $mapper ) {
				$localize['shipments'][ $order_id ]   = $shipments;
				$localize['returneds'][ $order_id ]   = $returneds;
				$localize['order_lines'][ $order_id ] = $mapper->get_lines();
				return $localize;
			}
		);

		add_action( 'wp_footer', array( $this, 'enqueue_customer_order_detail_assets' ) );
	}

	/**
	 * `my_orders_column` içerisinde biriktirilen sipariş verileriyle
	 * birlikte, sayfa başına yalnızca bir kez customer-order-detail
	 * Vue script/stilini dahil eder.
	 *
	 * @return void
	 */
	public function enqueue_customer_order_detail_assets() {
		gcargo_vue()
			->set_localize(
				array_merge(
					gcargo_data_handler()->default_localize_data(),
					apply_filters(
						'gcargo_customer_order_detail_localize_data',
						array(
							'shipments'   => array(),
							'returneds'   => array(),
							'order_lines' => array(),
						)
					)
				)
			)
			->set_vue_page( 'customer-order-detail' )
			->require_script()
			->require_style();
	}

	/**
	 * Kolon içeriği.
	 *
	 * @param  WC_Order $order Sipariş.
	 */
	public function after_order_table( $order ) {
		?>
		<div>
			<h4><?php esc_html_e( 'Shipment Tracking', 'kargo-entegrator' ); ?></h4>
			<?php
			$this->my_orders_column( $order );
			?>
		</div>
		<br>
		<hr>
		<?php
	}

	/**
	 * Ayar tablarına ekleme.
	 *
	 * @param array $settings Tablar.
	 */
	public function settings_pages( $settings ) {
		require_once GCARGO_PLUGIN_DIR_PATH . 'includes/class-gcargo-wc-settings-tab.php';
		$settings[] = new GCARGO_WC_Settings_Tab();
		return $settings;
	}

	/**
	 * Sipariş tablosuna kargo firması için yeni kolon oluşturur.
	 *
	 * @param array $columns Kolonlar.
	 */
	public function add_cargo_company_column( $columns ) {
		$cargo_columns = [];
		foreach ( $columns as $key => $column ) {
			$cargo_columns[ $key ] = $column;
			if ( 'order_status' === $key ) {
				$cargo_columns['cargo_company'] = "<gcargo-icon aria-label='Kargo Entegratör'></gcargo-icon> Kargo Entegratör";
			}
		}
		return $cargo_columns;
	}

	/**
	 * Sipariş tablosuna kargo firması için yeni kolon oluşturur.
	 *
	 * @param array $columns Kolonlar.
	 */
	public function add_cargo_company_column_old_version( $columns ) {
		$columns['cargo_company'] = "<gcargo-icon aria-label='Kargo Entegratör'></gcargo-icon> Kargo Entegratör";
		return $columns;
	}


	/**
	 * Sipariş tablosuna yeni eklenen kolon için veriler.
	 *
	 * @param array      $column kolon
	 * @param object|int $order sipariş objesi.
	 */
	public function cargo_company_column_data( $column, $order ) {

		$order_id = is_numeric( $order ) ? $order : $order->get_id();

		if ( 'cargo_company' === $column ) {
			gcargo_vue()->create_app_div( array( 'id' => 'gcargo-order-table-' . $order_id ) );

			add_filter(
				'gcargo_orders_table_localize_data',
				function ( $localize ) use ( $order_id ) {
					$order = wc_get_order( $order_id );
					if ( $order && ! in_array( $order->get_status(), gcargo_get_unwanted_order_statuses(), true ) ) {
						$shipments       = gcargo_shipments()->get_shipments_by_order_id( $order_id );
						$shipment_mapper = gcargo_shipment_map_wc_order( $order_id );

						$localize['shipments'][ $order_id ]               = $shipments;
						$localize['order_shipment_statuses'][ $order_id ] = $shipment_mapper->get_status();
					}
					return $localize;
				},
				10,
				1
			);
		}
	}


	/**
	 * Otomatik gönderi oluşturmak için zamanlanmış görev ataması.
	 *
	 * @param string $order_id Sipariş verisi.
	 */
	public function order_status_change( $order_id ) {
		wp_schedule_single_event( time() + $this->auto_shipment_settings->get_setting_by_key( 'generation_time' ), 'gcargo_auto_shipment', array( $order_id ) );
	}
}
