<?php

namespace FleekDash\Admin;

use FleekDash\Admin\Editor\EditorCSSManager;
use FleekDash\Admin\Editor\EditorIframeManager;
use FleekDash\Admin\Editor\ThirdPartyEditorCssManager;
use FleekDash\Admin\Iframe\IframeCSSManager;
use FleekDash\Admin\Iframe\IframeHelpers;

/**
 * Editor Customizer
 *
 * Customizes both TinyMCE (Classic Editor) and Gutenberg (Block Editor)
 * with unified theme integration, font customization, and iframe synchronization.
 *
 * Previously named TinyMCE.php but handles both editors.
 *
 * Bootstrap: call {@see EditorCustomizer::register()} on `plugins_loaded` (see fleekdash.php).
 * Do not instantiate this class at file load — avoids untestable side effects and matches plugin wiring patterns.
 *
 * @package FleekDash\Admin
 * @since 2.2.0
 */
class EditorCustomizer
{
    /**
     * Registered singleton (constructor registers WordPress hooks; reference satisfies analyzers).
     */
    private static ?self $instance = null;

    /**
     * Wire WordPress hooks (call from plugins_loaded — avoids side effects at require time).
     */
    public static function register(): void
    {
        if (self::$instance !== null) {
            return;
        }
        self::$instance = new self();
    }

    public function __construct()
    {
        \add_filter('tiny_mce_before_init', [$this, 'customizeTinymce']);
        \add_action('admin_enqueue_scripts', [$this, 'enqueueInterFont']);
        \add_filter('block_editor_settings_all', [$this, 'customizeGutenberg']);
        \add_action('admin_footer', [$this, 'injectCustomIframeClass']);
    }

    /**
     * Enqueue Inter font and admin styles
     *
     * @return void
     */
    public function enqueueInterFont(): void
    {
        // Don't load any assets if plugin is temporarily disabled
        if (class_exists('\FleekDash\Core\ClassicModeHandler') && \FleekDash\Core\ClassicModeHandler::isTemporarilyDisabled()) {
            return;
        }

        // Iframe shell loads skin via IframeCSSManager::enqueueDesignSystemTokens() (priority 998).
        if (isset($_GET['fleekdash-frame']) && (string) $_GET['fleekdash-frame'] === '1') {
            return;
        }

        // In protected mode we intentionally skip FleekDash design CSS (index); tokens only.
        if (IframeHelpers::isProtectedRequest()) {
            \wp_enqueue_style(
                'fleekdash-css-iframe-tokens',
                \FleekDash\Libs\Assets\getIframeTokensCssUrl(),
                array(),
                \FleekDash\Libs\Assets\getIframeTokensCssVersion(),
            );
            return;
        }

        $cssEntry = IframeCSSManager::getAdminSkinCssEntry();

        // Enqueue main admin styles (block editor → gutenberg-index; classic/lists → index).
        \wp_enqueue_style(
            'fleekdash-admin-css',
            \FleekDash\Libs\Assets\getCssUrl($cssEntry),
            array(),
            \FleekDash\Libs\Assets\getCssVersion($cssEntry),
        );

        ThirdPartyEditorCssManager::enqueueActiveStyles('fleekdash-admin-css');
        IframeCSSManager::enqueueWpdsBridgeLate('fleekdash-admin-css');
    }

    /**
     * Customize TinyMCE Classic Editor
     *
     * @param array $init TinyMCE configuration
     * @return array Modified configuration
     */
    public function customizeTinymce($init): array
    {
        // Add Inter font to the font family list
        $init['font_formats'] = 'Inter=Inter,sans-serif;' . (isset($init['font_formats']) ? $init['font_formats'] : '');

        // Set Inter as the default font using proper TinyMCE configuration
        $init['body_class'] = 'inter-font';

        // Add custom CSS for the editor
        $init['content_style'] = EditorCSSManager::getTinyMCEStyles();

        return $init;
    }

    /**
     * Customize Gutenberg Block Editor
     *
     * @param array $settings Gutenberg editor settings
     * @return array Modified settings
     */
    public function customizeGutenberg($settings): array
    {
        // Add our custom styles to the editor body
        $settings['styles'][] = array(
            'css' => EditorCSSManager::getGutenbergStyles()
        );

        return $settings;
    }

    /**
     * Inject custom iframe scripts for nested editor iframes
     *
     * Delegates to EditorIframeManager for complex iframe handling.
     *
     * @return void
     */
    public function injectCustomIframeClass(): void
    {
        EditorIframeManager::injectEditorIframeScripts();
    }
}
