<?php
/**
 * DashboardModule — Security dashboard feature module.
 *
 * Owns:
 *   • DashboardRegistry init and hook wiring
 *   • DashboardPage + ModulesManagerPage registration
 *   • Dashboard data refresh AJAX endpoint (with nonce + capability)
 *   • ModuleManagerAjax handlers (activate / deactivate / install / upload)
 *   • DashboardContributor (security score stat card)
 *
 * Zero dependency on other modules — all cross-module data flows in through
 * DashboardRegistry action hooks registered during each module's boot().
 *
 * @package UltraguardPro\modules\dashboard
 */

namespace UltraguardPro\modules\dashboard;

use UltraguardPro\modules\core\AbstractModule;
use UltraguardPro\support\LicenseInfo;
use UltraguardPro\support\AjaxResponseBuilder;

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

class DashboardModule extends AbstractModule {

    /** @var DashboardDataHandler|null  Lazy-loaded data handler instance. */
    private ?DashboardDataHandler $data_handler = null;

    public function get_id(): string { return 'dashboard'; }

    /**
     * Dashboard is a free-tier module — always available.
     */
    protected function requires_pro(): bool { return false; }

    /**
     * Dashboard is always enabled regardless of user settings.
     */
    public function is_enabled(): bool { return true; }

    public function boot(): void {
        // 1. Initialise the dynamic dashboard registry and wire its action hooks.
        //    Must happen before any module calls do_action('ultraguard_dashboard_register_*').
        DashboardRegistry::get_instance()->init_hooks();

        // 2. Register this module's own contribution (security score stat card).
        ( new DashboardContributor( $this->plugin ) )->register();

        // 3. Register admin pages.
        add_action( 'ultraguard_register_admin_pages', [ $this, 'register_pages' ], 10, 1 );

        // 4. AJAX: dashboard data refresh (registered via direct wp_ajax_ hook so
        //    the dashboard module does not depend on other modules' AJAX managers).
        add_action( 'wp_ajax_ultraguard_dashboard_refresh', [ $this, 'ajax_refresh' ] );

        // 5. Module-manager AJAX handlers.
        ( new ajax\ModuleManagerAjax( $this->plugin ) )->register();

        do_action( 'ultraguard_pro/dashboard/booted', $this );
    }

    // ── Admin page registration ───────────────────────────────────────────────

    /**
     * Register all dashboard admin pages with the UltraGuard page manager.
     *
     * @param mixed $admin  The admin page manager instance.
     */
    public function register_pages( $admin ): void {
        $admin->register_page( [
            'id'              => 'dashboard',
            'page_title'      => __( 'Security Dashboard', 'ultraguard-security-suite' ),
            'menu_title'      => __( 'UltraGuard', 'ultraguard-security-suite' ),
            'capability'      => 'manage_options',
            'scheme_callback' => [ $this->get_dashboard_page(), 'get_scheme' ],
            'is_parent'       => true,
            'priority'        => 1,
            'group'           => 'General',
            'icon'            => 'dashicons-shield-alt',
        ] );

        $admin->register_page( [
            'id'              => 'modules-manager',
            'page_title'      => __( 'Module Manager', 'ultraguard-security-suite' ),
            'menu_title'      => __( 'Modules', 'ultraguard-security-suite' ),
            'capability'      => 'manage_options',
            'scheme_callback' => [ pages\ModulesManagerPage::class, $this->plugin ],
            'parent_id'       => 'dashboard',
            'priority'        => 2,
            'group'           => 'General',
            'icon'            => 'dashicons-plugins-checked',
        ] );
    }

    // ── AJAX handlers ─────────────────────────────────────────────────────────

    /**
     * Invalidate dashboard caches and return the current timestamp.
     * Requires manage_options + valid nonce.
     */
    public function ajax_refresh(): void {
        // Verify nonce first, then capability — same order as wp_die() semantics
        if ( ! check_ajax_referer( 'ultraguard_dashboard_refresh', 'nonce', false ) ) {
            AjaxResponseBuilder::make()
                ->nonceError( __( 'Security check failed.', 'ultraguard-security-suite' ) )
                ->send( 403 );
        }

        if ( ! \UltraguardPro\ultraguard_current_user_can_manage() ) {
            AjaxResponseBuilder::make()
                ->permissionError( __( 'Permission denied.', 'ultraguard-security-suite' ) )
                ->send( 403 );
        }

        // Purge all dashboard caches
        if ( isset( $this->cache ) ) {
            $this->cache->invalidate_db();
            $this->cache->invalidate_render();
        }

        // Also clear the short-TTL transients used by DashboardDataHandler
        delete_transient( 'ultraguard_dashboard_data' );
        delete_transient( 'ultraguard_dashboard_overview' );

        AjaxResponseBuilder::make()
            ->success( __( 'Dashboard refreshed.', 'ultraguard-security-suite' ) )
            ->addData( 'timestamp', current_time( 'mysql', true ) )
            ->addNotification( __( 'Dashboard data refreshed successfully.', 'ultraguard-security-suite' ), 'success' )
            ->addAction( [
                'type'  => 'trigger',
                'event' => 'ultraguard:dashboard:refreshed',
                'data'  => [
                    'timestamp' => current_time( 'mysql', true ),
                ],
            ] )
            ->send();
    }

    // ── Accessors ─────────────────────────────────────────────────────────────

    /**
     * Return the shared DashboardDataHandler instance (lazy-loaded).
     *
     * @return DashboardDataHandler
     */
    public function get_data_handler(): DashboardDataHandler {
        if ( null === $this->data_handler ) {
            $this->data_handler = new DashboardDataHandler( $this->plugin );
        }
        return $this->data_handler;
    }

    /**
     * Return the DashboardPage instance (static singleton per request).
     *
     * @return pages\DashboardPage
     */
    private function get_dashboard_page(): pages\DashboardPage {
        static $page = null;
        if ( null === $page ) {
            $page = new pages\DashboardPage( $this->plugin );
        }
        return $page;
    }
}
