<?php
/**
 * This file belongs to the YIT Framework.
 *
 * This source file is subject to the GNU GENERAL PUBLIC LICENSE (GPL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.gnu.org/licenses/gpl-3.0.txt
 *
 * @package YITH\PreOrder\Includes
 * @author YITH <plugins@yithemes.com>
 */

if ( ! defined( 'ABSPATH' ) || ! defined( 'YITH_WCPO_VERSION' ) ) {
	exit; // Exit if accessed directly.
}
/**
 * Update the pre-orders from previous versions and add new metas.
 */

// This is to ensure that this function is executed only once on installations that were using the plugin previously:
// If there is the option 'yith_wcpo_enable_pre_order' (regardless of the value 'yes' or 'no'), it means that the
// plugin was previously installed before the update.
if ( get_option( 'yith_wcpo_enable_pre_order' ) && 'no' === get_option( 'ywpo_update_2_0_done', 'no' ) ) {
	add_action( 'admin_init', 'ywpo_update_2_0' );
}

if ( ! function_exists( 'ywpo_update_2_0' ) ) {
	/**
	 * Loop over all old pre-orders and add the new order and order item meta when necessary.
	 */
	function ywpo_update_2_0() {
		$args = apply_filters(
			'ywpo_update_2_0_args',
			array(
				'post_type'   => 'shop_order',
				'post_status' => 'any',
				'numberposts' => -1,
				'fields'      => 'ids',
				'meta_query'  => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
					'relation' => 'AND',
					array(
						'key'     => '_order_has_preorder',
						'value'   => 'yes',
						'compare' => '=',
					),
					array(
						'key'     => '_ywpo_status',
						'compare' => 'NOT EXISTS',
					),
				),
			)
		);

		// Get all old pre-orders (before Pre-Order 2.0).
		// They are those that have the meta '_order_has_preorder' meta but don't have the new meta '_ywpo_status'.
		$orders = get_posts( $args );
		if ( $orders ) {
			foreach ( $orders as $order_id ) {
				$order = wc_get_order( $order_id );
				if ( ! $order instanceof WC_Order ) {
					continue;
				}
				$pre_order_items = array();
				$update_order    = false;
				try {
					foreach ( $order->get_items() as $order_item ) {
						$item_id   = $order_item->get_id();
						$timestamp = $order_item->get_meta( '_ywpo_item_for_sale_date' );
						if ( $timestamp > time() ) {
							wc_add_order_item_meta( $item_id, '_ywpo_item_preorder', 'yes' );
							wc_add_order_item_meta( $item_id, '_ywpo_item_status', 'waiting' );
							$pre_order_items[ $item_id ] = 'waiting';
							$update_order                = true;
						}
					}
					if ( $update_order ) {
						$order->update_meta_data( '_ywpo_status', 'waiting' );
						$order->update_meta_data( '_ywpo_pre_order_items', $pre_order_items );
						$order->update_meta_data( '_ywpo_order_charge_type', 'upfront' );

						// Update '_ywpo_pending_payment' according to the order's payment status.
						$pending_payment = $order->get_meta( '_date_paid' ) ? 'no' : 'yes';
						$order->update_meta_data( '_ywpo_pending_payment', $pending_payment );
						$order->save();
					}
				} catch ( Exception $e ) {
					return new WP_Error( $e->getCode(), $e->getMessage() );
				}
			}
		}

		$args = apply_filters(
			'ywpo_update_2_0_product_args',
			array(
				'type'   => 'variable',
				'return' => 'ids',
				'limit'  => -1,
			)
		);

		// Get all variable products to check if they have at least one pre-order variation and
		// set the '_ywpo_has_variations' post meta.
		// This post meta is for identifying variable products that have any pre-order variation so these products
		// can be displayed in the 'Pre-order products' list table. See YITH_Pre_Order_Products_List.
		$products = wc_get_products( $args );
		if ( $products ) {
			foreach ( $products as $product_id ) {
				$product = wc_get_product( $product_id );
				if ( ! $product->is_type( 'variable' ) ) {
					continue;
				}

				$children = $product->get_children();
				if ( empty( $children ) ) {
					continue;
				}

				foreach ( $children as $variation_id ) {
					if ( 'yes' === get_post_meta( $variation_id, '_ywpo_preorder', true ) ) {
						update_post_meta( $product_id, '_ywpo_has_variations', 'yes' );
						break;
					}
				}
			}
		}

		update_option( 'ywpo_update_2_0_done', 'yes' );

		return true;
	}
}
