<?php
/**
 * Holds information about payment methods.
 *
 * @package northmill-online-shared
 */

declare( strict_types = 1 );

namespace Northmill_Online_Shared\Data;

use Northmill_Online_Shared\Abstract_Shared_Base;

defined( 'ABSPATH' ) || exit;

/**
 * Class Payment_Methods
 */
class Payment_Methods {
	/**
	 * Northmill Checkout payment methods.
	 */
	public const NMC_APPLE_PAY      = 'nm_shift4_apple_pay';
	public const NMC_BNPL           = 'northmill_bnpl';
	public const NMC_SHIFT4_CARD    = 'credorax';
	public const NMC_MF_INVOICE     = 'moreflo_invoice';
	public const NMC_NMI            = 'nmi_pay_gateway';
	public const NMC_RESURS_INVOICE = 'invoice_pays';
	public const NMC_SWISH          = 'swish_pay_gateway';

	/**
	 * WooCommerce core payment methods.
	 */
	public const WC_COD = 'cod';

	/**
	 * Core Gateway settings.
	 */
	public const GATEWAY_SETTING_ENABLED = 'enabled';
	public const GATEWAY_SETTING_TITLE   = 'title';
	public const GATEWAY_SETTING_DESC    = 'description';

	/**
	 * Get all payment method data.
	 * The array key is the method ID.
	 *
	 * Possible keys:
	 * - method_title:             The title of the payment method, as shown in WP admin.
	 * - method_description:       The description of the payment method, as shown in WP admin.
	 * - default_title:            The default title of the payment method, as shown in the checkout frontend.
	 * - icon:                     Path to an icon image for the payment method.
	 * - hub_online_solution_type: The online solution Type property for the payment method.
	 * - hub_iac_type:             The IAC PaymentType property for the payment method.
	 * - options:                  An array of option names for the payment method.
	 *                                  Each item can either be just a string, or a key-value pair.
	 *                                  If just a string, the key and value is considered the same.
	 *
	 * @return array
	 */
	public static function get_all_data(): array {
		return array(
			/**
			 * Northmill Checkout payment methods.
			 */
			self::NMC_APPLE_PAY      => array(
				'method_title'             => __( 'Northmill Checkout - Apple Pay', 'northmill-online-shared' ),
				'method_description'       => __( 'Use Apple Pay with Northmill.', 'northmill-online-shared' ),
				'default_title'            => __( 'Northmill Apple Pay', 'northmill-online-shared' ),
				'icon'                     => Abstract_Shared_Base::base_instance()->assets->get_shared_assets_url() . 'img/payment-methods/Apple_Pay_Mark_RGB_041619.svg',
				'hub_online_solution_type' => '', // TODO: Set correct type.
				'hub_iac_type'             => 'BankCardPayment',
				'options'                  => array(
					'mode',
					'merchant_id',
					'sub_merchant_id',
					'secret',
					'payment_networks',
					'billing_descriptor',
					'store_name',
					'log_enabled',
				),
			),
			self::NMC_BNPL           => array(
				'method_title'             => __( 'Northmill Checkout - Northmill Pay later', 'northmill-online-shared' ),
				'method_description'       => __( 'Initializes Northmill Pay later on checkout.', 'northmill-online-shared' ),
				'default_title'            => __( 'Northmill Pay later', 'northmill-online-shared' ),
				'hub_online_solution_type' => 'NBNPL',
				'hub_iac_type'             => 'NorthmillBNPL',
			),
			self::NMC_SHIFT4_CARD    => array(
				'method_title'             => __( 'Northmill Checkout - Finaro Pay', 'northmill-online-shared' ),
				'method_description'       => __( 'Accept card payments.', 'northmill-online-shared' ),
				'default_title'            => __( 'Card Payment', 'northmill-online-shared' ),
				'hub_online_solution_type' => '', // TODO: Set correct type.
				'hub_iac_type'             => 'BankCardPayment',
			),
			self::NMC_MF_INVOICE     => array(
				'method_title'             => __( 'Northmill Checkout - Flo Invoice', 'northmill-online-shared' ),
				'method_description'       => __( 'Use invoice payment.', 'northmill-online-shared' ),
				'hub_online_solution_type' => 'Invoice',
				'hub_iac_type'             => 'Invoice',
			),
			self::NMC_NMI            => array(
				'method_title'             => __( 'Northmill Checkout - NMI Pay', 'northmill-online-shared' ),
				'method_description'       => __( 'Use credit card payment with Northmill. Requires SSL in live mode.', 'northmill-online-shared' ),
				'hub_online_solution_type' => 'Nmi',
				'hub_iac_type'             => 'BankCardPayment',
				'options'                  => array(
					'sandbox',
					'live_terminal_id',
					'live_transaction_key',
					'live_hash_key',
					'log_enabled',
				),
			),
			self::NMC_RESURS_INVOICE => array(
				'method_title'             => __( 'Northmill Checkout - Resurs Bank', 'northmill-online-shared' ),
				'method_description'       => __( 'Use invoice, Swish and partial payment and validate the customers credibility with Resurs Bank. Requires SSL when in live mode.', 'northmill-online-shared' ),
				'hub_online_solution_type' => 'ResursBank',
				'hub_iac_type'             => 'ResursBank',
				'options'                  => array(
					'sandbox',
					'live_merchant_id',
					'live_password',
					'log_enabled',
				),
			),
			self::NMC_SWISH          => array(
				'method_title'             => __( 'Northmill Checkout - Swish', 'northmill-online-shared' ),
				'method_description'       => __( 'Use Swish payment as payment gateway. Requires SSL and generate certificate from swish.', 'northmill-online-shared' ),
				'default_title'            => __( 'Swish', 'northmill-online-shared' ),
				'hub_online_solution_type' => 'Swish',
				'hub_iac_type'             => 'Swish',
				'options'                  => array(
					'payee_number',
				),
			),
			/**
			 * WooCommerce core payment methods.
			 */
			self::WC_COD             => array(
				'method_title'             => __( 'Pay on delivery', 'northmill-online-shared' ),
				'hub_online_solution_type' => 'CashOnDelivery',
				'hub_iac_type'             => 'CashPayment',
			),
		);
	}

