<?php
/**
 * OrokuBlocks Admin
 * 
 * @package OrokuBlocks
 * @author OrokuBlocks (https://orokublocks.com/)
 * 
 * @since 1.0.0
 * 
 */

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

if ( ! class_exists( 'OrokuBlocks_Admin' ) ) {
  final class OrokuBlocks_Admin {
    /**
     * @var array Active plugins in the current install
     * 
     * @access private
     */
    private $active_plugins = null;

    /**
     * Prevent more than one instance from being created
     * 
     * @since 1.0.0
     * 
     * @access private
     */
    private function __construct() {}

    /**
     * Prevent cloning
     * 
     * @since 1.0.0
     * 
     * @access private
     */
    private function __clone() {}

    /**
     * Returns the class instance
     * 
     * @since 1.0.0
     * 
     * @return OrokuBlocks_Admin $instance  Class instance
     */
    public static function getInstance() {
      static $instance = null;

      if ( $instance === null ) {
        $instance = new OrokuBlocks_Admin();

        // setup
        $instance->addActions();
      }

      return $instance;
    }

    /**
     * Register actions
     * 
     * @since 1.0.0
     * 
     * @access private
     */
    private function addActions() {
      add_action( 'admin_enqueue_scripts', array( $this, 'enqueueStyles' ) );
      add_action( 'admin_enqueue_scripts', array( $this, 'enqueueScripts' ) );

      add_action( 'admin_menu', array( $this, 'registerMenuPages' ) );

      add_action( 'after_setup_theme', array( $this, 'getActivePlugins' ) );
    }

    /**
     * Enqueue styles and fonts
     * 
     * @since 1.0.0
     */
    public function enqueueStyles() {
      // Fonts
      wp_enqueue_style( 'orokublocks-admin-fonts', 'https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,100..900&family=Lexend:wght@100..900&display=swap' );

      // Main styles
      wp_enqueue_style( 'orokublocks-admin-font-styles', orokublocks()->url . 'admin/assets/css/font.css', [], '1.0.0' );
      wp_enqueue_style( 'orokublocks-admin-styles', orokublocks()->url . 'admin/assets/css/style.css', [], '1.0.0' );
    }

    /**
     * Enqueue scripts
     * 
     * @since 1.0.0
     */
    public function enqueueScripts() {
      // Main scripts
      wp_enqueue_script( 'orokublocks-admin-scripts', orokublocks()->url . 'admin/assets/js/main.js', [], '1.0.0', true );

      // Variables
      wp_add_inline_script( 'orokublocks-admin-scripts', $this->getScriptConstants(), 'before' );

      // Settings script
      wp_enqueue_script( 'orokublocks-admin-general-settings-scripts', orokublocks()->url . 'admin/assets/js/settings.js', [], '1.0.0', true );

      // SVG script
      wp_enqueue_script( 'orokublocks-admin-svg-scripts', orokublocks()->url . 'admin/assets/js/svg-loader.js', [], '1.0.0', true );
    }

    /**
     * Return constants for use in scripts
     * 
     * @since 1.0.0
     * 
     * @return  $script_constants   Script constants
     * 
     * @access private
     */
    private function getScriptConstants() {
      $constants_values = [
        'submenuItems'    => $this->getSubmenuItems(),
        'settings'        => orokublocks()->settings->getSettings(),
        'settingFormIds'  => orokublocks()->settings->getSettingFormIds(),
        'ajax_url'        => admin_url('admin-ajax.php'),
        'ajax_nonce'      => wp_create_nonce('orokublocks-settings'),
        'translation'     => [
          'save_changes'  => esc_html__( 'Save Changes', 'orokublocks' ),
          'saving'        => esc_html__( 'Saving...', 'orokublocks' )
        ]
      ];

      $constants = 'const orokublocksAdminConstants = ' . json_encode( $constants_values ) . ';';

      return $constants;
    }

    /**
     * Register admin menu pages
     * 
     * @since 1.0.0
     */
    public function registerMenuPages() {
      $main_menu_slug = 'orokublocks';
      $submenu_items = $this->getSubmenuItems();

      add_menu_page(
        'OrokuBlocks',
        'OrokuBlocks',
        'manage_options',
        $main_menu_slug,
        function () { $this->requireTemplate( 'admin' ); },
        'none'
      );

      foreach ( $submenu_items as $submenu_item ) {
        add_submenu_page(
          $main_menu_slug,
          $submenu_item['name'],
          $submenu_item['name'],
          'manage_options',
          OrokuBlocks_Router::adminSubmenuPagePathGet( $submenu_item['id'] ),
          '__return_null'
        );
      }

      // remove duplicate main menu page item
      remove_submenu_page( 'orokublocks', 'orokublocks' );
    }

    /**
     * Returns admin submenu items by id
     * 
     * @since 1.0.0
     * 
     * @return array $submenu_items
     */
    public function getSubmenuItems() {
      $submenu_items = [
        'general'   => [
          'id'    => 'general',
          'name'  => __( 'General', 'orokublocks' )
        ],
        'widgets'   => [
          'id'    => 'widgets',
          'name'  => __( 'Widgets', 'orokublocks' )
        ],
        'system'    => [
          'id'    => 'system',
          'name'  => __( 'System', 'orokublocks' )
        ]
      ];

      return apply_filters( 'orokublocks_admin_submenu_items', $submenu_items );
    }

    /**
     * Returns active plugins
     * 
     * @since 1.0.0
     * 
     * @return array $active_plugins  Active plugins
     */
    public function getActivePlugins() {
      if ( $this->active_plugins === null ) {
        $this->active_plugins = [];

        $active_plugins_ids = get_option( 'active_plugins' );
        $all_plugins = get_plugins();

        $this->active_plugins = array_filter(
          $all_plugins,
          function( $plugin_name ) use ( $active_plugins_ids ) {
            return in_array( $plugin_name, $active_plugins_ids );
          },
          ARRAY_FILTER_USE_KEY
        );
      }

      return $this->active_plugins;
    }

    /**
     * Require a template file by name
     * 
     * @since 1.0.0
     * 
     * @param string $template_name   Name of the template to require.
     */
    public function requireTemplate( $template_name, $args = [] ) {
      orokublocks()->requireTemplate( 'admin/includes/template/' . $template_name, $args );
    }
  }
}