<?php
/**
 * Single top-level WrenchPress admin menu registrar (D-01).
 *
 * Owns the one parent menu and every plugin submenu so the information
 * architecture stays consolidated under a single WrenchPress entry rather than
 * a scattered set of top-level menus. Each submenu passes the screen's own
 * required capability as the 4th argument, so a mechanic sees only the items
 * its role permits (T-03-05). The write-on-load handlers that the old per-page
 * register_menu methods wired are preserved here by capturing each
 * add_submenu_page() hook suffix and re-binding load-{hook} to the page's
 * handle_load callback.
 *
 * The Vehicles and Work Orders submenus are registered conditionally (guarded
 * by class_exists) so this plan can load cleanly before those feature slices
 * land; each slice fills its reserved slot when its admin page class exists.
 *
 * @package WrenchPress
 */

defined( 'ABSPATH' ) || exit;

/**
 * Class WrenchPress_Admin_Menu
 */
class WrenchPress_Admin_Menu {

	/**
	 * Slug of the single top-level parent menu. The Dashboard submenu reuses this
	 * exact slug so it becomes the default landing item and the auto-duplicated
	 * parent label is suppressed.
	 */
	const PARENT_SLUG = 'wrenchpress';

	/**
	 * Register the parent menu and every submenu on admin_menu.
	 *
	 * The parent uses VIEW_CUSTOMERS, a capability all three staff roles hold
	 * (including the mechanic), so the WrenchPress menu renders for everyone who
	 * works the CRM. Per-submenu capabilities then gate what each role sees
	 * inside it.
	 *
	 * @return void
	 */
	public static function register() {
		add_menu_page(
			__( 'PitDesk', 'pitdesk-repair-crm' ),
			__( 'PitDesk', 'pitdesk-repair-crm' ),
			WrenchPress_Capabilities::VIEW_CUSTOMERS,
			self::PARENT_SLUG,
			array( 'WrenchPress_Dashboard_Page', 'render' ),
			'dashicons-clipboard',
			26
		);

		// Dashboard: slug equals PARENT_SLUG so it is the default landing item and
		// the duplicated parent label is suppressed.
		add_submenu_page(
			self::PARENT_SLUG,
			__( 'Dashboard', 'pitdesk-repair-crm' ),
			__( 'Dashboard', 'pitdesk-repair-crm' ),
			WrenchPress_Capabilities::VIEW_CUSTOMERS,
			self::PARENT_SLUG,
			array( 'WrenchPress_Dashboard_Page', 'render' )
		);

		// Customers: viewable by all staff roles including the mechanic (D-22).
		$customers_hook = add_submenu_page(
			self::PARENT_SLUG,
			__( 'Customers', 'pitdesk-repair-crm' ),
			__( 'Customers', 'pitdesk-repair-crm' ),
			WrenchPress_Capabilities::VIEW_CUSTOMERS,
			WrenchPress_Customers_Admin_Page::MENU_SLUG,
			array( 'WrenchPress_Customers_Admin_Page', 'render' )
		);

		if ( $customers_hook ) {
			add_action( 'load-' . $customers_hook, array( 'WrenchPress_Customers_Admin_Page', 'handle_load' ) );
		}

		// Leads: triage surface, gated to manage-leads (mechanic excluded).
		$leads_hook = add_submenu_page(
			self::PARENT_SLUG,
			__( 'Leads', 'pitdesk-repair-crm' ),
			__( 'Leads', 'pitdesk-repair-crm' ),
			WrenchPress_Capabilities::MANAGE_LEADS,
			WrenchPress_Leads_Admin_Page::MENU_SLUG,
			array( 'WrenchPress_Leads_Admin_Page', 'render' )
		);

		if ( $leads_hook ) {
			add_action( 'load-' . $leads_hook, array( 'WrenchPress_Leads_Admin_Page', 'handle_load' ) );
		}

		// Vehicles: filled by its own slice. Guarded so this plan loads first.
		if ( class_exists( 'WrenchPress_Vehicles_Admin_Page' ) ) {
			$vehicles_hook = add_submenu_page(
				self::PARENT_SLUG,
				__( 'Vehicles', 'pitdesk-repair-crm' ),
				__( 'Vehicles', 'pitdesk-repair-crm' ),
				WrenchPress_Capabilities::VIEW_VEHICLES,
				'wrenchpress-vehicles',
				array( 'WrenchPress_Vehicles_Admin_Page', 'render' )
			);

			$vehicles_load = array( 'WrenchPress_Vehicles_Admin_Page', 'handle_load' );
			if ( $vehicles_hook && is_callable( $vehicles_load ) ) {
				add_action( 'load-' . $vehicles_hook, $vehicles_load );
			}
		}

		// Work Orders: all staff (incl. mechanic) can view; writes gated by finer
		// caps inside the page. Filled by its own slice; guarded.
		if ( class_exists( 'WrenchPress_Work_Orders_Admin_Page' ) ) {
			$work_orders_hook = add_submenu_page(
				self::PARENT_SLUG,
				__( 'Work Orders', 'pitdesk-repair-crm' ),
				__( 'Work Orders', 'pitdesk-repair-crm' ),
				WrenchPress_Capabilities::VIEW_VEHICLES,
				'wrenchpress-work-orders',
				array( 'WrenchPress_Work_Orders_Admin_Page', 'render' )
			);

			$work_orders_load = array( 'WrenchPress_Work_Orders_Admin_Page', 'handle_load' );
			if ( $work_orders_hook && is_callable( $work_orders_load ) ) {
				add_action( 'load-' . $work_orders_hook, $work_orders_load );
			}
		}

		// Reminders: the service follow-up worklist, gated to manage-reminders
		// (mechanic excluded). Mirrors the Leads submenu: capture the hook and
		// re-bind load-{hook} to the page's row-action handler.
		$reminders_hook = add_submenu_page(
			self::PARENT_SLUG,
			__( 'Reminders', 'pitdesk-repair-crm' ),
			__( 'Reminders', 'pitdesk-repair-crm' ),
			WrenchPress_Capabilities::MANAGE_REMINDERS,
			WrenchPress_Reminders_Admin_Page::MENU_SLUG,
			array( 'WrenchPress_Reminders_Admin_Page', 'render' )
		);

		if ( $reminders_hook ) {
			add_action( 'load-' . $reminders_hook, array( 'WrenchPress_Reminders_Admin_Page', 'handle_load' ) );
		}

		// Appointments: the FullCalendar island host. All staff (incl. mechanic)
		// with view capability see the calendar; writes are manage-gated inside the
		// REST layer. The page class ships this phase, so the guard just matches the
		// surrounding conditional style.
		if ( class_exists( 'WrenchPress_Appointments_Admin_Page' ) ) {
			add_submenu_page(
				self::PARENT_SLUG,
				__( 'Appointments', 'pitdesk-repair-crm' ),
				__( 'Appointments', 'pitdesk-repair-crm' ),
				WrenchPress_Capabilities::VIEW_APPOINTMENTS,
				WrenchPress_Appointments_Admin_Page::MENU_SLUG,
				array( 'WrenchPress_Appointments_Admin_Page', 'render' )
			);
		}

		// Settings: repointed under the parent (D-01); gated to manage-leads.
		add_submenu_page(
			self::PARENT_SLUG,
			__( 'PitDesk Settings', 'pitdesk-repair-crm' ),
			__( 'Settings', 'pitdesk-repair-crm' ),
			WrenchPress_Capabilities::MANAGE_LEADS,
			WrenchPress_Settings_Page::PAGE,
			array( 'WrenchPress_Settings_Page', 'render' )
		);
	}

