<?php
/**
 * Describes which parts of the site maintenance affects (admin confirmations).
 *
 * @package MacaHold
 */

defined( 'ABSPATH' ) || exit;

/**
 * Maintenance scope summaries for toggle confirmations.
 */
class Maca_Hold_Maintenance_Scope {

	/**
	 * Resolve maintenance scope after a toggle change.
	 *
	 * @param bool $enabled_after Whether manual maintenance will be enabled.
	 * @return array{effect: string, page_titles: array<int, string>}
	 */
	public static function resolve( $enabled_after ) {
		$scope = array(
			'effect'      => $enabled_after ? 'whole_site' : 'whole_site_public',
			'page_titles' => array(),
		);

		/**
		 * Filter maintenance scope used in admin toggle confirmations.
		 *
		 * @param array{effect: string, page_titles: array<int, string>} $scope        Scope data.
		 * @param bool                                                    $enabled_after Whether manual maintenance will be enabled.
		 */
		return apply_filters( 'maca_hold_maintenance_scope', $scope, (bool) $enabled_after );
	}

	/**
	 * Current maintenance scope for admin status text.
	 *
	 * @return array{effect: string, page_titles: array<int, string>}
	 */
	public static function get_display_scope() {
		if ( Maca_Hold_Settings::is_active() ) {
			return self::resolve( true );
		}

		return array(
			'effect'      => 'whole_site_public',
			'page_titles' => array(),
		);
	}

	/**
	 * Whether any maintenance is visible to visitors (global or per-page).
	 *
	 * @return bool
	 */
	public static function is_maintenance_visible() {
		return Maca_Hold_Settings::is_active();
	}

	/**
	 * Status line under the maintenance switch.
	 *
	 * @param array{effect: string, page_titles: array<int, string>}|null $scope Optional scope.
	 * @return string
	 */
	public static function get_status_text( $scope = null ) {
		$scope = is_array( $scope ) ? $scope : self::get_display_scope();
		$effect = $scope['effect'] ?? 'whole_site_public';
		$pages  = $scope['page_titles'] ?? array();

		if ( self::is_page_scope( $effect ) ) {
			if ( 1 === count( $pages ) ) {
				return sprintf(
					/* translators: %s: page title */
					__( 'The page "%s" is under maintenance.', 'maca-hold' ),
					$pages[0]
				);
			}

			return __( 'Selected pages are under maintenance.', 'maca-hold' );
		}

		if ( Maca_Hold_Settings::is_active() ) {
			if ( 'all_except_pages' === $effect ) {
				return __( 'Maintenance mode is active. Visitors receive HTTP 503 on most pages.', 'maca-hold' );
			}

			return __( 'Maintenance mode is active. Visitors receive HTTP 503.', 'maca-hold' );
		}

		return __( 'Maintenance mode is inactive. The site is public.', 'maca-hold' );
	}

	/**
	 * Short label for the admin bar lamp.
	 *
	 * @return string
	 */
	public static function get_admin_bar_status_text() {
		$scope = self::get_display_scope();

		if ( self::is_page_scope( $scope['effect'] ?? '' ) ) {
			return __( 'Pages under maintenance', 'maca-hold' );
		}

		if ( Maca_Hold_Settings::is_active() ) {
			return __( 'Maintenance active', 'maca-hold' );
		}

		return __( 'Site public', 'maca-hold' );
	}

	/**
	 * Confirmation messages for enable/disable toggle.
	 *
	 * @return array{enable: string, disable: string}
	 */
	public static function get_toggle_confirm_messages() {
		return array(
			'enable'  => self::format_enable_message( self::resolve( true ) ),
			'disable' => self::format_disable_message( self::resolve( false ) ),
		);
	}

	/**
	 * Flash message after a successful toggle.
	 *
	 * @param bool $enabled_after Whether manual maintenance was enabled.
	 * @return string
	 */
	public static function get_toggle_feedback_message( $enabled_after ) {
		$scope = self::resolve( $enabled_after );

		if ( $enabled_after && 'selected_pages' === ( $scope['effect'] ?? '' ) ) {
			return __( 'Selected pages are now under maintenance.', 'maca-hold' );
		}

		if ( $enabled_after ) {
			return __( 'Maintenance mode activated.', 'maca-hold' );
		}

		return __( 'Maintenance mode deactivated. The site is public.', 'maca-hold' );
	}

	/**
	 * @param string $effect Scope effect slug.
	 * @return bool
	 */
	private static function is_page_scope( $effect ) {
		return 'selected_pages' === $effect;
	}

	/**
	 * @param array{effect: string, page_titles: array<int, string>} $scope Scope data.
	 * @return string
	 */
	private static function format_enable_message( array $scope ) {
		$page_list = self::format_page_list( $scope['page_titles'] ?? array() );

		switch ( $scope['effect'] ?? 'whole_site' ) {
			case 'selected_pages':
				if ( '' === $page_list ) {
					return __( 'Activate maintenance mode? Only the selected pages will show maintenance. Other pages stay open.', 'maca-hold' );
				}

				return sprintf(
					/* translators: %s: bullet list of page titles */
					__( "Activate maintenance mode?\n\nOnly these pages will show maintenance:\n%s\n\nOther pages stay open.", 'maca-hold' ),
					$page_list
				);

			case 'all_except_pages':
				if ( '' === $page_list ) {
					return __( 'Activate maintenance mode? The entire site except the selected pages will show maintenance. Visitors receive HTTP 503 on those pages.', 'maca-hold' );
				}

				return sprintf(
					/* translators: %s: bullet list of page titles */
					__( "Activate maintenance mode?\n\nThe entire site except these pages will show maintenance:\n%s\n\nVisitors receive HTTP 503 on all other pages.", 'maca-hold' ),
					$page_list
				);

			default:
				return __( "Activate maintenance mode?\n\nThe entire site will show maintenance. Visitors receive HTTP 503 until you turn it off.", 'maca-hold' );
		}
	}

	/**
	 * @param array{effect: string, page_titles: array<int, string>} $scope Scope data.
	 * @return string
	 */
	private static function format_disable_message( array $scope ) {
		unset( $scope );

		return __( "Deactivate maintenance mode?\n\nThe entire site becomes public immediately.", 'maca-hold' );
	}

	/**
	 * @param array<int, string> $titles Page titles.
	 * @return string
	 */
	private static function format_page_list( array $titles ) {
		$titles = array_values(
			array_filter(
				array_map(
					static function ( $title ) {
						return trim( (string) $title );
					},
					$titles
				)
			)
		);

		if ( empty( $titles ) ) {
			return '';
		}

		return '• ' . implode( "\n• ", $titles );
	}
}
