<?php

declare( strict_types=1 );

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

/**
 * Handles admin-side WordPress integration:
 * - Registers the hidden onboarding submenu page
 * - Enqueues onboarding and admin SPA assets
 * - Redirects to onboarding on first activation
 */
class Playard_Admin {

	public function init(): void {
		add_action( 'admin_menu',             [ $this, 'register_pages' ] );
		add_action( 'admin_menu',             [ $this, 'restrict_staff_menu' ], 999 );
		add_action( 'admin_init',             [ $this, 'maybe_redirect_after_activation' ] );
		add_action( 'admin_init',             [ $this, 'redirect_staff_from_wp_pages' ] );
		add_filter( 'login_redirect',         [ $this, 'staff_login_redirect' ], 10, 3 );
		add_filter( 'show_admin_bar',         [ $this, 'staff_hide_admin_bar' ] );
		add_action( 'admin_enqueue_scripts',  [ $this, 'enqueue_assets' ] );
		add_action( 'admin_body_class',       [ $this, 'add_body_class' ] );
		add_action( 'in_admin_header',        [ $this, 'strip_foreign_admin_notices' ], 0 );
		add_filter( 'script_loader_tag',      [ $this, 'add_module_type' ], 10, 2 );
		add_action( 'admin_head',             [ $this, 'menu_icon_style' ] );
	}

	/**
	 * Constrain the custom PNG menu icon so it fits the WP sidebar row.
	 * Runs on every admin page (the menu is global), not just Playard screens.
	 */
	public function menu_icon_style(): void {
		echo '<style>'
			. '#adminmenu #toplevel_page_playard .wp-menu-image img{width:20px;height:20px;object-fit:contain;padding:5px 2px 0 8px;opacity:1;box-sizing:content-box;}'
			. '#adminmenu #toplevel_page_playard div.wp-menu-image{float:left;width:32px;height:32px;margin:0;text-align:center;}'
			. '</style>';
	}

	public function maybe_redirect_after_activation(): void {
		if ( ! get_transient( 'playard_activation_redirect' ) ) {
			return;
		}
		delete_transient( 'playard_activation_redirect' );

		// Don't redirect on bulk plugin activation.
		if ( isset( $_GET['activate-multi'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			return;
		}

		wp_safe_redirect( admin_url( 'admin.php?page=playard' ) );
		exit;
	}

	// -------------------------------------------------------------------------
	// Page Registration
	// -------------------------------------------------------------------------

	public function register_pages(): void {
		// Main Playard admin menu
		$menu_label = apply_filters( 'playard_is_pro', false )
			? __( 'Playard Pro', 'playard' )
			: __( 'Playard', 'playard' );

		add_menu_page(
			$menu_label,
			$menu_label,
			'playard_staff',
			'playard',
			[ $this, 'render_admin_app' ],
			PLAYARD_URL . 'assets/images/playard-wp-icon.png',
			58
		);

		// Submenus — all render the same Vue SPA; routing is handled client-side.
		// The first entry (same slug as parent) renames the parent item in the submenu list.
		add_submenu_page( 'playard', __( 'Dashboard',  'playard' ), __( 'Dashboard',  'playard' ), 'playard_staff',  'playard',           [ $this, 'render_admin_app' ] );
		add_submenu_page( 'playard', __( 'Bookings',   'playard' ), __( 'Bookings',   'playard' ), 'playard_staff',  'playard-bookings',  [ $this, 'render_admin_app' ] );
		add_submenu_page( 'playard', __( 'Customers',  'playard' ), __( 'Customers',  'playard' ), 'playard_staff',  'playard-customers', [ $this, 'render_admin_app' ] );
		add_submenu_page( 'playard', __( 'Fields',     'playard' ), __( 'Fields',     'playard' ), 'playard_admin',  'playard-fields',    [ $this, 'render_admin_app' ] );

		if ( apply_filters( 'playard_addon_coupon_enabled', false ) ) {
			add_submenu_page( 'playard', __( 'Coupons', 'playard' ), __( 'Coupons', 'playard' ), 'playard_admin', 'playard-coupons', [ $this, 'render_admin_app' ] );
		}

		add_submenu_page( 'playard', __( 'Facility',   'playard' ), __( 'Facility',   'playard' ), 'playard_admin',  'playard-facility',  [ $this, 'render_admin_app' ] );
		add_submenu_page( 'playard', __( 'Reports',    'playard' ), __( 'Reports',    'playard' ), 'playard_admin',  'playard-reports',   [ $this, 'render_admin_app' ] );
		add_submenu_page( 'playard', __( 'Settings',   'playard' ), __( 'Settings',   'playard' ), 'playard_admin',  'playard-settings',  [ $this, 'render_admin_app' ] );

		// Hidden page — no parent = not shown in admin menu
		add_submenu_page(
			null,
			__( 'Playard Setup', 'playard' ),
			__( 'Playard Setup', 'playard' ),
			'manage_options',
			'playard-onboarding',
			[ $this, 'render_onboarding' ]
		);

		do_action( 'playard_register_admin_pages' );
	}

	public function render_admin_app(): void {
		if ( ! current_user_can( 'playard_staff' ) && ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'You do not have permission to access this page.', 'playard' ) );
		}

		$page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		if ( $page === 'playard' && ! get_option( 'playard_onboarding_complete' ) ) {
			remove_all_actions( 'admin_notices' );
			do_action( 'playard_before_onboarding_page' );
			include PLAYARD_PATH . 'admin/views/onboarding.php';
			do_action( 'playard_after_onboarding_page' );
			return;
		}

		do_action( 'playard_before_admin_app' );
		include PLAYARD_PATH . 'admin/views/app.php';
		do_action( 'playard_after_admin_app' );
	}

