<?php
/**
 * File Path: includes/admin/class-mbs-tutorial-admin-page.php
 *
 * Tutorial Data Dashboard Card
 *
 * Registers three AJAX handlers (install / uninstall / reinstall) and renders
 * an inline panel on the MBS admin dashboard via the Tutorial Data tile in the
 * action bar.  The former Books > Tutorial Data submenu page has been removed;
 * all controls now live in the dashboard panel.
 *
 * AJAX actions:
 *   mbs_tutorial_install    -- calls MBS_Tutorial_Importer::run()
 *   mbs_tutorial_uninstall  -- calls MBS_Tutorial_Uninstaller::run()
 *   mbs_tutorial_reinstall  -- calls uninstall then install in sequence
 *
 * @package    MyBookShowroom
 * @subpackage Admin
 * @since      1.0.0
 */

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

/**
 * Dashboard panel and AJAX handlers for tutorial book data management.
 *
 * @since 1.0.0
 */
class MBS_Tutorial_Admin_Page {

    // -------------------------------------------------------------------------
    // Registration
    // -------------------------------------------------------------------------

    /**
     * Register admin_enqueue_scripts and AJAX hooks.
     *
     * @since  1.0.0
     * @return void
     */
    public static function register(): void {
        add_action( 'admin_enqueue_scripts',      array( __CLASS__, 'enqueue_assets' ), 20 );
        add_action( 'wp_ajax_mbs_tutorial_install',   array( __CLASS__, 'ajax_install' ) );
        add_action( 'wp_ajax_mbs_tutorial_uninstall', array( __CLASS__, 'ajax_uninstall' ) );
        add_action( 'wp_ajax_mbs_tutorial_reinstall',     array( __CLASS__, 'ajax_reinstall' ) );
        add_action( 'wp_ajax_mbs_tutorial_poll_progress', array( __CLASS__, 'ajax_poll_progress' ) );
    }

    // -------------------------------------------------------------------------
    // Asset enqueue
    // -------------------------------------------------------------------------

    /**
     * Localise tutorial nonce onto the dashboard JS object.
     * Runs only on the MBS dashboard page (toplevel_page_my-book-showroom).
     *
     * @since  1.0.0
     * @param  string $hook_suffix Current admin page hook suffix.
     * @return void
     */
    public static function enqueue_assets( string $hook_suffix ): void {
        if ( 'toplevel_page_my-book-showroom' !== $hook_suffix ) {
            return;
        }
        // Shared progress module (used by tutorial and ZIP import flows).
        wp_enqueue_script(
            'mbs-import-progress',
            plugins_url( 'assets/js/adminjs/mbs-import-progress.js', MBS_DIR . 'bookshowroom.php' ),
            array(),
            MBS_VERSION,
            true
        );

        // Tutorial Data panel JS.
        wp_enqueue_script(
            'mbs-tutorial-admin',
            plugins_url( 'assets/js/adminjs/mbs-tutorial-admin.js', MBS_DIR . 'bookshowroom.php' ),
            array( 'mbs-import-progress' ),
            MBS_VERSION,
            true
        );
        wp_localize_script(
            'mbs-tutorial-admin',
            'mbsTutorial',
            array(
                'ajaxUrl'        => admin_url( 'admin-ajax.php' ),
                'nonce'          => wp_create_nonce( 'mbs_tutorial_nonce' ),
                'i18nConfirm'    => __( 'Remove all tutorial books, media, and terms? This cannot be undone.', 'my-book-showroom' ),
                'i18nFailed'     => __( 'Request failed. Please try again.', 'my-book-showroom' ),
                'i18nError'      => __( 'An error occurred.', 'my-book-showroom' ),
                'i18nStarting'   => __( 'Starting…', 'my-book-showroom' ),
                'i18nRemoving'   => __( 'Removing tutorial data…', 'my-book-showroom' ),
                'i18nInstalled'  => __( 'Tutorial successfully installed.', 'my-book-showroom' ),
                'i18nInstalling' => __( 'Installing', 'my-book-showroom' ),
                'i18nOf'         => __( 'of', 'my-book-showroom' ),
            )
        );
    }

