<?php
/**
 * CommerceBird Quotation Payment Gateway
 *
 * @package CommerceBird\Includes\Quotes
 */

defined( 'ABSPATH' ) || exit;

/**
 * CMBIRD_Gateway_Quotation Class
 */
class CMBIRD_Gateway_Quotation extends WC_Payment_Gateway {

	/**
	 * Gateway instructions shown on thank-you page and in emails.
	 *
	 * @var string
	 */
	protected string $instructions = '';

	/**
	 * Allowed shipping methods (restrict gateway availability).
	 *
	 * @var array
	 */
	protected array $allowed_shipping_methods = array();

	/**
	 * Minimum cart total to enable gateway (0 = no limit).
	 *
	 * @var float
	 */
	protected float $enable_for_min_amount = 0;

	/**
	 * Maximum cart total to enable gateway (0 = no limit).
	 *
	 * @var float
	 */
	protected float $enable_for_max_amount = 0;

	/**
	 * Constructor
	 */
	public function __construct() {
		$this->id                 = 'cmbird_quotation_gateway';
		$this->icon               = apply_filters( 'cmbird_quotation_gateway_icon', '' );
		$this->has_fields         = false;
		$this->method_title       = __( 'Quotation request', 'commercebird' );
		$this->method_description = __( 'Allows customers to ask for quotations.', 'commercebird' );

		$this->init_form_fields();
		$this->init_settings();

		$this->title                    = $this->get_option( 'title' );
		$this->description              = $this->get_option( 'description' );
		$this->instructions             = $this->get_option( 'instructions', $this->description );
		$this->allowed_shipping_methods = $this->get_option( 'allowed_shipping_methods', array() );
		$this->enable_for_min_amount    = (float) $this->get_option( 'enable_for_min_amount', 0 );
		$this->enable_for_max_amount    = (float) $this->get_option( 'enable_for_max_amount', 0 );

		add_action( 'woocommerce_update_options_payment_gateways_' . $this->id, function () { $this->process_admin_options(); } );
		add_action( 'woocommerce_thankyou_' . $this->id, array( $this, 'thankyou_page' ) );
		add_action( 'woocommerce_email_before_order_table', array( $this, 'email_instructions' ), 10, 3 );
	}

	/**
	 * Initialize gateway settings form fields
	 */
	public function init_form_fields(): void {
		$this->form_fields = array(
			'enabled'                  => array(
				'title'   => __( 'Enable/Disable', 'commercebird' ),
				'type'    => 'checkbox',
				'label'   => __( 'Enable quotation requests', 'commercebird' ),
				'default' => 'no',
			),
			'title'                    => array(
				'title'       => __( 'Title', 'commercebird' ),
				'type'        => 'text',
				'description' => __( 'This controls the title for the payment method the customer sees during checkout.', 'commercebird' ),
				'default'     => __( 'Quotation request', 'commercebird' ),
				'desc_tip'    => true,
			),
			'description'              => array(
				'title'       => __( 'Description', 'commercebird' ),
				'type'        => 'textarea',
				'description' => __( 'Payment method description that the customer will see on your checkout.', 'commercebird' ),
				'default'     => __( 'We will make you our best offer.', 'commercebird' ),
				'desc_tip'    => true,
			),
			'instructions'             => array(
				'title'       => __( 'Instructions', 'commercebird' ),
				'type'        => 'textarea',
				'description' => __( 'Instructions that will be added to the thank you page and emails.', 'commercebird' ),
				'default'     => __( 'Thanks for your request, you will receive our best offer for the chosen products.', 'commercebird' ),
				'desc_tip'    => true,
			),
			'allowed_shipping_methods' => array(
				'title'             => __( 'Enable for shipping methods', 'commercebird' ),
				'type'              => 'multiselect',
				'class'             => 'wc-enhanced-select',
				'description'       => __( 'Select shipping methods that allow this payment method. Leave blank to enable for all methods.', 'commercebird' ),
				'default'           => '',
				'desc_tip'          => true,
				'options'           => $this->get_available_shipping_methods(),
				'custom_attributes' => array(
					'data-placeholder' => __( 'Select shipping methods', 'commercebird' ),
				),
			),
			'enable_for_min_amount'    => array(
				'title'       => __( 'Enable for min amount', 'commercebird' ),
				'type'        => 'number',
				'description' => __( 'Set a minimum cart amount to make this payment method available.', 'commercebird' ),
				'default'     => 0,
				'desc_tip'    => true,
			),
			'enable_for_max_amount'    => array(
				'title'       => __( 'Enable for max amount', 'commercebird' ),
				'type'        => 'number',
				'description' => __( 'Set a maximum cart amount to make this payment method available.', 'commercebird' ),
				'default'     => 0,
				'desc_tip'    => true,
			),
		);
	}