	public function render_onboarding(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'You do not have permission to access this page.', 'playard' ) );
		}

		remove_all_actions( 'admin_notices' );

		do_action( 'playard_before_onboarding_page' );
		include PLAYARD_PATH . 'admin/views/onboarding.php';
		do_action( 'playard_after_onboarding_page' );
	}

	// -------------------------------------------------------------------------
	// Admin Notices
	// -------------------------------------------------------------------------

	/**
	 * Remove all third-party admin notices on Playard admin pages.
	 *
	 * Fires on `in_admin_header`, before WordPress outputs the notice hooks,
	 * so foreign plugin notices (license prompts, update nags, etc.) never
	 * render inside the Playard SPA or onboarding screen.
	 */
	public function strip_foreign_admin_notices(): void {
		$page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended

		if ( false === strpos( $page, 'playard' ) ) {
			return;
		}

		remove_all_actions( 'admin_notices' );
		remove_all_actions( 'all_admin_notices' );
		remove_all_actions( 'user_admin_notices' );
		remove_all_actions( 'network_admin_notices' );
	}

	// -------------------------------------------------------------------------
	// Body Class
	// -------------------------------------------------------------------------

	public function add_body_class( string $classes ): string {
		$page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended

		if ( false !== strpos( $page, 'playard' ) ) {
			$classes .= ' playard-admin';
		}

		return $classes;
	}

	// -------------------------------------------------------------------------
	// Asset Enqueuing
	// -------------------------------------------------------------------------

	public function enqueue_assets( string $hook ): void {
		$page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended

		if ( $page === 'playard-onboarding' ) {
			$this->enqueue_onboarding_assets();
			return;
		}

		// Main admin SPA — loaded when other Playard pages are active
		if ( false !== strpos( $hook, 'playard' ) ) {
			if ( $page === 'playard' && ! get_option( 'playard_onboarding_complete' ) ) {
				$this->enqueue_onboarding_assets();
			} else {
				$this->enqueue_admin_spa_assets();
			}
		}
	}

	private function enqueue_onboarding_assets(): void {
		wp_register_style( 'playard-onboarding-base', false, [], PLAYARD_VERSION ); // phpcs:ignore
		wp_enqueue_style( 'playard-onboarding-base' );

		// Compiled Vite CSS (only if built)
		if ( file_exists( PLAYARD_PATH . 'assets/css/playard-onboarding.css' ) ) {
			wp_enqueue_style(
				'playard-onboarding',
				PLAYARD_URL . 'assets/css/playard-onboarding.css',
				[ 'playard-onboarding-base' ],
				PLAYARD_VERSION
			);
		}

		// Compiled Vite JS (only if built)
		if ( file_exists( PLAYARD_PATH . 'assets/js/playard-onboarding.js' ) ) {
			wp_enqueue_script(
				'playard-onboarding',
				PLAYARD_URL . 'assets/js/playard-onboarding.js',
				[],
				PLAYARD_VERSION,
				true
			);

			$settings = (array) get_option( 'playard_settings', [] );

			wp_localize_script(
				'playard-onboarding',
				'playard_onboarding',
				apply_filters( 'playard_onboarding_script_data', [
					'rest_url'      => esc_url_raw( rest_url( 'playard/v1/' ) ),
					'nonce'         => wp_create_nonce( 'wp_rest' ),
					'booking_url'   => playard_get_booking_url(),
					'site_url'      => home_url( '/' ),
					'logo_url'      => PLAYARD_URL . 'assets/images/playard-logo.webp',
					'currency'      => (string) ( is_string( $settings['currency'] ?? null ) ? $settings['currency'] : 'USD' ),
					'facility_id'   => playard_get_facility_id(),
					'is_complete'   => (bool) get_option( 'playard_onboarding_complete', false ),
				] )
			);
		}

		do_action( 'playard_enqueue_onboarding_assets' );
	}

	private function enqueue_admin_spa_assets(): void {
		// Load WordPress media library scripts for wp.media() uploads
		wp_enqueue_media();

		if ( file_exists( PLAYARD_PATH . 'assets/css/playard-admin.css' ) ) {
			wp_enqueue_style(
				'playard-admin',
				PLAYARD_URL . 'assets/css/playard-admin.css',
				[],
				(string) filemtime( PLAYARD_PATH . 'assets/css/playard-admin.css' )
			);
		}

		if ( file_exists( PLAYARD_PATH . 'assets/js/playard-admin.js' ) ) {
			wp_enqueue_script(
				'playard-admin',
				PLAYARD_URL . 'assets/js/playard-admin.js',
				[],
				(string) filemtime( PLAYARD_PATH . 'assets/js/playard-admin.js' ),
				true
			);

			if ( $this->is_pure_staff() ) {
				wp_add_inline_style( 'playard-admin',
					'#wpadminbar,#adminmenuwrap,#adminmenuback,#wpfooter{display:none!important}'
					. ' html.wp-toolbar{padding-top:0!important}'
					. ' #wpcontent,#wpbody{margin-left:0!important}'
					. ' #wpcontent{padding-left:0!important}'
					. ' #wpbody-content{padding-bottom:0!important}'
				);
			} else {
				wp_add_inline_style( 'playard-admin', '#wpcontent{padding-left:0!important}' );
			}

			wp_localize_script(
				'playard-admin',
				'playard_admin',
				apply_filters( 'playard_admin_script_data', [
					'rest_url'           => esc_url_raw( rest_url( 'playard/v1/' ) ),
					'nonce'              => wp_create_nonce( 'wp_rest' ),
					'version'            => PLAYARD_VERSION,
					'logo_url'           => PLAYARD_URL . 'assets/images/playard-logo.webp',
					'facility_id'        => playard_get_facility_id(),
					'site_timezone'      => ( static function (): string {
						$facility = playard_get_facility();
						$tz       = $facility ? trim( (string) ( $facility->timezone ?? '' ) ) : '';
						return $tz ?: wp_timezone_string();
					} )(),
					'currency_symbol'    => ( static function (): string {
						$settings     = (array) get_option( 'playard_settings', [] );
						$currency_sub = is_array( $settings['currency'] ?? null ) ? $settings['currency'] : [];
						$code         = (string) ( $currency_sub['currency'] ?? '' );
						if ( ! $code ) {
							$facility = playard_get_facility();
							$code     = $facility ? (string) $facility->currency : 'USD';
						}
						return playard_get_currency_symbol( $code );
					} )(),
					'time_format'        => ( static function (): string {
						$settings = (array) get_option( 'playard_settings', [] );
						return isset( $settings['time_format'] ) && $settings['time_format'] === '24h' ? '24h' : '12h';
					} )(),
					'user_display_name'  => wp_get_current_user()->display_name,
					'user_caps'          => [
						'is_admin' => current_user_can( 'playard_admin' ) || current_user_can( 'manage_options' ),
						'is_staff' => current_user_can( 'playard_staff' ) || current_user_can( 'manage_options' ),
					],
					'logout_url'         => wp_logout_url( admin_url( 'admin.php?page=playard' ) ),
					'portal_url'         => playard_get_portal_url(),
					'stripe_enabled'         => ( new Playard_Payment() )->is_stripe_configured(),
					'stripe_publishable_key' => ( new Playard_Payment() )->get_stripe_publishable_key(),
				] )
			);
		}

		do_action( 'playard_enqueue_admin_spa_assets' );
	}

	// -------------------------------------------------------------------------
	// ES Module support
	// -------------------------------------------------------------------------

	/**
	 * Adds type="module" to Vite-built scripts so the browser loads them as ES modules.
	 * Without this, the browser silently ignores the import statements in the bundle.
	 *
	 * @param string $tag    Full <script> HTML tag.
	 * @param string $handle Script handle.
	 * @return string
	 */
	public function add_module_type( string $tag, string $handle ): string {
		$module_handles = [ 'playard-admin', 'playard-onboarding', 'playard-frontend' ];

		if ( ! in_array( $handle, $module_handles, true ) ) {
			return $tag;
		}

		// Replace type="text/javascript" if present, otherwise inject type="module"
		if ( str_contains( $tag, "type='text/javascript'" ) ) {
			return str_replace( "type='text/javascript'", "type='module'", $tag );
		}
		if ( str_contains( $tag, 'type="text/javascript"' ) ) {
			return str_replace( 'type="text/javascript"', 'type="module"', $tag );
		}

		return str_replace( '<script ', '<script type="module" ', $tag );
	}

	// -------------------------------------------------------------------------
	// Staff UX — clean sidebar + redirects
	// -------------------------------------------------------------------------

	private function is_pure_staff(): bool {
		return current_user_can( 'playard_staff' ) && ! current_user_can( 'manage_options' );
	}

	public function staff_hide_admin_bar( bool $show ): bool {
		return $this->is_pure_staff() ? false : $show;
	}

	public function restrict_staff_menu(): void {
		if ( ! $this->is_pure_staff() ) {
			return;
		}

		$remove = [
			'index.php',
			'edit.php',
			'upload.php',
			'edit.php?post_type=page',
			'edit-comments.php',
			'themes.php',
			'plugins.php',
			'users.php',
			'tools.php',
			'options-general.php',
			'profile.php',
		];

		foreach ( $remove as $slug ) {
			remove_menu_page( $slug );
		}
	}

	public function redirect_staff_from_wp_pages(): void {
		if ( ! $this->is_pure_staff() ) {
			return;
		}

		$page   = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$script = isset( $_SERVER['PHP_SELF'] ) ? basename( sanitize_text_field( wp_unslash( $_SERVER['PHP_SELF'] ) ) ) : '';

		// Only these Playard pages are accessible to staff
		$staff_pages = [ 'playard', 'playard-bookings', 'playard-customers' ];

		if ( $page && in_array( $page, $staff_pages, true ) ) {
			return;
		}

		// Allow profile page so staff can change their own password
		if ( $script === 'profile.php' ) {
			return;
		}

		// Redirect everything else (WP dashboard, admin-only Playard pages, etc.) to Playard
		wp_safe_redirect( admin_url( 'admin.php?page=playard' ) );
		exit;
	}

	/**
	 * @param string          $redirect_to           The redirect destination.
	 * @param string          $requested_redirect_to The requested redirect destination.
	 * @param WP_User|WP_Error $user                 WP_User object or WP_Error on login failure.
	 */
	public function staff_login_redirect( string $redirect_to, string $requested_redirect_to, WP_User|WP_Error $user ): string {
		if ( is_wp_error( $user ) ) {
			return $redirect_to;
		}
		if ( $user->has_cap( 'playard_staff' ) && ! $user->has_cap( 'manage_options' ) ) {
			return admin_url( 'admin.php?page=playard' );
		}
		return $redirect_to;
	}
}
