<?php
/**
 * Admin menu and page handler.
 *
 * @package PDFDraft
 */

namespace PDFDraft;

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

use PDFDraft\Traits\Hooks;
use PDFDraft\Editor;

/**
 * Manages admin menus and page access.
 */
class Admin {
	use Hooks;

	/**
	 * Editor instance.
	 *
	 * @var Editor
	 */
	private $editor;

	/**
	 * Core settings page slug.
	 *
	 * @var string
	 */
	public const SETTINGS_PAGE_SLUG = 'pdfdraft-settings';

	/**
	 * Constructor.
	 *
	 * @param Editor $editor Editor instance.
	 */
	public function __construct( Editor $editor ) {
		$this->editor = $editor;
	}

	/**
	 * Option key for the active design slug.
	 *
	 * @var string
	 */
	public const ACTIVE_DESIGN_OPTION_KEY = 'pdfdraft_active_design_slug';

	/**
	 * Register admin action hooks.
	 *
	 * @return void
	 */
	public function init() {
		$this->addAction( 'admin_menu', array( $this, 'addMenu' ) );
		$this->addAction( 'admin_footer', array( $this, 'setParentMenuLink' ) );
		$this->addAction( 'admin_enqueue_scripts', array( $this, 'ensureSelectWooCompat' ), 1 );
		$this->addAction( 'admin_enqueue_scripts', array( $this, 'enqueueSettingsPageAssets' ) );
		$this->addAction( 'init', array( $this, 'onInit' ) );
		$this->addFilter( 'pdfdraft_editor_localized_data', array( $this, 'addActiveDesignLocalizedData' ) );
		$this->addAction( 'rest_api_init', array( $this, 'registerActiveDesignRestRoute' ) );
		$this->addAction( 'pdfdraft_after_delete_pdf_design', array( $this, 'onAfterDeletePdfDesign' ) );
	}

	/**
	 * Ensure selectWoo exists for third-party admin scripts (e.g., YITH).
	 *
	 * @return void
	 */
	public function ensureSelectWooCompat(): void {
		$select_woo_stub = "if ( typeof jQuery !== 'undefined' && typeof jQuery.fn.selectWoo !== 'function' ) { jQuery.fn.selectWoo = typeof jQuery.fn.select2 === 'function' ? jQuery.fn.select2 : function() { return this; }; }";
		wp_add_inline_script( 'jquery', $select_woo_stub, 'after' );
	}

