<?php

defined( 'ABSPATH' ) || exit();

/**
 *
 * @since   3.0.0
 * @package PaymentPlugins\Gateways
 * @author  User
 *
 */
class WC_Payment_Gateway_Stripe_CC extends WC_Payment_Gateway_Stripe {

	use WC_Stripe_Payment_Intent_Trait;

	protected $payment_method_type = 'card';

	public $installments;

	protected $supports_save_payment_method = true;

	public function __construct() {
		$this->id                 = 'stripe_cc';
		$this->tab_title          = __( 'Credit/Debit Cards', 'woo-stripe-payment' );
		$this->template_name      = 'credit-card.php';
		$this->token_type         = 'Stripe_CC';
		$this->method_title       = __( 'Credit Cards (Stripe) by Payment Plugins', 'woo-stripe-payment' );
		$this->method_description = __( 'Credit card gateway that integrates with your Stripe account.', 'woo-stripe-payment' );
		parent::__construct();
		$this->installments = \PaymentPlugins\Stripe\Installments\InstallmentController::instance();
	}

	public function get_icon() {
		$cards = $this->get_option( 'cards', array() );
		$icons = array();
		foreach ( $cards as $card ) {
			if ( $card && is_string( $card ) ) {
				$icons[ $card ] = stripe_wc()->assets_url( "img/cards/{$card}.svg" );
			}
		}

		return wc_stripe_get_template_html(
			'card-icons.php',
			apply_filters( 'wc_stripe_cc_icon_template_args', array(
				'cards'      => $cards,
				'icons'      => $icons,
				'assets_url' => stripe_wc()->assets_url()
			), $this )
		);
	}

	public function enqueue_checkout_scripts( $scripts ) {
		if ( $this->is_payment_element_active() ) {
			$scripts->assets_api->register_script( 'wc-stripe-credit-card', 'assets/build/credit-card-payment-element.js' );
			wp_enqueue_script( 'wc-stripe-credit-card' );
		} else {
			$scripts->enqueue_script(
				'credit-card',
				$scripts->assets_url( 'js/frontend/credit-card.js' ),
				array(
					$scripts->prefix . 'external',
					$scripts->prefix . 'wc-stripe',
				)
			);
		}
		$scripts->localize_script( 'credit-card', $this->get_localized_params() );
	}

	public function get_localized_params() {
		$data = parent::get_localized_params();

		return array_merge(
			$data,
			array(
				'cardOptions'        => $this->get_card_form_options(),
				'customFieldOptions' => $this->get_card_custom_field_options(),
				'cardFormType'       => $this->get_active_card_form_type(),
				'custom_form'        => $this->is_custom_form_active(),
				'custom_form_name'   => $this->get_option( 'custom_form' ),
				'html'               => array( 'card_brand' => sprintf( '<img id="wc-stripe-card" src="%s" />', $this->get_custom_form()['cardBrand'] ) ),
				'cards'              => array(
					'visa'       => stripe_wc()->assets_url( 'img/cards/visa.svg' ),
					'amex'       => stripe_wc()->assets_url( 'img/cards/amex.svg' ),
					'mastercard' => stripe_wc()->assets_url( 'img/cards/mastercard.svg' ),
					'discover'   => stripe_wc()->assets_url( 'img/cards/discover.svg' ),
					'diners'     => stripe_wc()->assets_url( 'img/cards/diners.svg' ),
					'jcb'        => stripe_wc()->assets_url( 'img/cards/jcb.svg' ),
					'unionpay'   => stripe_wc()->assets_url( 'img/cards/china_union_pay.svg' ),
					'unknown'    => $this->get_custom_form()['cardBrand'],
				),
				'postal_regex'       => $this->get_postal_code_regex(),
				'notice_location'    => $this->get_option( 'notice_location' ),
				'notice_selector'    => $this->get_notice_css_selector(),
				'installments'       => array(
					'loading' => __( 'Loading installments...', 'woo-stripe-payment' )
				)
			)
		);
	}

