<?php
/**
 * Contentosapp Studio — main module singleton.
 *
 * Bootstraps the module by registering all WordPress hooks:
 * REST routes, AJAX handlers, DB upgrade checks, and admin menus.
 *
 * Admin menus are ALWAYS registered so that WordPress populates
 * $admin_page_hooks.  License checks live inside page content and
 * AJAX handlers, not in the bootstrap.
 *
 * @package Contentosapp_Studio
 * @since   3.0.0
 */

defined( 'ABSPATH' ) || exit;

class Costudio {

    /** @var Costudio|null */
    private static ?Costudio $instance = null;

    private function __construct() {}

    public static function get_instance(): self {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    // ── Bootstrap ─────────────────────────────────────────────────────────────

    /**
     * Called by module.php on the 'contentos_loaded' action.
     *
     * Registers all hooks.  Safe to call multiple times (guards against
     * duplicate registration with a private flag).
     */
    public function init(): void {
        static $initialised = false;
        if ( $initialised ) return;
        $initialised = true;

        // REST endpoint for the background runner.
        add_action( 'rest_api_init', [ Costudio_Runner::class, 'register_rest_route' ] );
		add_action( 'rest_api_init', [ Costudio_Publication_Jobs::class, 'register_rest_route' ] );

        // Immediate WP-Cron step (parallel to loopback) so the next agent runs even when wp_remote_post(non-blocking) fails.
        add_action( 'costudio_pipeline_cron_run', [ Costudio_Runner::class, 'cron_run_background' ], 10, 2 );
		Costudio_Publication_Jobs::register_hooks();

        // Maintenance + stalled-pipeline watchdog.
        if ( class_exists( 'Costudio_Housekeeping' ) ) {
            Costudio_Housekeeping::register_hooks();
        }

        // Hook into ContentOS table install event (fired on Core activation).
        add_action( 'costudio_install_tables', [ Costudio_DB::class, 'install' ] );

        // Admin screens are hooked in Parte 2.
        if ( is_admin() ) {
            // DB upgrade check on admin context only.
            Costudio_DB::maybe_upgrade();
            $this->init_admin();
        }
    }

    // ── Admin ─────────────────────────────────────────────────────────────────

    private function init_admin(): void {
        $admin = new Costudio_Admin();
        $admin->register_hooks();
    }
}