    // -------------------------------------------------------------------------
    // Dashboard panel render
    // -------------------------------------------------------------------------

    /**
     * Render the tutorial controls panel.
     * Called from templates/admin/dashboard.php inside #mbs-tutorial-panel.
     *
     * @since  1.0.0
     * @return void
     */
    public static function render_panel_content(): void {
        if ( ! current_user_can( 'manage_options' ) ) {
            return;
        }

        $is_installed = (bool) get_option( 'mbs_tutorial_imported' );
        ?>
        <div style="display:flex;align-items:center;justify-content:space-between;
                    flex-wrap:wrap;gap:0.75rem;margin-bottom:0.75rem;">
            <h3 style="margin:0;font-size:1rem;font-weight:600;">
                <?php esc_html_e( 'Tutorial Data', 'my-book-showroom' ); ?>
            </h3>
            <?php if ( $is_installed ) : ?>
            <span style="font-size:0.8rem;padding:2px 10px;border-radius:3px;
                         background:#d4edda;color:#155724;border:1px solid #c3e6cb;">
                <?php esc_html_e( 'Installed', 'my-book-showroom' ); ?>
            </span>
            <?php else : ?>
            <span style="font-size:0.8rem;padding:2px 10px;border-radius:3px;
                         background:#f8f9fa;color:#6c757d;border:1px solid #dee2e6;">
                <?php esc_html_e( 'Not Installed', 'my-book-showroom' ); ?>
            </span>
            <?php endif; ?>
        </div>

        <p style="margin:0 0 1rem;color:#555;font-size:0.875rem;">
            <?php esc_html_e( 'Install the seven-book tutorial catalog used in the My Book Showroom written and video tutorials. The catalog demonstrates every plugin feature: author, multi-author books, series, collections, universes, spinning videos, endorsements, awards, BISAC / Thema classification, and Coming Soon books.', 'my-book-showroom' ); ?>
        </p>

        <div class="mbs-tutorial-actions" style="display:flex;gap:8px;flex-wrap:wrap;align-items:center;">
            <?php if ( ! $is_installed ) : ?>
            <button type="button" class="button button-primary mbs-tutorial-btn"
                    data-action="mbs_tutorial_install">
                <?php esc_html_e( 'Install Tutorial Data', 'my-book-showroom' ); ?>
            </button>
            <?php else : ?>
            <button type="button" class="button button-secondary mbs-tutorial-btn"
                    data-action="mbs_tutorial_reinstall">
                <?php esc_html_e( 'Reinstall', 'my-book-showroom' ); ?>
            </button>
            <button type="button" class="button mbs-tutorial-btn"
                    data-action="mbs_tutorial_uninstall"
                    style="color:#b32d2e;border-color:#b32d2e;">
                <?php esc_html_e( 'Remove Tutorial Data', 'my-book-showroom' ); ?>
            </button>
            <?php endif; ?>
        </div>

        <div id="mbs-tutorial-progress-bar" style="display:none;margin-top:1rem;margin-bottom:0.4rem;">
            <div style="background:#e9ecef;border-radius:4px;height:8px;overflow:hidden;">
                <div id="mbs-tutorial-bar"
                     style="height:100%;background:#2271b1;width:0%;border-radius:4px;
                            transition:width 0.45s ease;"></div>
            </div>
        </div>
        <div id="mbs-tutorial-msgarea" style="display:none;margin:0 0 0.5rem;font-size:0.875rem;color:#555;"></div>

        <div id="mbs-tutorial-result" style="display:none;margin-top:1rem;"></div>

        <?php
    }

    // -------------------------------------------------------------------------
    // AJAX handlers
    // -------------------------------------------------------------------------

