<?php

namespace SugarCalendarBookings\Integrations\Credits;

use SugarCalendarBookings\Admin\Settings\LicenseSettingsTab;
use SugarCalendarBookings\Integrations\IntegrationRegistry;
use SugarCalendarBookings\Notifications\Emails\EmailService;
use SugarCalendarBookings\Plugin;
use SugarCalendarBookings\Support\Helpers\Helpers;

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

/**
 * Credit usage alert email (Lite — lifetime plans only).
 *
 * Sends a one-time email to the site admin when integration credit usage reaches 80%.
 * Pro extends this to add monthly billing cycle support.
 *
 * @since 1.4.0
 */
class CreditAlertEmail {

	/**
	 * Option key for tracking sent alerts.
	 *
	 * @since 1.4.0
	 *
	 * @var string
	 */
	const OPTION_KEY = 'sugar_calendar_bookings_credit_alert_sent';

	/**
	 * Usage threshold percentage to trigger the alert.
	 *
	 * @since 1.4.0
	 *
	 * @var int
	 */
	const THRESHOLD = 80;

	/**
	 * Email ID for the credit usage alert.
	 *
	 * @since 1.4.0
	 *
	 * @var string
	 */
	const EMAIL_ID = 'credit_usage_alert_admin';

	/**
	 * Check credit data and send alert email if threshold is reached.
	 *
	 * @since 1.4.0
	 *
	 * @param array $credits Formatted credits data from CreditsService.
	 */
	public function maybe_send( array $credits ): void {

		if ( $credits['percentage'] < self::THRESHOLD ) {
			return;
		}

		if ( $this->was_already_sent( $credits['resets_at'] ) ) {
			return;
		}

		$sent = Plugin::get( EmailService::class )->send_admin_email(
			self::EMAIL_ID,
			get_option( 'admin_email' ),
			$this->get_email_vars( $credits )
		);

		if ( $sent ) {
			$this->mark_as_sent( $credits['resets_at'] );
		}
	}

	/**
	 * Check if the alert was already sent.
	 *
	 * Lite handles lifetime plans only: sent if option exists.
	 * Pro overrides to add monthly cycle support.
	 *
	 * @since 1.4.0
	 *
	 * @param string|null $resets_at Current resets_at value.
	 *
	 * @return bool True if already sent.
	 */
	protected function was_already_sent( ?string $resets_at ): bool {

		return get_option( self::OPTION_KEY ) !== false;
	}

	/**
	 * Mark the alert as sent.
	 *
	 * Lite stores 'lifetime'. Pro overrides for monthly cycle tracking.
	 *
	 * @since 1.4.0
	 *
	 * @param string|null $resets_at Current resets_at value.
	 */
	protected function mark_as_sent( ?string $resets_at ): void {

		update_option( self::OPTION_KEY, 'lifetime', false );
	}

	/**
	 * Get email template variables.
	 *
	 * Pro overrides to add {reset_date}.
	 *
	 * @since 1.4.0
	 *
	 * @param array $credits Formatted credits data.
	 *
	 * @return array Key-value pairs of smart tag => value.
	 */
	protected function get_email_vars( array $credits ): array {

		return [
			'{used}'               => number_format_i18n( $credits['used'] ),
			'{total}'              => number_format_i18n( $credits['total'] ),
			'{remaining}'          => number_format_i18n( $credits['remaining'] ),
			'{percentage}'         => (string) $credits['percentage'],
			'{credits_context}'    => $this->get_credits_context( $credits ),
			'{license_usage_url}'  => LicenseSettingsTab::get_url(),
			'{upgrade_url}'        => Helpers::get_utm_url(
				'https://sugarcalendar.com/pricing/bookings/',
				[
					'source'  => 'WordPress',
					'medium'  => 'credit-alert-email',
					'content' => 'usage-credits-upgrade',
				]
			),
			'{site_name}'          => get_bloginfo( 'name' ),
			'{admin_display_name}' => $this->get_admin_display_name(),
		];
	}

	/**
	 * Get the display name of the site admin for greeting the email recipient.
	 *
	 * Falls back to a generic "there" when the admin email doesn't resolve to a user.
	 *
	 * @since 1.4.0
	 *
	 * @return string
	 */
	protected function get_admin_display_name(): string {

		$user = get_user_by( 'email', get_option( 'admin_email' ) );

		if ( $user && ! empty( $user->display_name ) ) {
			return esc_html( $user->display_name );
		}

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

	/**
	 * Get the context paragraph for lifetime plans.
	 *
	 * Pro overrides to add monthly plan variant.
	 *
	 * @since 1.4.0
	 *
	 * @param array $credits Formatted credits data.
	 *
	 * @return string Context paragraph text.
	 */
	protected function get_credits_context( array $credits ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter.Found

		$integrations = $this->get_connected_integrations_text();

		if ( $integrations === '' ) {
			return esc_html__(
				'These credits don\'t reset. Once they run out, your connected integrations will stop working.',
				'sugar-calendar-bookings-scheduling-appointments-lite'
			);
		}

		return sprintf( /* translators: %1$s - comma-separated list of connected integration names. */
			esc_html__( 'These credits don\'t reset. Once they run out, %1$s will stop working.', 'sugar-calendar-bookings-scheduling-appointments-lite' ),
			$integrations
		);
	}

	/**
	 * Get a human-readable list of currently connected integrations.
	 *
	 * Uses WordPress's list formatter so the output respects locale rules
	 * (e.g. "Zoom, Google Meet, and Google Calendar").
	 *
	 * @since 1.4.0
	 *
	 * @return string Formatted list, or empty string if no connected integrations.
	 */
	protected function get_connected_integrations_text() {

		$names = [];

		foreach ( Plugin::get( IntegrationRegistry::class )->get_all() as $integration ) {
			if ( $integration->is_enabled() ) {
				$names[] = esc_html( $integration->get_name() );
			}
		}

		return $names === [] ? '' : wp_sprintf_l( '%l', $names );
	}
}