	/**
	 * @since 3.3.0
	 */
	public function get_card_form_options() {
		$options = array(
			'style'       => $this->get_form_style(),
			'disableLink' => ! \wc_string_to_bool( $this->get_option( 'link_enabled', 'yes' ) )
		);

		return apply_filters( 'wc_stripe_cc_form_options', $options, $this );
	}

	/**
	 * @return mixed|void
	 * @since 3.3.0
	 */
	public function get_card_custom_field_options() {
		$style   = $this->get_form_style();
		$options = array();
		foreach ( [ 'cardNumber', 'cardExpiry', 'cardCvc' ] as $key ) {
			$options[ $key ] = array( 'style' => $style );
		}

		return apply_filters( 'wc_stripe_get_card_custom_field_options', $options, $this );
	}

	public function get_form_style() {
		if ( $this->is_custom_form_active() ) {
			$style = $this->get_custom_form()['elementStyles'];
		} else {
			$style = array(
				'base'    => array(
					'color'         => '#32325d',
					'fontFamily'    => '"Helvetica Neue", Helvetica, sans-serif',
					'fontSmoothing' => 'antialiased',
					'fontSize'      => '18px',
					'::placeholder' => array( 'color' => '#aab7c4' ),
					':focus'        => array(),
				),
				'invalid' => array(
					'color'     => '#fa755a',
					'iconColor' => '#fa755a',
				),
			);
		}

		return apply_filters( 'wc_stripe_cc_element_style', $style, $this );
	}

	public function get_custom_form() {
		return wc_stripe_get_custom_forms()[ $this->get_option( 'custom_form' ) ];
	}

	public function get_element_options( $options = array() ) {
		if ( $this->is_custom_form_active() || ! $this->is_payment_element_active() ) {
			$options = array( 'locale' => wc_stripe_get_site_locale() );
			if ( $this->is_custom_form_active() ) {
				$options = array_merge(
					$this->get_custom_form()['elementOptions'],
					$options
				);
			}

			return apply_filters( 'wc_stripe_get_element_options', $options, $this );
		} elseif ( $this->is_payment_element_active() ) {
			$options                       = \PaymentPlugins\Stripe\Controllers\PaymentIntent::instance()->get_element_options();
			$options['paymentMethodTypes'] = array( 'card' );
			if ( \wc_string_to_bool( $this->get_option( 'link_enabled', 'yes' ) ) ) {
				$options['paymentMethodTypes'][] = 'link';
			}
			$options['appearance'] = array( 'theme' => $this->get_option( 'theme', 'stripe' ) );

			return parent::get_element_options( $options );
		}

		return parent::get_element_options();
	}


	/**
	 * Returns true if custom forms are enabled.
	 *
	 * @return bool
	 */
	public function is_custom_form_active() {
		return $this->get_option( 'form_type' ) === 'custom';
	}

	public function is_payment_element_active() {
		return $this->get_option( 'form_type' ) === 'payment';
	}

	public function get_custom_form_template() {
		$form = $this->get_option( 'custom_form' );

		return wc_stripe_get_custom_forms()[ $form ]['template'];
	}

	/**
	 * Returns true if the postal code field is enabled.
	 *
	 * @return bool
	 */
	public function postal_enabled() {
		if ( is_checkout() ) {
			return $this->is_active( 'postal_enabled' );
		}
		if ( is_add_payment_method_page() ) {
			return true;
		}
	}

	/**
	 * Returns true if the cvv field is enabled.
	 *
	 * @return bool
	 */
	public function cvv_enabled() {
		return $this->is_active( 'cvv_enabled' );
	}