    /**
     * AJAX: Return current tutorial install progress (transient poll).
     *
     * No side effects. Requires manage_options capability but skips nonce
     * verification intentionally -- this is a read-only status endpoint.
     *
     * @since  2.0.0
     * @return void  Sends JSON and exits.
     */
    public static function ajax_poll_progress(): void {
        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( null, 403 );
        }
        $progress = get_transient( 'mbs_tutorial_progress' );
        if ( false === $progress ) {
            wp_send_json_success( array( 'step' => 'idle', 'message' => '', 'pct' => 0 ) );
        }
        wp_send_json_success( $progress );
    }

    /**
     * AJAX: Install tutorial data.
     *
     * @since  1.0.0
     * @return void  Sends JSON and exits.
     */
    public static function ajax_install(): void {
        self::verify_request( 'mbs_tutorial_nonce' );

        // PLG-NEW-008: Refuse a plain install when tutorial data is already
        // present. Running the importer again would create a duplicate set of
        // books. The user must use "Reinstall" (uninstall then install) instead.
        if ( get_option( 'mbs_tutorial_imported' ) ) {
            wp_send_json_error( array(
                'message' => __( 'Tutorial data is already installed. Use "Reinstall" to replace it.', 'my-book-showroom' ),
            ) );
        }

        // Plain install: do not force overwrite (no duplicate creation).
        $stats = MBS_Tutorial_Importer::run();

        if ( ! empty( $stats['errors'] ) ) {
            wp_send_json_error( array(
                'message' => sprintf(
                    /* translators: 1: count installed, 2: error count, 3: error list */
                    __( 'Installed %1$d book(s) with %2$d error(s): %3$s', 'my-book-showroom' ),
                    (int) $stats['books_installed'],
                    count( $stats['errors'] ),
                    esc_html( implode( '; ', $stats['errors'] ) )
                ),
            ) );
        }

        wp_send_json_success( array(
            'message' => sprintf(
                /* translators: %d: number of books installed */
                __( 'Tutorial data installed successfully. %d book(s) added to your library.', 'my-book-showroom' ),
                (int) $stats['books_installed']
            ),
        ) );
    }

    /**
     * AJAX: Uninstall tutorial data.
     *
     * @since  1.0.0
     * @return void  Sends JSON and exits.
     */
    public static function ajax_uninstall(): void {
        self::verify_request( 'mbs_tutorial_nonce' );

        $stats = MBS_Tutorial_Uninstaller::run();

        wp_send_json_success( array(
            'message' => sprintf(
                /* translators: 1: books, 2: attachments, 3: terms */
                __( 'Tutorial data removed. Deleted %1$d book(s), %2$d attachment(s), %3$d term(s).', 'my-book-showroom' ),
                (int) $stats['books_deleted'],
                (int) $stats['attachments_deleted'],
                (int) $stats['terms_deleted']
            ),
        ) );
    }

    /**
     * AJAX: Reinstall tutorial data (uninstall then install).
     *
     * @since  1.0.0
     * @return void  Sends JSON and exits.
     */
    public static function ajax_reinstall(): void {
        self::verify_request( 'mbs_tutorial_nonce' );

        MBS_Tutorial_Uninstaller::run();
        $stats = MBS_Tutorial_Importer::run( true );

        wp_send_json_success( array(
            'message' => sprintf(
                /* translators: %d: number of books installed */
                __( 'Tutorial data reinstalled successfully. %d book(s) are ready.', 'my-book-showroom' ),
                (int) $stats['books_installed']
            ),
        ) );
    }

    // -------------------------------------------------------------------------
    // Internal helpers
    // -------------------------------------------------------------------------

    /**
     * Verify the AJAX nonce and capability; die on failure.
     *
     * @since  1.0.0
     * @param  string $action  Nonce action string.
     * @return void
     */
    private static function verify_request( string $action ): void {
        // SA-M8: Verify nonce BEFORE capability check to prevent user-enumeration
        // via timing differences (unauthenticated requests should fail on nonce first).
        $nonce = sanitize_text_field( wp_unslash( $_POST['nonce'] ?? '' ) );
        if ( ! wp_verify_nonce( $nonce, $action ) ) {
            wp_send_json_error( array( 'message' => __( 'Security check failed.', 'my-book-showroom' ) ), 403 );
        }

        if ( ! current_user_can( 'manage_options' ) ) {
            wp_send_json_error( array( 'message' => __( 'Insufficient permissions.', 'my-book-showroom' ) ), 403 );
        }
    }
}