	/**
	 * Page slugs that belong to this plugin. The shared admin stylesheet is only
	 * enqueued on these screens so it never loads site-wide.
	 *
	 * @return string[]
	 */
	public static function page_slugs() {
		return array(
			self::PARENT_SLUG,
			WrenchPress_Customers_Admin_Page::MENU_SLUG,
			WrenchPress_Leads_Admin_Page::MENU_SLUG,
			'wrenchpress-vehicles',
			'wrenchpress-work-orders',
			WrenchPress_Reminders_Admin_Page::MENU_SLUG,
			WrenchPress_Appointments_Admin_Page::MENU_SLUG,
			WrenchPress_Settings_Page::PAGE,
		);
	}

	/**
	 * Conditionally enqueue the shared admin assets on plugin screens only.
	 *
	 * Hooked on admin_enqueue_scripts. The $hook_suffix carries the current admin
	 * page; for a top-level menu it is 'toplevel_page_wrenchpress' and for each
	 * submenu it is 'wrenchpress_page_{slug}'. We match against the current
	 * screen id and the known page slugs so the badge styles load only where a
	 * status badge can appear, never across all of wp-admin (D-19).
	 *
	 * Both scripts hang off this same gate and inherit it for free. They declare
	 * wp-a11y because they speak through wp.a11y.speak(); core already loads that
	 * handle as a dependency of `common` on every admin screen, but declaring it
	 * is what makes the dependency true rather than merely lucky.
	 *
	 * @param string $hook_suffix Current admin page hook suffix.
	 * @return void
	 */
	public static function enqueue_admin_assets( $hook_suffix ) {
		$hook_suffix = (string) $hook_suffix;
		$is_plugin   = false;

		foreach ( self::page_slugs() as $slug ) {
			if ( false !== strpos( $hook_suffix, $slug ) ) {
				$is_plugin = true;
				break;
			}
		}

		if ( ! $is_plugin ) {
			return;
		}

		$admin_css = WRENCHPRESS_PATH . 'assets/css/wrenchpress-admin.css';
		wp_enqueue_style(
			'wrenchpress-admin',
			WRENCHPRESS_URL . 'assets/css/wrenchpress-admin.css',
			array(),
			file_exists( $admin_css ) ? (string) filemtime( $admin_css ) : false
		);

		$dialog_js = WRENCHPRESS_PATH . 'assets/js/wrenchpress-dialog.js';
		wp_enqueue_script(
			'wrenchpress-dialog',
			WRENCHPRESS_URL . 'assets/js/wrenchpress-dialog.js',
			array( 'wp-a11y' ),
			file_exists( $dialog_js ) ? (string) filemtime( $dialog_js ) : false,
			true
		);

		$a11y_js = WRENCHPRESS_PATH . 'assets/js/wrenchpress-a11y.js';
		wp_enqueue_script(
			'wrenchpress-a11y',
			WRENCHPRESS_URL . 'assets/js/wrenchpress-a11y.js',
			array( 'wp-a11y' ),
			file_exists( $a11y_js ) ? (string) filemtime( $a11y_js ) : false,
			true
		);
	}
}
