<?php

namespace SugarCalendarBookings\SetupWizard;

use SugarCalendarBookings\Options;
use SugarCalendarBookings\Payments\Gateways\Stripe\StripePaymentGateway;
use SugarCalendarBookings\Plugin;
use SugarCalendarBookings\Support\Helpers\Helpers;
use SugarCalendarBookings\Support\Helpers\Security;
use WP_Error;

/**
 * Class StripeSetupService.
 *
 * Handles Stripe Connect setup and credential management for Setup Wizard.
 *
 * @since 1.2.0
 */
class StripeSetupService {


	/**
	 * Get Stripe settings for hydration.
	 *
	 * @since 1.2.0
	 *
	 * @return array
	 */
	public function get_settings() {

		return [
			'connect_url'       => $this->get_connect_url(),
			'connected'         => $this->is_connected(),
			'documentation_url' => Helpers::get_utm_url(
				'https://sugarcalendar.com/docs/bookings/setting-up-payment-options/',
				[
					'medium'  => 'setup-wizard',
					'content' => 'stripe-documentation',
				]
			),
		];
	}

	/**
	 * Connect to Stripe using OAuth state.
	 *
	 * @since 1.2.0
	 *
	 * @param string $state Stripe OAuth state parameter.
	 *
	 * @return array|WP_Error Array with 'connected' status on success, WP_Error on failure.
	 */
	public function connect( $state ) { // phpcs:ignore Generic.Metrics.CyclomaticComplexity.TooHigh

		$test_mode = Plugin::get( Options::class )->get( 'stripe.test_mode', false );

		$credentials_url = $this->get_credentials_url( $test_mode, $state );
		$response        = wp_remote_get( esc_url_raw( $credentials_url ) );

		if (
			is_wp_error( $response ) ||
			200 !== wp_remote_retrieve_response_code( $response ) ||
			! wp_remote_retrieve_body( $response )
		) {
			return new WP_Error(
				'stripe_connect_failed',
				__(
					'There was an error getting your Stripe credentials. Please try again. If you continue to have this problem, please contact support.',
					'sugar-calendar-bookings-scheduling-appointments-lite'
				)
			);
		}

		$response = json_decode( $response['body'], true );

		if ( empty( $response['data'] ) ) {
			return new WP_Error(
				'invalid_response',
				__( 'Invalid response from Stripe.', 'sugar-calendar-bookings-scheduling-appointments-lite' )
			);
		}

		$credentials = $response['data'];

		$this->save_credentials(
			$credentials['publishable_key'] ?? '',
			$credentials['secret_key'] ?? '',
			$credentials['stripe_user_id'] ?? '',
			$test_mode
		);

		return [ 'connected' => $this->is_connected() ];
	}

	/**
	 * Check if Stripe is connected.
	 *
	 * @since 1.2.0
	 *
	 * @return bool
	 */
	public function is_connected() {

		$gateway = Plugin::get( StripePaymentGateway::class );

		return $gateway ? $gateway->is_configured() : false;
	}

	/**
	 * Get Stripe connect URL.
	 *
	 * @since 1.2.0
	 *
	 * @return string
	 */
	public function get_connect_url() {

		$test_mode = Plugin::get( Options::class )->get( 'stripe.test_mode', false );

		return add_query_arg(
			[
				'sc_gateway_connect_init'     => 'stripe_connect',
				'live_mode'                   => (int) ! $test_mode,
				'state'                       => rawurlencode( Security::generate_secure_random( 32 ) ),
				'customer_site_url'           => rawurlencode( $this->get_return_url( $test_mode ) ),
				'error_parameter'             => 'scb_gateway_connect_error',
				'error_description_parameter' => 'scb_gateway_connect_error_description',
				'completion_parameter'        => 'scb_gateway_connect_completion',
			],
			$this->get_base_url()
		);
	}

	/**
	 * Get Stripe credentials URL.
	 *
	 * @since 1.2.0
	 *
	 * @param bool   $test_mode Whether Stripe is in test mode.
	 * @param string $state     Stripe state auth parameter.
	 *
	 * @return string
	 */
	private function get_credentials_url( $test_mode, $state ) {

		return add_query_arg(
			[
				'sc_gateway_connect_credentials' => 'stripe_connect',
				'live_mode'                      => (int) ! $test_mode,
				'state'                          => rawurlencode( $state ),
				'customer_site_url'              => rawurlencode( $this->get_return_url( $test_mode ) ),
			],
			$this->get_base_url()
		);
	}

	/**
	 * Get Setup Wizard Stripe return URL.
	 *
	 * Returns the ProductApi Setup Wizard URL with the Stripe step,
	 * including authentication token and REST API URL.
	 *
	 * @since 1.2.0
	 *
	 * @param bool $test_mode Whether test mode is activated.
	 *
	 * @return string
	 */
	private function get_return_url( $test_mode ) {

		$setup_wizard = Plugin::get( SetupWizard::class );
		$step_url     = $setup_wizard->get_url( 'steps/stripe-setup' );

		return add_query_arg(
			[
				'token'     => Plugin::get( Auth::class )->get_token(),
				'rest_url'  => rawurlencode( Plugin::get( RestApi::class )->get_url() ),
				'test_mode' => (int) $test_mode,
			],
			$step_url
		);
	}

	/**
	 * Get Stripe Connect base URL.
	 *
	 * @since 1.2.0
	 *
	 * @return string
	 */
	private function get_base_url() {

		return defined( 'SCBOOKINGS_STRIPE_CONNECT_BASE_URL' )
			? SCBOOKINGS_STRIPE_CONNECT_BASE_URL
			: 'https://sugarcalendar.com/';
	}

	/**
	 * Save Stripe credentials.
	 *
	 * @since 1.2.0
	 *
	 * @param string $publishable_key Publishable key.
	 * @param string $secret_key      Secret key.
	 * @param string $user_id         User ID.
	 * @param bool   $test_mode       Whether in test mode.
	 */
	private function save_credentials( $publishable_key, $secret_key, $user_id, $test_mode ) {

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

		if ( $test_mode === true ) {
			$data = [
				'stripe' => [
					'test_publishable_key' => $publishable_key,
					'test_secret_key'      => $secret_key,
					'test_user_id'         => $user_id,
					'test_mode'            => true,
				],
			];
		} else {
			$data = [
				'stripe' => [
					'live_publishable_key' => $publishable_key,
					'live_secret_key'      => $secret_key,
					'live_user_id'         => $user_id,
					'test_mode'            => false,
				],
			];
		}

		$options->update( $data );

		// Enable Stripe gateway.
		$options->update(
			[
				'payments' => [
					'gateways' => [
						'stripe' => [
							'enabled' => true,
						],
					],
				],
			]
		);
	}
}
