<?php

namespace SugarCalendarBookings\Admin\Settings;

use Exception;
use SugarCalendarBookings\Options;
use SugarCalendarBookings\Payments\Admin\PaymentMethodsSection;
use SugarCalendarBookings\Payments\Gateways\PaymentGatewayRegistry;
use SugarCalendarBookings\Plugin;
use SugarCalendarBookings\Support\Admin\AbstractTabPage;
use SugarCalendarBookings\Support\Admin\Notices;
use SugarCalendarBookings\Support\Data\Currencies;
use SugarCalendarBookings\Support\DataProcessing\InputProcessor;
use SugarCalendarBookings\Support\Helpers\UI;

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

/**
 * Payments Settings tab.
 *
 * @since 1.0.0
 */
class PaymentsSettingsTab extends AbstractTabPage {

	/**
	 * Page title.
	 *
	 * @since 1.0.0
	 *
	 * @return string
	 */
	public static function get_title() {

		return esc_html__( 'Payments', 'sugar-calendar-bookings-scheduling-appointments-lite' );
	}

	/**
	 * Page slug.
	 *
	 * @since 1.0.0
	 *
	 * @return string
	 */
	public static function get_slug() {

		return 'settings';
	}

	/**
	 * Page view slug.
	 *
	 * @since 1.0.0
	 *
	 * @return string
	 */
	public static function get_view_slug() {

		return 'payments';
	}

	/**
	 * Priority in menu position.
	 *
	 * @since 1.0.0
	 *
	 * @return int
	 */
	public static function get_priority() {

		return 30;
	}

	/**
	 * Register page hooks.
	 *
	 * @since 1.0.0
	 */
	public function hooks() {

		add_action( 'admin_init', [ $this, 'handle_auth' ] );
		add_action( 'admin_init', [ $this, 'display_notices' ] );
	}

	/**
	 * Display page.
	 *
	 * @since 1.0.0
	 */
	public function display_content() {

		ob_start();

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

		// Display payment methods section.
		Plugin::get( PaymentMethodsSection::class )->display_content();

		// Payment gateway specific settings.
		foreach ( Plugin::get( PaymentGatewayRegistry::class )->get_registered() as $gateway ) {
			$gateway->get_settings()->display_content();
		}

		// Display heading.
		UI::heading(
			[
				'title' => esc_html__( 'Currency', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			]
		);

		// Currency.
		UI::select_input(
			[
				'id'          => 'payments_currency',
				'name'        => [ 'payments', 'currency' ],
				'options'     => Currencies::get_all(),
				'value'       => $options->get( 'payments.currency' ),
				'label'       => esc_html__( 'Currency', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				'description' => esc_html__( 'Choose your currency. Note that some payment gateways have currency restrictions.', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			]
		);

		// Symbol position.
		$positions = [
			'before' => esc_html__( 'Before ($10)', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			'after'  => esc_html__( 'After (10$)', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
		];

		UI::select_input(
			[
				'id'          => 'payments_currency_position',
				'name'        => [ 'payments', 'currency_position' ],
				'options'     => $positions,
				'value'       => $options->get( 'payments.currency_position' ),
				'label'       => esc_html__( 'Currency Symbol Position', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				'description' => esc_html__( 'Choose the location of the currency symbol.', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			]
		);

		// Thousands separator.
		$thousands_description = sprintf( /* translators: %1$s - field description; %2$s - or.*/
			'%1$s <code>,</code> %2$s <code>.</code>.',
			esc_html__( 'The symbol to separate thousandths. Usually', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			esc_html__( 'or', 'sugar-calendar-bookings-scheduling-appointments-lite' )
		);

		UI::text_input(
			[
				'id'          => 'payments_thousands_separator',
				'name'        => [ 'payments', 'thousands_separator' ],
				'value'       => $options->get( 'payments.thousands_separator' ),
				'label'       => esc_html__( 'Thousands Separator', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				'description' => $thousands_description,
			]
		);

		$decimal_description = sprintf( /* translators: %1$s - field description; %2$s - or.*/
			'%1$s <code>,</code> %2$s <code>.</code>.',
			esc_html__( 'The symbol to separate decimal points. Usually', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			esc_html__( 'or', 'sugar-calendar-bookings-scheduling-appointments-lite' )
		);

		UI::text_input(
			[
				'id'          => 'payments_decimal_separator',
				'name'        => [ 'payments', 'decimal_separator' ],
				'value'       => $options->get( 'payments.decimal_separator' ),
				'label'       => esc_html__( 'Decimal Separator', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				'description' => $decimal_description,
			]
		);

		UI::form_wrapper( ob_get_clean() );

		// Render confirmation modal.
		UI::confirmation_modal();
	}

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

		$currencies = implode( ',', array_keys( Currencies::get_all() ) );

		$rules = [
			'payments.currency'            => "required|string|in:$currencies",
			'payments.currency_position'   => 'required|string|in:before,after',
			'payments.thousands_separator' => 'required|string',
			'payments.decimal_separator'   => 'required|string',
		];

		// Add validation rules for gateway enabled states.
		foreach ( Plugin::get( PaymentGatewayRegistry::class )->get_registered() as $gateway ) {
			$gateway_id = $gateway::get_id();

			$rules[ "payments.gateways.{$gateway_id}.enabled" ] = 'form_boolean';

			$rules = array_merge(
				$rules,
				$gateway->get_settings()->get_post_data_processing_rules()
			);
		}

		return $rules;
	}

	/**
	 * Handle POST requests.
	 *
	 * @since 1.0.0
	 *
	 * @param array $post_data Post data.
	 */
	public function handle_post( $post_data = [] ) {

		// Ensure onsite is always enabled if no other gateways are enabled.
		$stripe_gateway = Plugin::get( PaymentGatewayRegistry::class )->get_registered()['stripe'] ?? null;
		$stripe_enabled = ! empty( $post_data['payments']['gateways']['stripe']['enabled'] ) && $stripe_gateway && $stripe_gateway->is_configured();

		if ( ! $stripe_enabled ) {
			$post_data['payments']['gateways']['onsite']['enabled'] = true;
		}

		Plugin::get( Options::class )->update( $post_data );

		Plugin::get( Notices::class )->success( __( 'Settings successfully saved.', 'sugar-calendar-bookings-scheduling-appointments-lite' ) );
	}

	/**
	 * Handle authentication requests.
	 *
	 * @since 1.0.0
	 */
	public function handle_auth() {

		foreach ( Plugin::get( PaymentGatewayRegistry::class )->get_registered() as $gateway ) {
			try {
				$gateway->get_settings()->handle_connect();
				$gateway->get_settings()->handle_disconnect();
			} catch ( Exception $e ) {
				Plugin::get( Notices::class )->error( $e->getMessage() );

				return;
			}
		}
	}

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

		foreach ( Plugin::get( PaymentGatewayRegistry::class )->get_registered() as $gateway ) {
			$gateway->get_settings()->display_notices();
		}
	}
}
