<?php

use Automattic\WooCommerce\Enums\OrderStatus;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * The Multibanco Payment Method class extending UPE base class
 */
class WC_Stripe_UPE_Payment_Method_Multibanco extends WC_Stripe_UPE_Payment_Method {

	public const STRIPE_ID = WC_Stripe_Payment_Methods::MULTIBANCO;

	/**
	 * Stripe account countries that may enable Multibanco.
	 *
	 * @var string[]
	 */
	protected const SUPPORTED_ACCOUNT_COUNTRIES = [
		WC_Stripe_Country_Code::AUSTRIA,
		WC_Stripe_Country_Code::BELGIUM,
		WC_Stripe_Country_Code::BULGARIA,
		WC_Stripe_Country_Code::SWITZERLAND,
		WC_Stripe_Country_Code::CYPRUS,
		WC_Stripe_Country_Code::CZECH_REPUBLIC,
		WC_Stripe_Country_Code::GERMANY,
		WC_Stripe_Country_Code::DENMARK,
		WC_Stripe_Country_Code::ESTONIA,
		WC_Stripe_Country_Code::SPAIN,
		WC_Stripe_Country_Code::FINLAND,
		WC_Stripe_Country_Code::FRANCE,
		WC_Stripe_Country_Code::UNITED_KINGDOM,
		WC_Stripe_Country_Code::GIBRALTAR,
		WC_Stripe_Country_Code::GREECE,
		WC_Stripe_Country_Code::CROATIA,
		WC_Stripe_Country_Code::HUNGARY,
		WC_Stripe_Country_Code::IRELAND,
		WC_Stripe_Country_Code::ITALY,
		WC_Stripe_Country_Code::LIECHTENSTEIN,
		WC_Stripe_Country_Code::LITHUANIA,
		WC_Stripe_Country_Code::LUXEMBOURG,
		WC_Stripe_Country_Code::LATVIA,
		WC_Stripe_Country_Code::MALTA,
		WC_Stripe_Country_Code::NETHERLANDS,
		WC_Stripe_Country_Code::NORWAY,
		WC_Stripe_Country_Code::POLAND,
		WC_Stripe_Country_Code::PORTUGAL,
		WC_Stripe_Country_Code::ROMANIA,
		WC_Stripe_Country_Code::SWEDEN,
		WC_Stripe_Country_Code::SLOVENIA,
		WC_Stripe_Country_Code::SLOVAKIA,
		WC_Stripe_Country_Code::UNITED_STATES,
	];

	/**
	 * Shopper billing countries permitted to use Multibanco.
	 *
	 * @var string[]
	 */
	protected const SUPPORTED_BILLING_COUNTRIES = [ WC_Stripe_Country_Code::PORTUGAL ];

	/**
	 * Constructor for Multibanco payment method
	 */
	public function __construct() {
		parent::__construct();
		$this->stripe_id            = self::STRIPE_ID;
		$this->title                = __( 'Multibanco', 'woocommerce-gateway-stripe' );
		$this->is_reusable          = false;
		$this->supported_currencies = [ WC_Stripe_Currency_Code::EURO ];
		$this->label                = __( 'Multibanco', 'woocommerce-gateway-stripe' );
		$this->description          = __(
			'Multibanco is an interbank network that links the ATMs of all major banks in Portugal, allowing customers to pay through either their ATM or online banking environment.',
			'woocommerce-gateway-stripe'
		);

		add_filter( 'wc_stripe_allowed_payment_processing_statuses', [ $this, 'add_allowed_payment_processing_statuses' ], 10, 2 );

		add_action( 'wc_gateway_stripe_process_payment_intent_requires_action', [ $this, 'save_instructions' ], 10, 2 );
		add_action( 'woocommerce_thankyou_stripe_multibanco', [ $this, 'thankyou_page' ] );
		add_action( 'woocommerce_email_before_order_table', [ $this, 'email_instructions' ], 10, 3 );
	}

	/**
	 * Output for the order received page.
	 *
	 * @param int $order_id The order ID.
	 * @return void
	 */
	public function thankyou_page( $order_id ) {
		$order = wc_get_order( $order_id );
		if ( ! $order ) {
			return;
		}

		$this->get_instructions( $order );
	}