	/**
	 * Output instructions on the order received page
	 */
	public function thankyou_page(): void {
		if ( $this->instructions ) {
			echo wp_kses_post( wpautop( wptexturize( $this->instructions ) ) );
		}
	}

	/**
	 * Add instructions to WC emails for on-quote orders
	 *
	 * @param WC_Order $order         Order object.
	 * @param bool     $sent_to_admin Whether the email is sent to admin.
	 * @param bool     $plain_text    Whether the email is plain text.
	 */
	public function email_instructions( WC_Order $order, bool $sent_to_admin, bool $plain_text = false ): void {
		if ( $this->instructions && ! $sent_to_admin && $this->id === $order->get_payment_method() && $order->has_status( 'on-quote' ) ) {
			echo wp_kses_post( wpautop( wptexturize( $this->instructions ) ) ) . PHP_EOL;
		}
	}

	/**
	 * Process the payment: set order to on-quote and empty cart
	 *
	 * @param int $order_id Order ID.
	 * @return array
	 */
	public function process_payment( $order_id ): array {
		$order = wc_get_order( $order_id );

		if ( ! $order ) {
			return array(
				'result'   => 'failure',
				'redirect' => '',
			);
		}

		$order->update_status( 'on-quote' );
		WC()->cart->empty_cart();

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

	/**
	 * Check whether the gateway is available based on shipping method and min/max cart total
	 *
	 * @return bool
	 */
	public function is_available(): bool {
		$amount = 0;
		$order  = null;

		if ( WC()->cart ) {
			$amount = (float) WC()->cart->get_total( 'edit' );
		} elseif ( is_page( wc_get_page_id( 'checkout' ) ) && 0 < get_query_var( 'order-pay' ) ) {
			$order_id = absint( get_query_var( 'order-pay' ) );
			$order    = wc_get_order( $order_id );
			$amount   = $order ? $order->get_total() : 0;
		}

		if ( $amount > 0 ) {
			if ( $this->enable_for_min_amount && $this->enable_for_min_amount > $amount ) {
				return false;
			}
			if ( $this->enable_for_max_amount && $this->enable_for_max_amount < $amount ) {
				return false;
			}
		}

		if ( ! empty( $this->allowed_shipping_methods ) ) {
			$needs_shipping           = false;
			$chosen_shipping_methods  = array();

			if ( WC()->cart && WC()->cart->needs_shipping() ) {
				$needs_shipping = true;
				if ( $session_methods = WC()->session->get( 'chosen_shipping_methods' ) ) {
					$chosen_shipping_methods = array_unique( array_map( 'wc_get_string_before_colon', $session_methods ) );
				}
			} elseif ( $order ) {
				foreach ( $order->get_items( 'line_item' ) as $item ) {
					$product = $item->get_product();
					if ( $product && $product->needs_shipping() ) {
						$needs_shipping = true;
						break;
					}
				}
				if ( $needs_shipping ) {
					$chosen_shipping_methods = array_unique( array_map( 'wc_get_string_before_colon', array_keys( $order->get_shipping_methods() ) ) );
				}
			}

			if ( $needs_shipping && 0 < count( array_diff( $chosen_shipping_methods, $this->allowed_shipping_methods ) ) ) {
				return false;
			}
		}

		return parent::is_available();
	}

	/**
	 * Get all available WooCommerce shipping methods
	 *
	 * @return array
	 */
	protected function get_available_shipping_methods(): array {
		$shipping_methods = array();
		foreach ( WC()->shipping()->load_shipping_methods() as $method ) {
			$shipping_methods[ $method->id ] = $method->get_method_title();
		}
		return $shipping_methods;
	}
}