	public function get_postal_code_regex() {
		return array(
			'AT' => '^([0-9]{4})$',
			'BR' => '^([0-9]{5})([-])?([0-9]{3})$',
			'CH' => '^([0-9]{4})$',
			'DE' => '^([0]{1}[1-9]{1}|[1-9]{1}[0-9]{1})[0-9]{3}$',
			'ES' => '^([0-9]{5})$',
			'FR' => '^([0-9]{5})$',
			'IT' => '^([0-9]{5})$/i',
			'IE' => '([AC-FHKNPRTV-Y]\d{2}|D6W)[0-9AC-FHKNPRTV-Y]{4}',
			'JP' => '^([0-9]{3})([-])([0-9]{4})$',
			'PT' => '^([0-9]{4})([-])([0-9]{3})$',
			'US' => '^([0-9]{5})(-[0-9]{4})?$',
			'CA' => '^([ABCEGHJKLMNPRSTVXY]\d[ABCEGHJKLMNPRSTVWXYZ])([\ ])?(\d[ABCEGHJKLMNPRSTVWXYZ]\d)$',
			'PL' => '^([0-9]{2})([-])([0-9]{3})',
			'CZ' => '^([0-9]{3})(\s?)([0-9]{2})$',
			'SK' => '^([0-9]{3})(\s?)([0-9]{2})$',
			'NL' => '^([1-9][0-9]{3})(\s?)(?!SA|SD|SS)[A-Z]{2}$',
		);
	}

	/**
	 *
	 * {@inheritDoc}
	 *
	 * @see WC_Payment_Gateway_Stripe::add_stripe_order_args()
	 */
	public function add_stripe_order_args( &$args, $order, $intent = null ) {
		// if the merchant is forcing 3D secure for all intents then add the required args.
		if ( $this->is_active( 'force_3d_secure' ) && is_checkout() && ! doing_action( 'woocommerce_scheduled_subscription_payment_' . $this->id ) ) {
			$args['payment_method_options']['card']['request_three_d_secure'] = 'any';
		}
		if ( stripe_wc()->advanced_settings && wc_string_to_bool( stripe_wc()->advanced_settings->get_option( 'extended_authorization', 'no' ) ) ) {
			if ( isset( $args['capture_method'] ) && $args['capture_method'] === WC_Stripe_Constants::MANUAL ) {
				$args['payment_method_options']['card']['request_extended_authorization'] = 'if_available';
			}
		}
	}

	public function has_enqueued_scripts( $scripts ) {
		return wp_script_is( $scripts->get_handle( 'credit-card' ) );
	}

	/**
	 * Returns true if the save payment method checkbox can be displayed.
	 *
	 * @return boolean
	 * @deprecated 3.3.42 - use ::show_save_payment_method_html
	 */
	public function show_save_source() {
		return $this->show_save_payment_method_html();
	}

	/**
	 * @return mixed|void
	 * @since 3.3.32
	 */
	private function get_notice_css_selector() {
		$location = $this->get_option( 'notice_location' );
		$selector = '';
		switch ( $location ) {
			case 'acf':
				$selector = 'div.payment_method_stripe_cc';
				break;
			case 'bcf':
				$selector = '.wc-stripe-card-notice';
				break;
			case 'toc':
				$selector = 'form.checkout';
				break;
			case 'custom':
				$selector = $this->get_option( 'notice_selector', 'div.payment_method_stripe_cc' );
				break;
		}

		return $selector;
	}

	public function is_installment_available() {
		$order_id = null;
		if ( is_checkout_pay_page() ) {
			global $wp;
			$order_id = absint( $wp->query_vars['order-pay'] );
		}

		return $this->installments->is_available( $order_id );
	}

	/**
	 * @return string Serves as a wrapper for the form_type option with some validations to ensure
	 *                a payment intent exists in the session.
	 */
	protected function get_active_card_form_type() {
		return $this->get_option( 'form_type' );
	}

	public function validate_form_type_field( $key, $value ) {
		if ( ! in_array( $value, array( 'payment', 'inline' ) ) && $this->is_active( 'link_enabled' ) ) {
			$value = $this->get_option( 'form_type' );
			WC_Admin_Settings::add_error( __( 'Only the Stripe payment form and inline form can be used while Link is enabled.', 'woo-stripe-payment' ) );
		}

		return $value;
	}

	public function is_deferred_intent_creation() {
		return $this->is_payment_element_active();
	}

	public function get_save_payment_method_label() {
		return __( 'Save Card', 'woo-stripe-payment' );
	}

	public function get_payment_element_options() {
		return array( 'terms' => array( 'card' => stripe_wc()->advanced_settings->get_terms_display_rule() ) );
	}

}