<?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\Gateways
 * @author YITH <plugins@yithemes.com>
 */

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

/**
 * Pay Later Gateway.
 *
 * Offline gateway for placing pre-orders that will be charged upon release.
 */
class YITH_Pre_Order_Pay_Later extends WC_Payment_Gateway {

	/**
	 * Array of locales
	 *
	 * @var array
	 */
	public $locale;

	/**
	 * Constructor for the gateway.
	 */
	public function __construct() {

		$this->id                 = 'ywpo_pay_later';
		$this->icon               = apply_filters( 'ywpo_pay_later_icon', '' );
		$this->has_fields         = false;
		$this->method_title       = __( 'YITH Pre-Order Pay Later', 'yith-pre-order-for-woocommerce' );
		$this->method_description = __( 'Allow your customers to pay for pre-ordered products later on.', 'yith-pre-order-for-woocommerce' );

		// Load the settings.
		$this->init_form_fields();
		$this->init_settings();

		// Define user set variables.
		$this->enabled     = $this->settings['enabled'];
		$this->title       = $this->settings['title'];
		$this->description = $this->settings['description'];
		$this->supports    = array( 'products', 'yith_pre_orders' );

		// Actions.
		if ( is_admin() ) {
			add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, array( $this, 'process_admin_options' ) );
		}
	}

	/**
	 * Init settings for the gateway.
	 */
	public function init_settings() {
		$settings = array();

		$settings['enabled']      = get_option( 'ywpo_pay_later_enabled', 'no' );
		$settings['title']        = get_option( 'ywpo_pay_later_title', __( 'Pay Later', 'yith-pre-order-for-woocommerce' ) );
		$settings['description']  = get_option( 'ywpo_pay_later_description', __( 'Complete your order and we will ask you to pay when the product becomes available.', 'yith-pre-order-for-woocommerce' ) );
		$settings['order_status'] = get_option( 'ywpo_pay_later_order_status', YITH_Pre_Order_Orders_Manager::$pre_ordered_status );

		$this->settings = $settings;

		// If there are no settings defined, use defaults.
		if ( ! is_array( $this->settings ) ) {
			$form_fields    = $this->get_form_fields();
			$this->settings = array_merge( array_fill_keys( array_keys( $form_fields ), '' ), wp_list_pluck( $form_fields, 'default' ) );
		}
	}

	/**
	 * Processes and saves options.
	 * If there is an error thrown, will continue to save and validate fields, but will leave the erroring field out.
	 *
	 * @return bool was anything saved?
	 */
	public function process_admin_options() {
		$this->init_settings();

		$post_data = $this->get_post_data();

		foreach ( $this->get_form_fields() as $key => $field ) {
			if ( 'title' !== $this->get_field_type( $field ) ) {
				try {
					if ( 'enabled' === $key || 'title' === $key || 'description' === $key || 'order_status' === $key ) {
						update_option( 'ywpo_pay_later_' . $key, $this->get_field_value( $key, $field, $post_data ) );
					}
					$this->settings[ $key ] = $this->get_field_value( $key, $field, $post_data );
				} catch ( Exception $e ) {
					$this->add_error( $e->getMessage() );
				}
			}
		}

		return update_option( $this->get_option_key(), apply_filters( 'woocommerce_settings_api_sanitized_fields_' . $this->id, $this->settings ), 'yes' );
	}

	/**
	 * Initialise Gateway Settings Form Fields.
	 */
	public function init_form_fields() {

		$this->form_fields = array(
			'enabled'      => array(
				'title'   => __( 'Enable/Disable', 'yith-pre-order-for-woocommerce' ),
				'type'    => 'checkbox',
				'label'   => __( 'Enable YITH Pre-Order Pay Later gateway', 'yith-pre-order-for-woocommerce' ),
				'default' => 'no',
			),
			'title'        => array(
				'title'       => __( 'Label', 'yith-pre-order-for-woocommerce' ),
				'type'        => 'text',
				'description' => __( 'This controls the title that the user will see during checkout.', 'yith-pre-order-for-woocommerce' ),
				'default'     => __( 'Pay Later', 'yith-pre-order-for-woocommerce' ),
				'desc_tip'    => true,
			),
			'description'  => array(
				'title'       => __( 'Description', 'yith-pre-order-for-woocommerce' ),
				'type'        => 'textarea',
				'description' => __( 'Payment method description that the customer will see on your checkout.', 'yith-pre-order-for-woocommerce' ),
				'default'     => __( 'Complete your order and we will ask you to pay when the product becomes available.', 'yith-pre-order-for-woocommerce' ),
				'desc_tip'    => true,
			),
			'order_status' => array(
				'title'       => __( 'Order status for pre-orders placed with the Pay Later gateway', 'yith-pre-order-for-woocommerce' ),
				'description' => __( 'Choose the order status that will be assigned after placing a pre-order with the Pay Later gateway. Changing this option will not affect previous orders.', 'yith-pre-order-for-woocommerce' ),
				'type'        => 'select',
				'class'       => 'wc-enhanced-select',
				'options'     => wc_get_order_statuses(),
				'default'     => YITH_Pre_Order_Orders_Manager::$pre_ordered_status,
			),
		);

	}

	/**
	 * Disables the gateway under any of these conditions:
	 * 1) If the cart does not contain a pre-order
	 * 2) If the pre-order amount is charged upfront
	 * 3) On the pay page
	 *
	 * @since 1.0
	 * @return bool
	 */
	public function is_available() {
		if ( apply_filters( 'ywpo_pay_later_not_available', ! ywpo_cart_contains_pre_order_product() || is_checkout_pay_page() || ! ywpo_is_pay_later_cart(), $this ) ) {
			return false;
		}

		return true;
	}

	/**
	 * Process the payment and return the result.
	 *
	 * @param int $order_id Order ID.
	 * @return array
	 */
	public function process_payment( $order_id ) {

		$order = wc_get_order( $order_id );

		do_action( 'ywpo_pay_later_before_update_status', $order );

		$order->update_meta_data( '_ywpo_pay_later', 'yes' );
		$order->update_meta_data( '_ywpo_pending_payment', 'yes' );
		$order->update_status( apply_filters( 'ywpo_pay_later_process_payment_order_status', get_option( 'ywpo_pay_later_order_status', 'wc-on-hold' ), $order ) );

		// In case the order status updated is considered as a "payment completed order status", delete the date_paid meta.
		YITH_Pre_Order_Orders_Manager::delete_date_paid_meta( $order );

		do_action( 'ywpo_pay_later_after_update_status', $order );

		if ( apply_filters( 'ywpo_pay_later_reduce_stock_levels', true, $order ) ) {
			wc_maybe_reduce_stock_levels( $order_id );
		}

		// Remove cart.
		WC()->cart->empty_cart();

		// Return thankyou redirect.
		return array(
			'result'   => 'success',
			'redirect' => $this->get_return_url( $order ),
		);
	}
}
