<?php

namespace SugarCalendarBookings\Payments\Gateways\Stripe;

use SugarCalendarBookings\Admin\Settings\PaymentsSettingsTab;
use SugarCalendarBookings\Options;
use SugarCalendarBookings\Payments\Gateways\AbstractPaymentGateway;
use SugarCalendarBookings\Payments\Gateways\BasePaymentGatewaySettings;
use SugarCalendarBookings\Payments\Gateways\PaymentGatewayRegistry;
use SugarCalendarBookings\Plugin;
use SugarCalendarBookings\Support\Admin\Notices;
use SugarCalendarBookings\Support\DataProcessing\InputProcessor;
use SugarCalendarBookings\Support\Helpers\Helpers;
use SugarCalendarBookings\Support\Helpers\UI;
use SugarCalendarBookings\Support\Helpers\WP;
use WP_Error;

/**
 * Stripe Settings.
 *
 * @since 1.0.0
 */
class StripePaymentGatewaySettings extends BasePaymentGatewaySettings {

	/**
	 * Payment gateway.
	 *
	 * @since 1.0.0
	 *
	 * @var StripePaymentGateway
	 */
	protected $gateway;

	/**
	 * Connect handler.
	 *
	 * @since 1.0.0
	 *
	 * @var StripeConnectHandler
	 */
	private $connect_handler;

	/**
	 * Constructor.
	 *
	 * @since 1.0.0
	 */
	public function __construct() {

		$this->gateway         = Plugin::get( PaymentGatewayRegistry::class )->get( 'stripe' );
		$this->connect_handler = new StripeConnectHandler();
	}