	/**
	 * Add content to the WC emails.
	 *
	 * @param WC_Order $order
	 * @param bool     $sent_to_admin
	 * @param bool     $plain_text
	 * @return void
	 */
	public function email_instructions( $order, $sent_to_admin, $plain_text = false ) {
		if ( ! $order || ! is_a( $order, 'WC_Order' ) ) {
			return;
		}
		$payment_method = $order->get_payment_method();
		if ( ! $sent_to_admin && 'stripe_multibanco' === $payment_method && $order->has_status( OrderStatus::ON_HOLD ) ) {
			$this->get_instructions( $order, $plain_text );
		}
	}

	/**
	 * Gets Multibanco payment instructions for the customer.
	 *
	 * @param WC_Order $order      The order object.
	 * @param bool     $plain_text Whether to output as plain text.
	 * @return void
	 */
	public function get_instructions( $order, $plain_text = false ) {
		$data = WC_Stripe_Order_Helper::get_instance()->get_stripe_multibanco_data( $order );
		if ( ! $data ) {
			return;
		}

		if ( $plain_text ) {
			esc_html_e( 'MULTIBANCO ORDER INFORMATION', 'woocommerce-gateway-stripe' ) . "\n\n";
			echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";
			esc_html_e( 'Amount:', 'woocommerce-gateway-stripe' ) . "\n\n";
			echo wp_kses_post( $data['amount'] ) . "\n\n";
			echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";
			esc_html_e( 'Entity:', 'woocommerce-gateway-stripe' ) . "\n\n";
			echo esc_html( $data['entity'] ) . "\n\n";
			echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n\n";
			esc_html_e( 'Reference:', 'woocommerce-gateway-stripe' ) . "\n\n";
			echo esc_html( $data['reference'] ) . "\n\n";
		} else {
			?>
			<h3><?php esc_html_e( 'MULTIBANCO ORDER INFORMATION', 'woocommerce-gateway-stripe' ); ?></h3>
			<ul class="woocommerce-order-overview woocommerce-thankyou-order-details order_details">
				<li class="woocommerce-order-overview__order order">
					<?php esc_html_e( 'Amount:', 'woocommerce-gateway-stripe' ); ?>
					<strong><?php echo wp_kses_post( $data['amount'] ); ?></strong>
				</li>
				<li class="woocommerce-order-overview__order order">
					<?php esc_html_e( 'Entity:', 'woocommerce-gateway-stripe' ); ?>
					<strong><?php echo esc_html( $data['entity'] ); ?></strong>
				</li>
				<li class="woocommerce-order-overview__order order">
					<?php esc_html_e( 'Reference:', 'woocommerce-gateway-stripe' ); ?>
					<strong><?php echo esc_html( $data['reference'] ); ?></strong>
				</li>
			</ul>
			<?php
		}
	}


	/**
	 * Saves Multibanco information to the order meta for later use.
	 *
	 * @param WC_Order $order          The order object.
	 * @param object   $payment_intent The PaymentIntent object.
	 * @return void
	 */
	public function save_instructions( $order, $payment_intent ) {
		if ( empty( $payment_intent->next_action->multibanco_display_details ) ) {
			return;
		}

		$data = [
			'amount'    => $order->get_formatted_order_total(),
			'entity'    => $payment_intent->next_action->multibanco_display_details->entity,
			'reference' => $payment_intent->next_action->multibanco_display_details->reference,
		];

		WC_Stripe_Order_Helper::get_instance()->update_stripe_multibanco_data( $order, $data );
	}

	/**
	 * Adds on-hold as accepted status during webhook handling on orders paid with Multibanco
	 *
	 * @param array    $allowed_statuses The allowed statuses.
	 * @param WC_Order $order            The order object.
	 * @return array
	 */
	public function add_allowed_payment_processing_statuses( $allowed_statuses, $order ) {
		if ( WC_Stripe_Payment_Methods::MULTIBANCO === WC_Stripe_Order_Helper::get_instance()->get_stripe_upe_payment_type( $order ) && ! in_array( OrderStatus::ON_HOLD, $allowed_statuses, true ) ) {
			$allowed_statuses[] = OrderStatus::ON_HOLD;
		}

		return $allowed_statuses;
	}
}
