<?php
/**
 * Admin screen registry.
 *
 * @package ScheduledChanges
 */

namespace ScheduledChanges\Admin;

use ScheduledChanges\Capabilities\CapabilityManager;
use ScheduledChanges\Extension\BundledModuleIds;

/** Keeps the neutral admin shell independent from feature screen names. */
final class AdminScreenRegistry {
	/** @var array<string,array<string,string>> */
	private array $screens;
	/** @var string[] */
	private array $module_ids;
	private bool $filters_applied = false;

	/**
	 * @param array<string,array<string,string>> $screens Screen definitions.
	 * @param string[]                           $module_ids Selected module IDs.
	 */
	public function __construct( array $screens, array $module_ids = array() ) {
		$this->screens    = $screens;
		$this->module_ids = $module_ids;
	}

	/**
	 * Creates the built-in registrations selected by active modules.
	 *
	 * @param string[] $module_ids Active module IDs.
	 */
	public static function forModules( array $module_ids ): self {
		$selected = static fn ( string $id ): bool => in_array( $id, $module_ids, true );
		$screens  = array();

		$product_admin_selected = $selected( BundledModuleIds::ADMIN_READ_ONLY )
			|| $selected( BundledModuleIds::ADMIN_SCHEDULE )
			|| $selected( BundledModuleIds::ADMIN_RECORDING )
			|| $selected( BundledModuleIds::ADMIN_RUN_HISTORY )
			|| $selected( BundledModuleIds::ADMIN_MODULES );

		if ( $selected( BundledModuleIds::ADMIN_SHELL ) && ! $product_admin_selected ) {
			$screens['schedule-center'] = self::screen( 'jjs-scheduler', 'JJ\'s Post and Product Scheduler', 'Overview', CapabilityManager::VIEW_SCHEDULES );
		}

		if ( $selected( BundledModuleIds::ADMIN_READ_ONLY ) ) {
			$screens['schedule-center'] = self::screen( 'jjs-scheduler', 'JJ\'s Post and Product Scheduler', 'Overview', CapabilityManager::VIEW_SCHEDULES );
			$screens['all-changes']     = self::screen( 'jjs-scheduler-list', 'JJ\'s Post and Product Scheduler', 'Schedules', CapabilityManager::VIEW_SCHEDULES );
		}
		if ( $selected( BundledModuleIds::ADMIN_SCHEDULE ) ) {
			$screens['schedule-center'] = self::screen( 'jjs-scheduler', 'JJ\'s Post and Product Scheduler', 'Overview', CapabilityManager::VIEW_SCHEDULES );
			$screens['all-changes']     = self::screen( 'jjs-scheduler-list', 'JJ\'s Post and Product Scheduler', 'Schedules', CapabilityManager::VIEW_SCHEDULES );
			$screens['calendar']        = self::screen( 'jjs-scheduler-calendar', 'JJ\'s Post and Product Scheduler Calendar', 'Calendar', CapabilityManager::VIEW_SCHEDULES );
		}
		if ( $selected( BundledModuleIds::ADMIN_RECORDING ) ) {
			$screens['recordings'] = self::screen( 'jjs-scheduler-record', 'Record a Change', 'Record a Change', CapabilityManager::VIEW_SCHEDULES );
		}
		if ( $selected( BundledModuleIds::ADMIN_RUN_HISTORY ) ) {
			$screens['runs-logs'] = self::screen( 'jjs-scheduler-history', 'JJ\'s Post and Product Scheduler History', 'History', CapabilityManager::VIEW_LOGS );
		}
		if ( $selected( BundledModuleIds::ADMIN_MODULES ) ) {
			$screens['modules'] = self::screen( 'jjs-scheduler-addons', 'JJ\'s Post and Product Scheduler Addons', 'Addons', CapabilityManager::VIEW_SCHEDULES );
		}

		return new self( $screens, $module_ids );
	}

	/** @return array<string,array<string,string>> */
	public function all(): array {
		return array_map( array( self::class, 'translateScreen' ), $this->filteredScreens() );
	}

	/** Returns the first registered screen. */
	public function primaryId(): string {
		return (string) array_key_first( $this->filteredScreens() );
	}

	/** @return array<string,string> */
	private static function screen( string $slug, string $page_title, string $menu_title, string $capability ): array {
		return array(
			'slug'       => $slug,
			'pageTitle'  => $page_title,
			'menuTitle'  => $menu_title,
			'capability' => $capability,
		);
	}

	/** @return array<string,array<string,string>> */
	private function filteredScreens(): array {
		if ( $this->filters_applied ) {
			return $this->screens;
		}

		/** Filters declarative screen registrations contributed by active modules. */
		$filtered = apply_filters( 'scheduled_changes_admin_screens', $this->screens, $this->module_ids );

		$this->screens         = is_array( $filtered ) ? $filtered : $this->screens;
		$this->filters_applied = true;

		return $this->screens;
	}

	/**
	 * @param array<string,string> $screen Screen definition.
	 * @return array<string,string>
	 */
	private static function translateScreen( array $screen ): array {
		$screen['pageTitle'] = self::translateLabel( (string) ( $screen['pageTitle'] ?? '' ) );
		$screen['menuTitle'] = self::translateLabel( (string) ( $screen['menuTitle'] ?? '' ) );

		return $screen;
	}

	/** Translates built-in screen labels while preserving extension-provided labels. */
	private static function translateLabel( string $label ): string {
		switch ( $label ) {
			case 'JJ\'s Post and Product Scheduler':
				return __( 'JJ\'s Post and Product Scheduler', 'jjs-post-scheduler' );
			case 'Overview':
				return __( 'Overview', 'jjs-post-scheduler' );
			case 'Schedules':
				return __( 'Schedules', 'jjs-post-scheduler' );
			case 'Schedule Center':
				return __( 'Schedule Center', 'jjs-post-scheduler' );
			case 'JJ\'s Post and Product Scheduler Calendar':
				return __( 'JJ\'s Post and Product Scheduler Calendar', 'jjs-post-scheduler' );
			case 'Calendar':
				return __( 'Calendar', 'jjs-post-scheduler' );
			case 'Record a Change':
				return __( 'Record a Change', 'jjs-post-scheduler' );
			case 'JJ\'s Post and Product Scheduler History':
				return __( 'JJ\'s Post and Product Scheduler History', 'jjs-post-scheduler' );
			case 'History':
				return __( 'History', 'jjs-post-scheduler' );
			case 'JJ\'s Post and Product Scheduler Addons':
				return __( 'JJ\'s Post and Product Scheduler Addons', 'jjs-post-scheduler' );
			case 'Addons':
				return __( 'Addons', 'jjs-post-scheduler' );
			default:
				return $label;
		}
	}
}