	/**
	 * Get data for a payment method.
	 *
	 * @param string $method_id The method ID.
	 *
	 * @return array
	 */
	public static function get_data( string $method_id ): array {
		$all_data = self::get_all_data();

		return $all_data[ $method_id ] ?? array();
	}

	/**
	 * Get a specific key from the data for a payment method.
	 *
	 * @param string $method_id     The method ID.
	 * @param string $key           The key to get.
	 * @param mixed  $default_value The default value to return if the key is not found, or value is null.
	 *
	 * @return mixed
	 */
	private static function get_data_key( string $method_id, string $key, mixed $default_value = '' ): mixed {
		$method_data = self::get_data( $method_id );

		return $method_data[ $key ] ?? $default_value;
	}

	/**
	 * Get the method title for a payment method.
	 *
	 * @param string $method_id The method ID.
	 *
	 * @return string
	 * @used Express Order
	 */
	public static function get_method_title( string $method_id ): string {
		return self::get_data_key( $method_id, 'method_title' );
	}

	/**
	 * Get the method description for a payment method.
	 *
	 * @param string $method_id The method ID.
	 *
	 * @return string
	 * @used Express Order
	 */
	public static function get_method_description( string $method_id ): string {
		return self::get_data_key( $method_id, 'method_description' );
	}

	/**
	 * Get the default title for a payment method.
	 *
	 * @param string $method_id The method ID.
	 *
	 * @return string
	 * @used Express Order
	 */
	public static function get_default_title( string $method_id ): string {
		return self::get_data_key( $method_id, 'default_title' );
	}

	/**
	 * Get the icon for a payment method.
	 *
	 * @param string $method_id The method ID.
	 *
	 * @return string
	 * @used Express Order
	 */
	public static function get_icon( string $method_id ): string {
		return self::get_data_key( $method_id, 'icon' );
	}

	/**
	 * Get a specific option key for a payment method.
	 *
	 * @param string $method_id   The method ID.
	 * @param string $option_name The option name, as defined above.
	 *
	 * @return string
	 * @used Express Order
	 */
	public static function get_option_key( string $method_id, string $option_name ): string {
		$method_data = self::get_data_key( $method_id, 'options', array() );

		if ( isset( $method_data[ $option_name ] ) ) {
			return $method_data[ $option_name ];
		} elseif ( in_array( $option_name, $method_data, true ) ) {
			return $option_name;
		} else {
			return '';
		}
	}

	/**
	 * Get the online solution type for a payment method.
	 *
	 * @param string $method_id The method ID.
	 *
	 * @return string|null
	 */
	public static function get_online_solution_type( string $method_id ): ?string {
		return self::get_data_key( $method_id, 'hub_online_solution_type', null );
	}

	/**
	 * Get the IAC type for a payment method.
	 *
	 * @param string $method_id The method ID.
	 *
	 * @return string|null
	 */
	public static function get_iac_type( string $method_id ): ?string {
		return self::get_data_key( $method_id, 'hub_iac_type', null );
	}

	/**
	 * Get the gateway ID for a payment method using the online solution type.
	 *
	 * @param string $type The online solution type.
	 *
	 * @return string|null
	 */
	public static function get_gateway_id_from_online_solution_type( string $type ): ?string {
		$all_data = self::get_all_data();

		foreach ( $all_data as $method_id => $method_data ) {
			if ( $method_data['hub_online_solution_type'] === $type ) {
				return $method_id;
			}
		}

		return null;
	}

	/**
	 * Get the payment method map for IAC.
	 *
	 * @return array[]
	 */
	public static function get_iac_payment_method_map(): array {
		$payment_method_map = array(
			'BankCardPayment' => array(
				'bacs',                 // Woocommerce Core – BACS.
			),
			'Klarna'          => array(
				'klarna_payments',
				'kco',
			),
			'Paypal'          => array(
				'ppcp-gateway',
			),
			'Stripe'          => array(
				'stripe',
				'stripe_alipay',
				'stripe_multibanco',
				'stripe_sepa',
				'stripe_giropay',
				'stripe_ideal',
				'stripe_bancontact',
				'stripe_eps',
				'stripe_p24',
				'stripe_boleto',
				'stripe_oxxo',
			),
			'SveaWebPay'      => array(
				'sveawebpay_card',
				'sveawebpay_direct_bank',
				'sveawebpay_invoice',
				'sveawebpay_part_pay',
			),
			'WooPayments'     => array(
				'woocommerce_payments',
			),
			'ExternalPayment' => array( // The "others"-option.
				'cheque',               // Woocommerce Core – Cheque.
			),
		);

		foreach ( self::get_all_data() as $method_id => $method_data ) {
			if ( empty( $method_data['hub_iac_type'] ) ) {
				continue;
			}

			if ( ! isset( $payment_method_map[ $method_data['hub_iac_type'] ] ) ) {
				$payment_method_map[ $method_data['hub_iac_type'] ] = array();
			}

			$payment_method_map[ $method_data['hub_iac_type'] ][] = $method_id;
		}

		return $payment_method_map;
	}
}