	/**
	 * Display content.
	 *
	 * @since 1.0.0
	 * @since 1.3.0 Add notice banner for pay-as-you-go pricing.
	 */
	public function display_content() {

		$description = wp_kses(
			sprintf(
			/* Translators: %1$s - Stripe documentation URL. */
				__( 'Easily collect credit card payments with Stripe. For getting started and more information, see our <a href="%1$s" target="_blank">Stripe documentation</a>.', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				Helpers::get_utm_url(
					'https://sugarcalendar.com/docs/bookings/setting-up-payment-options',
					[
						'medium'  => 'settings-payments-stripe',
						'content' => 'Stripe documentation',
					]
				)
			),
			[
				'a' => [
					'href'   => [],
					'target' => [],
				],
			]
		);

		UI::heading(
			[
				'id'          => 'stripe',
				'title'       => esc_html__( 'Stripe', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				'description' => $description,
			]
		);

		// Only show educational notice for the Lite version.
		if ( ! sugar_calendar_bookings()->is_pro() ) {

			$upgrade_url = Helpers::get_utm_url(
				'https://sugarcalendar.com/pricing/bookings/',
				[
					'source'  => 'WordPress',
					'medium'  => 'settings-payments-stripe',
					'content' => 'Upgrade to Pro',
				]
			);

			$upgrade_link_open = sprintf(
				'<a href="%1$s" target="_blank" rel="noopener noreferrer">',
				esc_url( $upgrade_url )
			);

			$upgrade_link_close = '</a>';

			UI::notice_banner(
				[
					'title'    => esc_html__( 'Pay-as-you-go Pricing', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
					'text'     => sprintf(
						/* translators: %1$s - opening link tag; %2$s - closing link tag. */
						esc_html__(
							'3%% fee per transaction + Stripe fees. %1$sUpgrade to Pro%2$s to remove additional fees and unlock powerful features.',
							'sugar-calendar-bookings-scheduling-appointments-lite'
						),
						$upgrade_link_open,
						$upgrade_link_close
					),
					'class'    => [ 'sugar-calendar-bookings-payment-notice-pay-as-you-go' ],
					'bordered' => true,
				]
			);
		}

		$options = Plugin::get( Options::class );

		$test_mode_description = wp_kses(
			sprintf(
			/* Translators: %1$s - Stripe dashboard URL. */
				__( 'While in test mode no live payments are processed. Be sure to enable Test Mode in your <a href="%1$s" target="_blank">Stripe Dashboard</a>.', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				esc_url( 'https://dashboard.stripe.com/dashboard' )
			),
			[
				'a' => [
					'href'   => [],
					'target' => [],
				],
			]
		);

		$test_mode = $options->get( 'stripe.test_mode', false );

		UI::toggle_control(
			[
				'id'          => 'stripe_test_mode',
				'name'        => [ 'stripe', 'test_mode' ],
				'value'       => $test_mode,
				'label'       => esc_html__( 'Test Mode', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				'description' => $test_mode_description,
			]
		);

		ob_start();

		if ( $this->gateway->is_configured() ) {
			?>
			<span>
			<?php
			echo wp_kses(
				sprintf(
				/* Translators: %1$s - Stripe connection mode. */
					__( 'Your Stripe account is connected in <strong>%1$s</strong> mode.', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
					$test_mode ? __( 'test', 'sugar-calendar-bookings-scheduling-appointments-lite' ) : __( 'live', 'sugar-calendar-bookings-scheduling-appointments-lite' )
				),
				[
					'strong' => [],
				]
			);
			?>
			</span>
			<?php
			UI::button(
				[
					'id'   => 'sugar-calendar-bookings-btn-stripe--reconnect',
					'type' => 'secondary',
					'size' => 'sm',
					'text' => esc_html__( 'Reconnect', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
					'link' => esc_url( $this->connect_handler->get_connect_url( $test_mode ) ),
				]
			);

			UI::button(
				[
					'id'   => 'sugar-calendar-bookings-btn-stripe--disconnect',
					'type' => 'tertiary',
					'size' => 'sm',
					'text' => esc_html__( 'Disconnect', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
					'link' => esc_url( $this->connect_handler->get_disconnect_url() ),
				]
			);
		} else {
			UI::button(
				[
					'id'          => 'sugar-calendar-bookings-btn-stripe--connect',
					'class'       => [ 'sugar-calendar-bookings-btn-stripe', 'sugar-calendar-bookings-btn-stripe--connect' ],
					'text'        => esc_html__( 'Connect with', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
					'link'        => $this->connect_handler->get_connect_url( $test_mode ),
					'data'        => [
						'test-url' => $this->connect_handler->get_connect_url( true ),
						'live-url' => $this->connect_handler->get_connect_url(),
					],
					'description' => sprintf(
					/* Translators: %1$s - Stripe documentation URL. */
						__( 'Securely connect to Stripe with just a few clicks to begin accepting payments! <a href="%1$s" target="_blank">Learn more</a> about connecting with Stripe.', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
						Helpers::get_utm_url(
							'https://sugarcalendar.com/docs/bookings/setting-up-payment-options',
							[
								'medium'  => 'settings-payments-stripe',
								'content' => 'Learn more',
							]
						)
					),
				]
			);
		}

		$stripe_button = ob_get_clean();

		UI::field_wrapper(
			[
				'id'    => 'stripe_connect',
				'class' => 'sugar-calendar-bookings-setting-row-stripe_connect' . ( $this->gateway->is_configured() ? '--connected' : '' ),
				'label' => esc_html__( 'Connection Status', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			],
			$stripe_button
		);
	}

	/**
	 * Get post data processing rules.
	 *
	 * @since 1.0.0
	 *
	 * @return array
	 */
	public function get_post_data_processing_rules() {

		return [
			'stripe.test_mode' => 'required|form_boolean',
		];
	}

	/**
	 * Handle oAuth connection requests.
	 *
	 * @since 1.0.0
	 */
	public function handle_connect() {

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$connection = $this->connect_handler->handle_connection( $_GET );

		// Bail if not connecting.
		if ( ! $connection ) {
			return;
		}

		// Redirect on error.
		if ( is_wp_error( $connection ) ) {
			WP::redirect_with_notice( PaymentsSettingsTab::get_url(), $connection->get_error_code() );
		}

		// TODO: maybe abstract this.
		/**
		 * Fires after a payment gateway has been connected.
		 *
		 * @since 1.0.0
		 *
		 * @param AbstractPaymentGateway $payment_gateway Payment gateway instance.
		 */
		do_action( 'sugar_calendar_bookings_payments_gateways_gateway_connected', $this->gateway ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName

		WP::redirect_with_notice( PaymentsSettingsTab::get_url(), 'oauth-connected-stripe' );
	}

	/**
	 * Handle oAuth disconnection requests.
	 *
	 * @since 1.0.0
	 */
	public function handle_disconnect() {

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$disconnection = $this->connect_handler->handle_disconnection( $_GET );

		// Bail if not disconnecting.
		if ( ! $disconnection ) {
			return;
		}

		/**
		 * Fires after a payment gateway has been disconnected.
		 *
		 * @since 1.0.0
		 *
		 * @param AbstractPaymentGateway $payment_gateway Payment gateway instance.
		 */
		do_action( 'sugar_calendar_bookings_payments_gateways_gateway_disconnected', $this->gateway ); // phpcs:ignore WPForms.PHP.ValidateHooks.InvalidHookName

		WP::redirect_with_notice( PaymentsSettingsTab::get_url(), 'oauth-disconnected-stripe' );
	}

	/**
	 * Display notices.
	 *
	 * @since 1.0.0
	 */
	public function display_notices() {

		$notices = Plugin::get( Notices::class );

		switch ( $notices->get_query_notice() ) {
			case 'oauth-connected-stripe':
				$notices->success( esc_html__( 'Stripe connected successfully.', 'sugar-calendar-bookings-scheduling-appointments-lite' ) );
				break;

			case 'oauth-disconnected-stripe':
				$notices->success( esc_html__( 'Stripe disconnected successfully.', 'sugar-calendar-bookings-scheduling-appointments-lite' ) );
				break;

			case 'oauth-error-credentials-stripe':
				$notices->error(
					sprintf(
					/* Translators: %1$s - Payment settings URL. */
						__(
							'There was an error getting your Stripe credentials. Please <a href="%s">try again</a>. If you continue to have this problem, please contact support.',
							'sugar-calendar-bookings-scheduling-appointments-lite'
						),
						esc_url( PaymentsSettingsTab::get_url() )
					)
				);
				break;

			case 'oauth-error-connect-stripe':
				$notices->error(
					$notices->get_query_notice_data()[0] ?? esc_html__( 'Authentication error.', 'sugar-calendar-bookings-scheduling-appointments-lite' )
				);

				return;
		}
	}
}
