<?php

namespace SugarCalendarBookings\Integrations\OAuthRelay;

use SugarCalendarBookings\Admin\Area;
use SugarCalendarBookings\Admin\Settings\IntegrationsSettingsTab;
use SugarCalendarBookings\Support\Admin\Notices;
use SugarCalendarBookings\Support\Bootable;

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

/**
 * OAuth Connection Error Notice.
 *
 * Displays a dismissible admin notice on all plugin settings pages
 * when any OAuth connection has an authentication error and needs
 * to be reconnected.
 *
 * @since 1.4.0
 */
class OAuthConnectionErrorNotice implements Bootable {

	/**
	 * Notices instance.
	 *
	 * @since 1.4.0
	 *
	 * @var Notices
	 */
	private Notices $notices;

	/**
	 * Constructor.
	 *
	 * @since 1.4.0
	 *
	 * @param Notices $notices Notices instance.
	 */
	public function __construct( Notices $notices ) {

		$this->notices = $notices;
	}

	/**
	 * Whether to load this module.
	 *
	 * @since 1.4.0
	 *
	 * @return bool
	 */
	public function allow_load(): bool {

		return is_admin();
	}

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

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

	/**
	 * Display notice if any OAuth connections have auth errors.
	 *
	 * @since 1.4.0
	 */
	public function maybe_display_notice() {

		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		// Skip on the integrations settings page — the inline error UI is sufficient.
		if ( $this->is_integrations_page() ) {
			return;
		}

		$errored_connections = $this->get_errored_connections();

		if ( empty( $errored_connections ) ) {
			return;
		}

		$this->display_notice( $errored_connections );
	}

	/**
	 * Check if the current page is the integrations settings page.
	 *
	 * @since 1.4.0
	 *
	 * @return bool
	 */
	private function is_integrations_page(): bool {

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : '';
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$view = isset( $_GET['view'] ) ? sanitize_text_field( wp_unslash( $_GET['view'] ) ) : '';

		return $page === Area::SLUG . '-settings' && $view === 'integrations';
	}

	/**
	 * Get OAuth connections with auth errors.
	 *
	 * @since 1.4.0
	 *
	 * @return OAuthConnectionModel[]
	 */
	private function get_errored_connections(): array {

		return OAuthConnectionModel::query()
			->where( 'status', '=', 'auth_error', '%s' )
			->get();
	}

	/**
	 * Display the error notice linking to the integrations settings page.
	 *
	 * @since 1.4.0
	 *
	 * @param OAuthConnectionModel[] $connections Errored connections.
	 */
	private function display_notice( array $connections ) {

		$providers = array_unique( array_map( fn( $c ) => ucfirst( $c->provider ), $connections ) );

		$message = sprintf(
			wp_kses( /* translators: %1$s - comma-separated provider names; %2$s - URL to Integrations settings page. */
				__(
					'Your %1$s connection has lost authorization. Meetings will not be created until this is resolved. Please visit <a href="%2$s">Integrations Settings</a> to refresh or reconnect your account.',
					'sugar-calendar-bookings-scheduling-appointments-lite'
				),
				[
					'a' => [
						'href' => [],
					],
				]
			),
			esc_html( implode( ', ', $providers ) ),
			esc_url( IntegrationsSettingsTab::get_url() )
		);

		$this->notices->error( $message );
	}
}
