<?php

namespace SugarCalendarBookings\Admin\Settings;

use SugarCalendarBookings\Admin\Area;
use SugarCalendarBookings\Integrations\Credits\CreditsService;
use SugarCalendarBookings\Integrations\IntegrationInterface;
use SugarCalendarBookings\Integrations\IntegrationRegistry;
use SugarCalendarBookings\Options;
use SugarCalendarBookings\Plugin;
use SugarCalendarBookings\Support\Admin\AbstractTabPage;
use SugarCalendarBookings\Support\Admin\Notices;
use SugarCalendarBookings\Support\Helpers\Helpers;
use SugarCalendarBookings\Support\Helpers\UI;
use SugarCalendarBookings\Vendor\ProductApi\Auth\SiteRegistration;
use SugarCalendarBookings\Vendor\ProductApi\ProductApi;

/**
 * Integrations Settings tab.
 *
 * Renders the integrations page with sidebar navigation and content panels.
 * Each integration registers itself into the IntegrationRegistry and provides
 * its own sidebar nav item and content panel rendering.
 *
 * @since 1.4.0
 */
class IntegrationsSettingsTab extends AbstractTabPage {

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

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

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

		return 'settings';
	}

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

		return 'integrations';
	}

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

		return 50;
	}

	/**
	 * Check if site is registered with Product API.
	 *
	 * @since 1.4.0
	 *
	 * @return bool
	 */
	private function is_site_registered(): bool {

		return ProductApi::get( SiteRegistration::class )->is_registered();
	}

	/**
	 * Get page script data.
	 *
	 * @since 1.4.0
	 *
	 * @return array
	 */
	public function get_script_data() {

		return [
			'credits_usage' => current_user_can( 'manage_options' )
				? Plugin::get( CreditsService::class )->get_credits()
				: null,
		];
	}

	/**
	 * Get the currently active integration slug from the URL.
	 *
	 * @since 1.4.0
	 *
	 * @return string
	 */
	private function get_active_integration_slug(): string {

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended
		return isset( $_GET['integration'] ) ? sanitize_key( $_GET['integration'] ) : '';
	}

	/**
	 * Get the active integration, falling back to the first registered one.
	 *
	 * @since 1.4.0
	 *
	 * @param IntegrationRegistry $registry Integration registry.
	 *
	 * @return IntegrationInterface|null
	 */
	private function get_active_integration( IntegrationRegistry $registry ): ?IntegrationInterface {

		$slug        = $this->get_active_integration_slug();
		$integration = $registry->get_by_slug( $slug );

		// Fall back to first registered integration.
		if ( $integration === null ) {
			$all = $registry->get_all();

			$integration = ! empty( $all ) ? reset( $all ) : null;
		}

		return $integration;
	}

	/**
	 * Get the URL for an integration tab.
	 *
	 * @since 1.4.0
	 *
	 * @param string $slug Integration slug.
	 *
	 * @return string
	 */
	private function get_integration_url( string $slug ): string {

		return add_query_arg( 'integration', $slug, self::get_url() );
	}

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

		$registry    = Plugin::get( IntegrationRegistry::class );
		$integration = $this->get_active_integration( $registry );

		$this->render_header();

		?>
		<div id="sugar-calendar-bookings-integrations-content">
			<?php if ( Plugin::get( Options::class )->get( 'misc.disable_integrations' ) ) : ?>
				<?php
				UI::notice_banner(
					[
						'text'     => sprintf(
							wp_kses( /* translators: %1$s - Misc settings page URL. */
								__( 'Integrations have been disabled. You can re-enable them on the <a href="%1$s">Misc</a> settings page.', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
								[
									'a' => [
										'href' => [],
									],
								]
							),
							esc_url( MiscSettingsTab::get_url() )
						),
						'bordered' => true,
					]
				);
				?>
			<?php elseif ( ! current_user_can( 'manage_options' ) && ! $this->is_site_registered() ) : ?>
				<?php
				UI::notice_banner(
					[
						'text'     => esc_html__( 'Integrations are not available yet. Please ask your administrator to set them up.', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
						'bordered' => true,
					]
				);
				?>
			<?php elseif ( $integration !== null ) : ?>
				<div class="scb-integrations-panel">
					<?php $this->render_sidebar( $registry, $integration ); ?>
					<?php $this->render_content_panel( $integration ); ?>
				</div>
			<?php endif; ?>
		</div>

		<div id="sugar-calendar-bookings-integrations-app"></div>
		<?php

		UI::confirmation_modal();
	}

	/**
	 * Render the page header.
	 *
	 * @since 1.4.0
	 */
	private function render_header(): void {

		$credits = current_user_can( 'manage_options' )
			? Plugin::get( CreditsService::class )->get_credits()
			: null;

		?>
		<div class="scb-integrations-header">
			<div class="scb-integrations-header__content">
				<h2 class="scb-integrations-header__title">
					<?php esc_html_e( 'Configure Integrations', 'sugar-calendar-bookings-scheduling-appointments-lite' ); ?>
				</h2>
				<p class="scb-integrations-header__description">
					<?php esc_html_e( 'Connect calendar, video conferencing, and automation tools to streamline your booking workflow', 'sugar-calendar-bookings-scheduling-appointments-lite' ); ?>
				</p>
			</div>

			<?php if ( $credits !== null && current_user_can( 'manage_options' ) ) : ?>
				<?php $this->render_credits_signal( $credits ); ?>
			<?php endif; ?>
		</div>
		<?php
	}

	/**
	 * Render the credits usage signal (pill + popup).
	 *
	 * @since 1.4.0
	 *
	 * @param array $credits Credits data from CreditsService.
	 */
	private function render_credits_signal( array $credits ): void {

		$is_maxed    = $credits['is_maxed'];
		$maxed_class = $is_maxed ? ' is-maxed' : '';
		$percentage  = $credits['percentage'];

		?>
		<div class="scb-credits-signal-wrapper">
			<button type="button"
				class="scb-credits-signal<?php echo esc_attr( $maxed_class ); ?>"
				data-credits-toggle
				aria-expanded="false"
				aria-controls="scb-credits-popup">
				<?php // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- SVG markup. ?>
				<?php echo $this->get_circular_indicator_svg( $percentage, $is_maxed ); ?>
				<span class="scb-credits-signal__text">
					<?php
					$decimals = fmod( (float) $percentage, 1.0 ) === 0.0 ? 0 : 1;
					printf(
						/* translators: %1$s - percentage of integration credits used. */
						esc_html__( '%1$s%% Integration Usage Used', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
						esc_html( number_format_i18n( (float) $percentage, $decimals ) )
					);
					?>
				</span>
			</button>

			<div id="scb-credits-popup"
				class="scb-credits-popup<?php echo esc_attr( $maxed_class ); ?>"
				role="dialog"
				aria-label="<?php esc_attr_e( 'Integration credit usage details', 'sugar-calendar-bookings-scheduling-appointments-lite' ); ?>">
				<div class="scb-credits-popup__content">
					<div class="scb-credits-popup__header">
						<?php $this->render_usage_header_text( $credits ); ?>
					</div>

					<div class="scb-credits-popup__bar">
						<div class="scb-credits-popup__bar-track">
							<div class="scb-credits-popup__bar-fill"
								style="width: <?php echo esc_attr( $percentage ); ?>%"></div>
						</div>
					</div>

					<div class="scb-credits-popup__footer">
						<?php if ( $credits['resets_at'] !== null ) : ?>
							<span class="scb-credits-popup__reset-text">
								<?php echo esc_html( $this->get_reset_text( $credits['resets_at'] ) ); ?>
							</span>
						<?php else : ?>
							<span class="scb-credits-popup__reset-text">
								<?php esc_html_e( 'Lifetime credit limit', 'sugar-calendar-bookings-scheduling-appointments-lite' ); ?>
							</span>
						<?php endif; ?>

						<?php if ( $credits['show_upgrade'] ) : ?>
							<a href="<?php echo esc_url( $this->get_credits_upgrade_url() ); ?>"
								class="scb-credits-popup__upgrade-link"
								target="_blank"
								rel="noopener noreferrer">
								<?php esc_html_e( 'Upgrade for more', 'sugar-calendar-bookings-scheduling-appointments-lite' ); ?>
							</a>
						<?php endif; ?>
					</div>
				</div>
			</div>
		</div>
		<?php
	}

	/**
	 * Get the SVG markup for the circular progress indicator.
	 *
	 * @since 1.4.0
	 *
	 * @param int  $percentage Usage percentage (0-100).
	 * @param bool $is_maxed   Whether credits are fully used.
	 *
	 * @return string SVG markup.
	 */
	private function get_circular_indicator_svg( float $percentage, bool $is_maxed ): string {

		// Circle parameters: 16x16 viewBox, radius 6, center at 8,8.
		$radius        = 6;
		$circumference = 2 * M_PI * $radius;
		$offset        = $circumference - ( $percentage / 100 ) * $circumference;

		$fill_class = $is_maxed ? 'scb-credits-indicator__fill--maxed' : 'scb-credits-indicator__fill';

		return '<svg class="scb-credits-indicator" width="16" height="16" viewBox="0 0 16 16">'
			. '<circle class="scb-credits-indicator__track" cx="8" cy="8" r="' . (int) $radius . '" fill="none" stroke-width="2.5"/>'
			. '<circle class="' . esc_attr( $fill_class ) . '" cx="8" cy="8" r="' . (int) $radius . '" fill="none" stroke-width="2.5"'
			. ' stroke-dasharray="' . esc_attr( (string) $circumference ) . '"'
			. ' stroke-dashoffset="' . esc_attr( (string) $offset ) . '"'
			. ' transform="rotate(-90 8 8)"/>'
			. '</svg>';
	}

	/**
	 * Render the usage header text for the popup.
	 *
	 * The "used" number is rendered with a prominent style, the rest in muted text.
	 *
	 * @since 1.4.0
	 *
	 * @param array $credits Credits data.
	 */
	private function render_usage_header_text( array $credits ): void {

		$used      = number_format_i18n( $credits['used'] );
		$total     = number_format_i18n( $credits['total'] );
		$used_html = '<span class="scb-credits-popup__used-count">' . esc_html( $used ) . '</span>';
		$kses_tags = [ 'span' => [ 'class' => [] ] ];

		if ( $credits['resets_at'] === null ) {
			$format = wp_kses( /* translators: %1$s - credits used (styled); %2$s - total credits. */
				__( '%1$s / %2$s used', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				$kses_tags
			);
			$args   = [ $used_html, esc_html( $total ) ];
		} else {
			// resets_at is the next reset date; current period is the month before.
			$reset_time   = strtotime( $credits['resets_at'] );
			$period_month = wp_date( 'F Y', strtotime( '-1 day', $reset_time ) );

			$format = wp_kses( /* translators: %1$s - credits used (styled); %2$s - total credits; %3$s - billing period month and year. */
				__( '%1$s / %2$s used for %3$s', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				$kses_tags
			);
			$args   = [ $used_html, esc_html( $total ), esc_html( $period_month ) ];
		}

		?>
		<span class="scb-credits-popup__usage-text">
			<?php
			// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- $format is wp_kses'd, $args values are esc_html'd.
			printf( $format, ...$args );
			?>
		</span>
		<?php
	}

	/**
	 * Get the reset countdown text.
	 *
	 * @since 1.4.0
	 *
	 * @param string $resets_at ISO 8601 reset date.
	 *
	 * @return string Reset text like "Resets in 12 days".
	 */
	private function get_reset_text( string $resets_at ): string {

		$reset_ts  = strtotime( $resets_at );
		$days_left = max( 0, (int) ceil( ( $reset_ts - time() ) / DAY_IN_SECONDS ) );

		if ( $days_left === 0 ) {
			return esc_html__( 'Resets today', 'sugar-calendar-bookings-scheduling-appointments-lite' );
		}

		return sprintf(
			esc_html( /* translators: %1$d - number of days until credit reset. */
				_n(
					'Resets in %1$d day',
					'Resets in %1$d days',
					$days_left,
					'sugar-calendar-bookings-scheduling-appointments-lite'
				)
			),
			$days_left
		);
	}

	/**
	 * Get the upgrade URL with UTM parameters.
	 *
	 * @since 1.4.0
	 *
	 * @return string
	 */
	private function get_credits_upgrade_url(): string {

		return Helpers::get_utm_url(
			'https://sugarcalendar.com/pricing/bookings/',
			[
				'medium'  => 'integrations-settings',
				'content' => 'integration-credits-upgrade',
			]
		);
	}

	/**
	 * Render the sidebar navigation.
	 *
	 * @since 1.4.0
	 *
	 * @param IntegrationRegistry  $registry Integration registry.
	 * @param IntegrationInterface $active   Active integration.
	 */
	private function render_sidebar( IntegrationRegistry $registry, IntegrationInterface $active ): void {

		?>
		<div class="scb-integrations-sidebar">
			<?php foreach ( $registry->get_all() as $integration ) : ?>
				<?php $this->render_sidebar_item( $integration, $integration->get_slug() === $active->get_slug() ); ?>
			<?php endforeach; ?>

			<?php $this->render_coming_soon_items(); ?>
		</div>
		<?php
	}

	/**
	 * Render a single sidebar navigation item.
	 *
	 * @since 1.4.0
	 *
	 * @param IntegrationInterface $integration Integration instance.
	 * @param bool                 $is_active   Whether this tab is active.
	 */
	private function render_sidebar_item( IntegrationInterface $integration, bool $is_active ): void {

		$classes = [ 'scb-integrations-sidebar__item' ];

		if ( $is_active ) {
			$classes[] = 'scb-integrations-sidebar__item--active';
		}

		// Sidebar icon reflects the real connection state: hidden when no
		// accounts are connected, a check when all is well, and a red cross
		// when one or more connected accounts have auth/token problems.
		$status       = $integration->get_status();
		$show_status  = $status !== 'not_connected';
		$status_icon  = $this->get_sidebar_status_icon( $status );
		$status_class = $this->get_sidebar_status_class( $status );
		?>

		<a href="<?php echo esc_url( $this->get_integration_url( $integration->get_slug() ) ); ?>"
			class="<?php echo esc_attr( implode( ' ', $classes ) ); ?>">

			<img
				class="scb-integrations-sidebar__icon"
				src="<?php echo esc_url( $integration->get_icon_url() ); ?>"
				alt="<?php echo esc_attr( $integration->get_name() ); ?>"
				width="40"
				height="40"
			/>

			<span class="scb-integrations-sidebar__name">
				<?php echo esc_html( $integration->get_name() ); ?>
			</span>

			<?php if ( $show_status ) : ?>
				<span class="scb-integrations-sidebar__status <?php echo esc_attr( $status_class ); ?>">
					<?php UI::svg_icon( $status_icon ); ?>
				</span>
			<?php endif; ?>
		</a>
		<?php
	}

	/**
	 * Get the sidebar status icon name for an integration status.
	 *
	 * @since 1.4.0
	 *
	 * @param string $status Integration status.
	 *
	 * @return string Icon name for UI::svg_icon().
	 */
	private function get_sidebar_status_icon( string $status ): string {

		$map = [
			'connected'         => 'check-circle',
			'paused'            => 'pause-circle',
			'not_connected'     => 'times-circle',
			'disabled'          => 'times-circle',
			'disabled_by_admin' => 'times-circle',
			'out_of_credits'    => 'times-circle',
			'error'             => 'times-circle',
		];

		return $map[ $status ] ?? 'times-circle';
	}

	/**
	 * Get the sidebar status CSS class for an integration status.
	 *
	 * @since 1.4.0
	 *
	 * @param string $status Integration status.
	 *
	 * @return string CSS class for the sidebar status indicator.
	 */
	private function get_sidebar_status_class( string $status ): string {

		$map = [
			'connected'         => 'scb-integrations-sidebar__status--connected',
			'paused'            => 'scb-integrations-sidebar__status--paused',
			'not_connected'     => 'scb-integrations-sidebar__status--disconnected',
			'disabled'          => 'scb-integrations-sidebar__status--disconnected',
			'disabled_by_admin' => 'scb-integrations-sidebar__status--disconnected',
			'out_of_credits'    => 'scb-integrations-sidebar__status--disconnected',
			'error'             => 'scb-integrations-sidebar__status--disconnected',
		];

		return $map[ $status ] ?? 'scb-integrations-sidebar__status--disconnected';
	}

	/**
	 * Get the list of coming soon integrations.
	 *
	 * @since 1.4.0
	 *
	 * @return array[] Each item has 'name' and 'icon' keys.
	 */
	private function get_coming_soon_integrations(): array {

		$icons_url = SCBOOKINGS_PLUGIN_URL . 'assets/images/icons/integrations/';

		return [
			[
				'name' => esc_html__( 'Google Meet', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				'icon' => $icons_url . 'google-calendar.png',
			],
			[
				'name' => esc_html__( 'Apple Calendar', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				'icon' => $icons_url . 'apple-calendar.png',
			],
			[
				'name' => esc_html__( 'Zapier', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				'icon' => $icons_url . 'zapier.png',
			],
			[
				'name' => esc_html__( 'iCalendar Feed', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
				'icon' => $icons_url . 'icalendar-feed.png',
			],
		];
	}

	/**
	 * Render the coming soon integration items in the sidebar.
	 *
	 * @since 1.4.0
	 */
	private function render_coming_soon_items(): void {

		foreach ( $this->get_coming_soon_integrations() as $integration ) :
			?>
			<div class="scb-integrations-sidebar__item scb-integrations-sidebar__item--coming-soon">
				<img
					class="scb-integrations-sidebar__icon"
					src="<?php echo esc_url( $integration['icon'] ); ?>"
					alt="<?php echo esc_attr( $integration['name'] ); ?>"
					width="40"
					height="40"
				/>

				<span class="scb-integrations-sidebar__name">
					<?php echo esc_html( $integration['name'] ); ?>
				</span>

				<span class="scb-integrations-sidebar__badge-coming-soon">
					<?php esc_html_e( 'Coming Soon', 'sugar-calendar-bookings-scheduling-appointments-lite' ); ?>
				</span>
			</div>
			<?php
		endforeach;
	}

	/**
	 * Render the content panel for the active integration.
	 *
	 * @since 1.4.0
	 *
	 * @param IntegrationInterface $integration Active integration.
	 */
	private function render_content_panel( IntegrationInterface $integration ): void {

		$status      = $integration->get_status();
		$badge_class = $this->get_status_badge_class( $status );
		$badge_label = $this->get_status_badge_label( $status );
		?>

		<div class="scb-integrations-content">
			<div class="scb-integrations-content__title-bar">
				<h2 class="scb-integrations-content__title">
					<?php echo esc_html( $integration->get_name() ); ?>
				</h2>
				<span class="sugar-calendar-bookings-badge sugar-calendar-bookings-badge--<?php echo esc_attr( $badge_class ); ?>">
					<?php echo esc_html( $badge_label ); ?>
				</span>
			</div>

			<form class="sugar-calendar-bookings-admin-content__settings-form" method="post" action="">
				<div class="scb-integrations-content__body">
					<?php $integration->render_content(); ?>
				</div>

				<div class="scb-integrations-content__footer">
					<p class="submit">
						<?php
						UI::button(
							[
								'text' => esc_html__( 'Save Settings', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
							]
						);
						?>
					</p>
				</div>

				<?php wp_nonce_field( Area::SLUG ); ?>
			</form>
		</div>
		<?php
	}

	/**
	 * Get the CSS class for the status badge.
	 *
	 * @since 1.4.0
	 *
	 * @param string $status Integration status.
	 *
	 * @return string
	 */
	private function get_status_badge_class( string $status ): string {

		$map = [
			'connected'         => 'green',
			'paused'            => 'yellow',
			'not_connected'     => 'neutral',
			'disabled'          => 'neutral',
			'disabled_by_admin' => 'red',
			'out_of_credits'    => 'red',
			'error'             => 'red',
		];

		return $map[ $status ] ?? 'neutral';
	}

	/**
	 * Get the label for the status badge.
	 *
	 * @since 1.4.0
	 *
	 * @param string $status Integration status.
	 *
	 * @return string
	 */
	private function get_status_badge_label( string $status ): string {

		$map = [
			'connected'         => esc_html__( 'Connected', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			'paused'            => esc_html__( 'Paused', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			'not_connected'     => esc_html__( 'Not Connected', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			'disabled'          => esc_html__( 'Disabled', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			'disabled_by_admin' => esc_html__( 'Disabled by Admin', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			'out_of_credits'    => esc_html__( 'Out of Credits', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			'error'             => esc_html__( 'Reconnection Required', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
		];

		return $map[ $status ] ?? esc_html__( 'Unknown', 'sugar-calendar-bookings-scheduling-appointments-lite' );
	}

	/**
	 * Get post data processing rules.
	 *
	 * Delegates to the active integration so each integration defines its own rules.
	 *
	 * @since 1.4.0
	 *
	 * @return array
	 */
	public function get_post_data_processing_rules() {

		$registry    = Plugin::get( IntegrationRegistry::class );
		$integration = $this->get_active_integration( $registry );

		if ( $integration === null ) {
			return [];
		}

		return $integration->get_post_data_processing_rules();
	}

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

		$registry    = Plugin::get( IntegrationRegistry::class );
		$integration = $this->get_active_integration( $registry );

		// Let the integration process its own POST data.
		if ( $integration !== null && method_exists( $integration, 'handle_post_data' ) ) {
			$integration->handle_post_data( $post_data );
		}

		// Only admins can modify global plugin settings.
		if ( current_user_can( 'manage_options' ) ) {
			Plugin::get( Options::class )->update( $post_data );
		}

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