	/**
	 * Handle init action for PDFDraft pages.
	 *
	 * @return void
	 */
	public function onInit() {
		if ( ! $this->isPDFDraftPage() ) {
			return;

		}
		if ( ! is_user_logged_in() ) {
			$redirect = admin_url( 'admin.php?page=pdfdraft#/' );
			if ( ! empty( $_GET['for'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
				$redirect = add_query_arg( 'for', sanitize_text_field( wp_unslash( $_GET['for'] ) ), $redirect ); // phpcs:ignore WordPress.Security.NonceVerification.Recommended
			}
			wp_safe_redirect(
				wp_login_url( add_query_arg( 'redirect_to', rawurlencode( $redirect ) ) )
			);
			exit;
		}

		if ( ! current_user_can( 'edit_posts' ) ) {
			wp_die( esc_html__( 'You do not have sufficient permissions to access this page.', 'pdfdraft' ) );
		}

		$this->editor->init();
	}

	/**
	 * Add the PDFDraft admin menu and submenus.
	 *
	 * @return void
	 */
	public function addMenu() {
		add_menu_page(
			__( 'PDFDraft', 'pdfdraft' ),
			__( 'PDFDraft', 'pdfdraft' ),
			'edit_posts',
			'pdfdraft',
			'__return_empty_string',
			'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHZpZXdCb3g9IjAgMCA0MCA0MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48cGF0aCBkPSJNMjIuNSAxMS43OTdjMCAuOTAyLjg0NCAxLjY0IDEuODc1IDEuNjRIMzVWMzUuODZjMCAuOTA5LS44MzYgMS42NC0xLjg3NSAxLjY0aC0yMS4zOGwzLjU1LTUuNzg2cS4xMi0uMjE0LjM1OC0uMzE1YS44Ny44NyAwIDAgMSAuNTExLS4wNDggNy4zIDcuMyAwIDAgMCAzLjQzNS0uMjIgNy4xIDcuMSAwIDAgMCAyLjk1NC0xLjc0OSA2LjggNi44IDAgMCAwIDEuNzU1LTIuODc2IDYuNCA2LjQgMCAwIDAgLjE0Mi0zLjMyMiAxIDEgMCAwIDAtLjQ0My0uNjc2IDEuMTQgMS4xNCAwIDAgMC0uNzc4LS4xNzZxLS40MjMuMDUxLS43MzIuNDA0bC0yLjYyNyAzLjg5OHEtLjM3OS41MDQtMS4wNS41NzFhMS42NSAxLjY1IDAgMCAxLTEuMTk4LS4zMjVsLTIuNTkzLTEuOTQzYTEuNTMgMS41MyAwIDAgMS0uNjIyLTEuMDI2cS0uMDk4LS42My4zMzQtMS4xNy40MzQtLjU0IDEuNjE0LTEuNyAxLjE4LTEuMTYxIDEuNjQyLTEuNzA0LjI3Ni0uMzc4LjIwOC0uNzg0YTEuMTMgMS4xMyAwIDAgMC0uMzg2LS42ODNxLS4zMTctLjI3NS0uNzg3LS4yNDYtMS41Ni4wNzYtMi45NDcuNzc1YTYuOCA2LjggMCAwIDAtMi4zMjcgMS45MDIgNi43IDYuNyAwIDAgMC0xLjQyNiAzLjQ2NSA2LjcgNi43IDAgMCAwIC42MSAzLjY0NS45NS45NSAwIDAgMSAuMDUuNDk1LjcuNyAwIDAgMS0uMjI3LjQxM0w1IDMzLjkxMVY0LjE0MUM1IDMuMjMgNS44MzYgMi41IDYuODc1IDIuNUgyMi41eiIgZmlsbD0iI2E3YWFhZCIvPjxwYXRoIGQ9Ik0yNS40NzcgMi41Yy41IDAgLjk3Ni4xNyAxLjMyOC40NzhsNy42NDggNi43Yy4zNTIuMzA3LjU0Ny43MjUuNTQ3IDEuMTU1di42M0gyNC40MTZWMi41eiIgZmlsbD0iI2E3YWFhZCIvPjwvc3ZnPg==',
			59 // Just above Appearance (position 60).
		);

		add_submenu_page(
			'pdfdraft',
			__( 'PDFDraft', 'pdfdraft' ),
			__( 'Home', 'pdfdraft' ),
			'edit_posts',
			'pdfdraft',
			'__return_empty_string'
		);

		add_submenu_page(
			'pdfdraft',
			__( 'PDFDraft Settings', 'pdfdraft' ),
			__( 'Settings', 'pdfdraft' ),
			'edit_posts',
			self::SETTINGS_PAGE_SLUG,
			array( $this, 'renderSettingsPage' )
		);

		$items = $this->applyFilters( 'pdfdraft_admin_submenus', array() );

		foreach ( $items as $item ) {
			add_submenu_page(
				'pdfdraft',
				$item['page_title'],
				$item['menu_title'],
				$item['capability'],
				$item['slug'],
				$item['callback']
			);
		}
	}

	/**
	 * Render the core PDFDraft settings page mount.
	 *
	 * @return void
	 */
	public function renderSettingsPage() {
		if ( ! current_user_can( 'edit_posts' ) ) {
			wp_die( esc_html__( 'You do not have sufficient permissions.', 'pdfdraft' ) );
		}
		?>
		<div class="wrap" style="margin:0;padding:0;">
			<div id="pdfdraft-settings-root" class="pdfdraft-settings-root"></div>
		</div>
		<?php
	}

	/**
	 * Get addon settings sections visible to the current user.
	 *
	 * Sections are registered via the `pdfdraft_settings_sections` filter.
	 * Each entry must have: key (string), label (string), capability (string).
	 *
	 * @return array<int, array{key: string, label: string, capability: string}>
	 */
	public function getVisibleSettingsSections(): array {
		$sections = $this->applyFilters( 'pdfdraft_settings_sections', array() );
		return array_values(
			array_filter(
				$sections,
				function ( $s ) {
					$cap = $s['capability'] ?? 'manage_options';
					return ! empty( $s['key'] ) && ! empty( $s['label'] ) && current_user_can( $cap );
				}
			)
		);
	}

	/**
	 * Output script to set the parent menu link URL.
	 *
	 * @return void
	 */
	public function setParentMenuLink() {
		$url = admin_url( 'admin.php?page=pdfdraft' );
		?>
		<script>
			(function() {
				var link = document.querySelector('#toplevel_page_pdfdraft > a');
				if (link) link.href = <?php echo wp_json_encode( $url ); ?>;
			})();
		</script>
		<?php
	}

	/**
	 * Check if the current page is a PDFDraft admin page.
	 *
	 * @return bool
	 */
	public function isPDFDraftPage() {
		global $pagenow;
		return 'admin.php' === $pagenow && isset( $_GET['page'] ) && 'pdfdraft' === $_GET['page']; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
	}

	/**
	 * Check if current admin page is the core PDFDraft settings page.
	 *
	 * @return bool
	 */
	public function isPDFDraftSettingsPage() {
		global $pagenow;
		$page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		return 'admin.php' === $pagenow && self::SETTINGS_PAGE_SLUG === $page;
	}

	/**
	 * Enqueue scripts/styles for core settings screen.
	 *
	 * @return void
	 */
	public function enqueueSettingsPageAssets() {
		if ( ! $this->isPDFDraftSettingsPage() ) {
			return;
		}

		wp_add_inline_script(
			'wp-api-fetch',
			'window.wpApiSettings = ' . wp_json_encode(
				array(
					'root'  => esc_url_raw( rest_url() ),
					'nonce' => wp_create_nonce( 'wp_rest' ),
				)
			) . ';',
			'before'
		);
		// Shared settings-shell CSS is reused by all PDFDraft settings pages.
		wp_enqueue_style( 'pdfdraft-editor' );
		wp_enqueue_style( 'pdfdraft-settings-shell' );
		wp_enqueue_style( 'pdfdraft-settings' );
		wp_enqueue_script( 'pdfdraft-settings' );

		// Pass registered addon sections to the JS bundle.
		$visible_sections = $this->getVisibleSettingsSections();
		wp_localize_script(
			'pdfdraft-settings',
			'__PDFDRAFT_SETTINGS__',
			array(
				'sections' => array_map(
					function ( $s ) {
						$entry = array(
							'key'   => $s['key'],
							'label' => $s['label'],
						);
						// Forward optional children (sub-sections shown as nested nav items).
						if ( ! empty( $s['children'] ) && is_array( $s['children'] ) ) {
							$entry['children'] = array_values(
								array_map(
									fn( $c ) => array(
										'key'   => (string) ( $c['key'] ?? '' ),
										'label' => (string) ( $c['label'] ?? '' ),
									),
									$s['children']
								)
							);
						}
						return $entry;
					},
					$visible_sections
				),
			)
		);

		// Let addons enqueue their own scripts/styles on this page.
		$this->doAction( 'pdfdraft_settings_page_enqueue_scripts' );
	}

	/**
	 * Add active design slug to localized editor data.
	 *
	 * @param array $data Existing localized data.
	 * @return array Modified localized data.
	 */
	public function addActiveDesignLocalizedData( array $data ) {
		if ( empty( $data['for'] ) ) {
			$data['activeDesignSlug'] = get_option( self::ACTIVE_DESIGN_OPTION_KEY, '' );
		}
		return $data;
	}

	/**
	 * Register REST API routes for the main active design.
	 *
	 * @return void
	 */
	public function registerActiveDesignRestRoute() {
		register_rest_route(
			'pdfdraft/v1',
			'/active-design',
			array(
				'methods'             => 'GET',
				'permission_callback' => fn() => current_user_can( 'edit_posts' ),
				'callback'            => function () {
					return rest_ensure_response( array( 'slug' => get_option( self::ACTIVE_DESIGN_OPTION_KEY, '' ) ) );
				},
			)
		);
		register_rest_route(
			'pdfdraft/v1',
			'/active-design',
			array(
				'methods'             => 'POST',
				'permission_callback' => fn() => current_user_can( 'edit_posts' ),
				'callback'            => function ( \WP_REST_Request $request ) {
					$slug = $request->get_param( 'slug' );
					update_option( self::ACTIVE_DESIGN_OPTION_KEY, $slug );
					return rest_ensure_response( array( 'slug' => $slug ) );
				},
				'args'                => array(
					'slug' => array(
						'required'          => true,
						'type'              => 'string',
						'sanitize_callback' => 'sanitize_text_field',
					),
				),
			)
		);
	}

	/**
	 * Clear the active design option when the design is deleted.
	 *
	 * @param \WP_REST_Request $request REST request from the delete action.
	 * @return void
	 */
	public function onAfterDeletePdfDesign( $request ) {
		$for = $request->get_param( 'for' ) ?? '';
		if ( ! empty( $for ) ) {
			return;
		}
		$deleted = $request->get_param( 'id' );
		if ( ! is_string( $deleted ) || '' === $deleted ) {
			return;
		}
		$active = (string) get_option( self::ACTIVE_DESIGN_OPTION_KEY, '' );
		if ( '' !== $active && $active === $deleted ) {
			delete_option( self::ACTIVE_DESIGN_OPTION_KEY );
		}
	}
}
