<?php

/**
 * The public-facing functionality of the plugin.
 *
 * @link       https://orphic.ca
 * @since      1.0.0
 *
 * @package    Orphic_UI
 * @subpackage Orphic_UI/public
 */

/**
 * The public-facing functionality of the plugin.
 *
 * Defines the plugin name, version, and two examples hooks for how to
 * enqueue the public-facing stylesheet and JavaScript.
 *
 * @package    Orphic_UI
 * @subpackage Orphic_UI/public
 * @author     orphic <contact@orphic.ca>
 */
class Orphic_UI_Public
{

  const DEFAULT_COLORS =  array(
    // Couleurs principales
    ['color' => '#0052CC', 'name' => 'Primary color', 'slug' => 'primary'],
    ['color' => '#172B4D', 'name' => 'Secondary color', 'slug' => 'secondary'],
    ['color' => '#5487df', 'name' => 'Accent color', 'slug' => 'accent'],
    ['color' => 'white', 'name' => 'Background', 'slug' => 'background'],
    ['color' => '#f4f5f7', 'name' => 'Section background', 'slug' => 'section-background'],
    ['color' => '#ebecf0', 'name' => 'Section background hover', 'slug' => 'section-background-hover'],
    ['color' => '#172B4D', 'name' => 'Text', 'slug' => 'text'],
    ['color' => '#EBECF0', 'name' => 'Border', 'slug' => 'border'],

    // Couleurs d'état
    ['color' => '#de350b', 'name' => 'Error Text', 'slug' => 'error'],
    ['color' => '#36B37E', 'name' => 'Success Text', 'slug' => 'success'],
    ['color' => '#FFAB00', 'name' => 'Warning Text', 'slug' => 'warning'],
    ['color' => '#0065FF', 'name' => 'Info Text', 'slug' => 'info'],

    // Couleurs d'état en background
    ['color' => '#E6F9F4', 'name' => 'Success background', 'slug' => 'success-background'],
    ['color' => '#ffbdad', 'name' => 'Error background', 'slug' => 'error-background'],
    ['color' => '#FFF8E6', 'name' => 'Warning background', 'slug' => 'warning-background'],
    ['color' => '#E6F4FF', 'name' => 'Info background', 'slug' => 'info-background']
  );

  /**
   * The ID of this plugin.
   *
   * @since    1.0.0
   * @access   private
   * @var      string    $plugin_name    The ID of this plugin.
   */
  private $plugin_name;

  /**
   * The version of this plugin.
   *
   * @since    1.0.0
   * @access   private
   * @var      string    $version    The current version of this plugin.
   */
  private $version;

  /**
   * Initialize the class and set its properties.
   *
   * @since    1.0.0
   * @param      string    $plugin_name       The name of the plugin.
   * @param      string    $version    The version of this plugin.
   */
  public function __construct($plugin_name, $version)
  {

    $this->plugin_name = $plugin_name;
    $this->version = $version;
  }

  /**
   * Register the stylesheets for the public-facing side of the site.
   *
   * @since    1.0.0
   */
  public function enqueue_styles()
  {

    /**
     * This function is provided for demonstration purposes only.
     *
     * An instance of this class should be passed to the run() function
     * defined in Orphic_UI_Loader as all of the hooks are defined
     * in that particular class.
     *
     * The Orphic_UI_Loader will then create the relationship
     * between the defined hooks and the functions defined in this
     * class.
     */

    wp_enqueue_style($this->plugin_name, plugin_dir_url(__FILE__) . 'css/orphic-ui-public.css', array(), $this->version, 'all');
  }

  public function orphic_wp_block_plugin_enqueue_assets()
  {
    $global_color_palette_name = get_option(ConstBlockOrphicOptionName::GLOBAL_COLOR_PALETTE);
    switch ($global_color_palette_name) {
      case ConstBlockOrphicOptionValue::GLOBAL_COLOR_PALETTE_CLASSIC:
        wp_enqueue_style('orphic-wp-block-plugin-classic', ORPHIC_PLUGIN_UI_DIR_URL . 'public/css/orphic-wp-block-plugin-classic.css', array(), $this->version, 'all');
        break;
      case ConstBlockOrphicOptionValue::GLOBAL_COLOR_PALETTE_CUSTOM:
        wp_enqueue_style('orphic-wp-block-plugin-custom', ORPHIC_PLUGIN_UI_DIR_URL . 'public/css/orphic-wp-block-plugin-custom.css', array(), $this->version, 'all');
        break;
    }
  }

  /**
   * Register the JavaScript for the public-facing side of the site.
   *
   * @since    1.0.0
   */
  public function enqueue_scripts()
  {

    /**
     * This function is provided for demonstration purposes only.
     *
     * An instance of this class should be passed to the run() function
     * defined in Orphic_UI_Loader as all of the hooks are defined
     * in that particular class.
     *
     * The Orphic_UI_Loader will then create the relationship
     * between the defined hooks and the functions defined in this
     * class.
     */

    wp_enqueue_script($this->plugin_name, plugin_dir_url(__FILE__) . 'js/orphic-ui-public.js', array('jquery'), $this->version, false);

    // Enregistrer et charger le module d'animation
    orphic_module_import()->register_module(
      'module-orphic-motion-animation',
      ORPHIC_PLUGIN_UI_DIR_URL . 'features/modules/module-js/orphic-motion-animation.js',
      array(),
      $this->version,
      true
    );
  }

  /**
   * Check if a specific module is active
   *
   * @param string $module_slug The slug of the module to check
   * @return boolean True if the module is active, false otherwise
   */
  private function is_module_active($module_slug)
  {
    $active_modules = get_option(ConstBlockOrphicOptionName::ACTIVE_MODULES, array());
    return in_array($module_slug, $active_modules);
  }

  /**
   * Enqueue editor assets for active modules
   */
  public function enqueue_editor_assets()
  {
    $js_modules_dir = ORPHIC_PLUGIN_UI_DIR_PATH . 'features/modules/module-js/';

    if (!is_dir($js_modules_dir)) {
      return;
    }

    // Parcourir les modules
    foreach (new DirectoryIterator($js_modules_dir) as $moduleDir) {
      if ($moduleDir->isDot() || !$moduleDir->isDir()) continue;

      $module_name = $moduleDir->getBasename();
      $editor_dir = $moduleDir->getPathname() . '/editor';

      // Vérifier si le module est actif
      if ($this->is_module_active($module_name) && is_dir($editor_dir)) {
        foreach (new DirectoryIterator($editor_dir) as $editorFile) {
          if ($editorFile->isFile() && $editorFile->getExtension() === 'js') {
            wp_enqueue_script(
              'orphic-' . $module_name . '-editor',
              ORPHIC_PLUGIN_UI_DIR_URL . 'features/modules/module-js/' . $module_name . '/editor/' . $editorFile->getFilename(),
              array(
                'wp-blocks',
                'wp-element',
                'wp-editor',
                'wp-components',
                'wp-i18n',
                'wp-compose',
                'lodash'
              ),
              filemtime($editorFile->getPathname()),
              true
            );
          }
        }
      }
    }
  }

  function register_orphic_module()
  {
    // Base directories for modules
    $js_modules_dir = ORPHIC_PLUGIN_UI_DIR_PATH . 'features/modules/module-js/';

    // Create directories if they don't exist
    if (!is_dir($js_modules_dir)) {
      throw new Error('JS modules directory not found: ' . $js_modules_dir);
    }

    // Register JS Modules
    $js_iterator = new RecursiveIteratorIterator(
      new RecursiveDirectoryIterator($js_modules_dir, RecursiveDirectoryIterator::SKIP_DOTS),
      RecursiveIteratorIterator::SELF_FIRST
    );

    foreach ($js_iterator as $fileinfo) {
      if ($fileinfo->isDir()) {
        $module_name = basename($fileinfo->getPathname());
        $view_dir = $fileinfo->getPathname() . '/view';
        $module_slug = $module_name;

        // Vérifier si le module est actif
        $is_active = $this->is_module_active($module_slug);

        // Process view files
        if (is_dir($view_dir)) {
          foreach (new DirectoryIterator($view_dir) as $viewFile) {
            if ($viewFile->isFile() && $viewFile->getExtension() === 'js') {
              if ($is_active) {
                // Enqueue if module is active
                orphic_module_import()->enqueue_module(
                  'module-' . $module_slug,
                  ORPHIC_PLUGIN_UI_DIR_URL . 'features/modules/module-js/' . $module_name . '/view/' . $viewFile->getFilename(),
                  array(),
                  filemtime($viewFile->getPathname()),
                  true
                );
              } else {
                // Just register if module is not active
                orphic_module_import()->register_module(
                  'module-' . $module_slug,
                  ORPHIC_PLUGIN_UI_DIR_URL . 'features/modules/module-js/' . $module_name . '/view/' . $viewFile->getFilename(),
                  array(),
                  filemtime($viewFile->getPathname()),
                  true
                );
              }
            }
          }
        }
      }
    }
  }

  /**
   * Register the blocks for the plugin
   * @see ConstBlockOrphicBlockList
   * @see ACTIVE_BLOCKS
   * @see save_active_blocks()
   * @return void
   */
  function register_orphic_block()
  {

    if (! function_exists('register_block_type')) {
      return;
    }

    $base_dir = ORPHIC_PLUGIN_UI_DIR_PATH . 'build/';

    // if the base dir does not exist, we return because need to build with npm start before
    if (!is_dir($base_dir)) {
      return;
    }

    $iterator = new RecursiveIteratorIterator(
      new RecursiveDirectoryIterator($base_dir, RecursiveDirectoryIterator::SKIP_DOTS),
      RecursiveIteratorIterator::SELF_FIRST
    );

    $active_blocks = get_option(ConstBlockOrphicOptionName::ACTIVE_BLOCKS);

    // Récupérer la liste complète des blocs pour vérifier lesquels sont en développement
    $all_blocks = ConstBlockOrphicBlockList::BLOCKS;
    $dev_blocks = array();

    // Créer un tableau des blocs en développement
    foreach ($all_blocks as $block) {
      if (isset($block['experimental']) && $block['experimental']) {
        $dev_blocks[] = $block['key'];
      }
    }

    foreach ($iterator as $fileinfo) {
      if ($fileinfo->isDir()) {
        $block_dir = $fileinfo->getPathname();
        $block_slug = basename($block_dir, '.php');

        // Vérifier si ce bloc est en développement et si le mode dev n'est pas activé
        if (in_array($block_slug, $dev_blocks) && (!defined('ORPHIC_EXPERIMENTAL_MODE') || !ORPHIC_EXPERIMENTAL_MODE)) {
          continue; // Ignorer ce bloc s'il est en dev et que le mode dev n'est pas activé
        }

        // Check if this is a main block or a sub-block
        $is_sub_block = false;
        foreach ($active_blocks as $active_block) {
          // Vérifier également si le bloc parent est en développement
          if (in_array($active_block, $dev_blocks) && (!defined('ORPHIC_EXPERIMENTAL_MODE') || !ORPHIC_EXPERIMENTAL_MODE)) {
            continue; // Ignorer ce sous-bloc si son parent est en dev et que le mode dev n'est pas activé
          }

          if (strpos($block_slug, $active_block . '-') === 0) {
            $is_sub_block = true;
            register_block_type($block_dir);
            break;
          }
        }

        // Register if it's a main block that's active
        if (!$is_sub_block && in_array($block_slug, $active_blocks)) {
          register_block_type($block_dir);
        }
      }
    }
  }


  /**
   * Creates the plugin block function option page
   *
   * This function sets up the admin menu page for the Orphic WP Block plugin.
   * It creates a new instance of the Orphic_WP_Block_Option_Page class,
   * defines an SVG icon, and adds a new top-level menu page to the WordPress admin.
   *
   * @return void
   */
  public function create_plugin_block_function_option_page()
  {
    //TODO: change svg color
    $wp_block_option_page = new Orphic_WP_Block_Option_Page();
    $svg = '
    <svg width="149" height="149" viewBox="0 0 149 149" fill="none" xmlns="http://www.w3.org/2000/svg">
    <path d="M78 18C112.5 40.5 123.5 97.5 78.5 131L84.5 139C133.5 103 125 38.5 84.5 10L78 18Z" fill="black"/>
    <path d="M30 11.5H40V136.5H30V11.5Z" fill="black"/>
    </svg>
    ';
    add_menu_page(
      'Orphic UI',
      'Orphic UI',
      'manage_options',
      'orphic-wp-block',
      array($wp_block_option_page, 'render_option_page'),
      'data:image/svg+xml;base64,' . base64_encode($svg),
      80
    );
  }

  /**
   * Registers admin scripts and styles
   *
   * This function checks if we're on the Orphic WP Block admin page,
   * and if so, registers the necessary JavaScript and CSS files.
   *
   * @param string $hook The current admin page here its toplevel_page_orphic-wp-block
   *  			as you hook can be toplevel_page_{your_menu_slug}
   * @return void
   */
  public function register_admin_script_and_style($hook)
  {

    //todo: research if this is the best way to do it
    // because post.php its the hook for gutenberg editor but we also have post-new.php
    // so i have a problem because the custom post type have to a specific hook ?
    // i dont want to have a big conditional to check the hook
    // so i will always load the script and let it not do anything if the hook is not the good one
    // but i think this is not the best practice
    Orphic_WP_Block_Constants::enqueue_constants_script(); //only admin

    if ($hook != 'toplevel_page_orphic-wp-block') {
      return;
    }

    $wp_block_option_page = new Orphic_WP_Block_Option_Page();
    $wp_block_option_page->register_javascript();
    $wp_block_option_page->register_css();
  }

  /**
   * if you want to add a new option, you need to add it to the global option name
   * Sets the global option settings for this plugin
   *
   * This function initializes the default color palette name
   * and adds it to the WordPress options table.
   *
   * @return void
   */
  public function set_global_options_settings_wp_block_orphic()
  {
    // Gestion de la palette de couleurs globale
    if (!get_option(ConstBlockOrphicOptionName::GLOBAL_COLOR_PALETTE)) {
      add_option(ConstBlockOrphicOptionName::GLOBAL_COLOR_PALETTE, ConstBlockOrphicOptionValue::GLOBAL_COLOR_PALETTE_CLASSIC);
    }

    // Gestion des couleurs par défaut
    $existing_colors = get_option(ConstBlockOrphicOptionName::PLUGIN_COLORS);

    if (!$existing_colors) {
      update_option(ConstBlockOrphicOptionName::PLUGIN_COLORS, self::DEFAULT_COLORS);
    }

    $existing_colors_custom = get_option(ConstBlockOrphicOptionName::PLUGIN_COLORS_CUSTOM);
    if (!$existing_colors_custom) {
      update_option(ConstBlockOrphicOptionName::PLUGIN_COLORS_CUSTOM, self::DEFAULT_COLORS);
    }

    $existing_active_blocks = get_option(ConstBlockOrphicOptionName::ACTIVE_BLOCKS);
    if (!$existing_active_blocks) {
      update_option(ConstBlockOrphicOptionName::ACTIVE_BLOCKS, []);
    }

    $existing_active_modules = get_option(ConstBlockOrphicOptionName::ACTIVE_MODULES);
    if (!$existing_active_modules) {
      update_option(ConstBlockOrphicOptionName::ACTIVE_MODULES, []);
    }

    !get_option(ConstBlockOrphicOptionName::BREAKPOINT_TABLET_MAX) ? update_option(ConstBlockOrphicOptionName::BREAKPOINT_TABLET_MAX, 950) : 0;
    !get_option(ConstBlockOrphicOptionName::BREAKPOINT_MOBILE) ? update_option(ConstBlockOrphicOptionName::BREAKPOINT_MOBILE, 768) : 0;
    !get_option(ConstBlockOrphicOptionName::BREAKPOINT_TABLET_MIN) ? update_option(ConstBlockOrphicOptionName::BREAKPOINT_TABLET_MIN, 768) : 0;
    !get_option(ConstBlockOrphicOptionName::BREAKPOINT_DESKTOP) ? update_option(ConstBlockOrphicOptionName::BREAKPOINT_DESKTOP, 950) : 0;
  }

  /**
   * AJAX
   * 
   * Save the colors and the global color palette
   * call the script to create the css file
   *
   * @return void
   */
  public function save_colors()
  {
    // Vérifier si les données nécessaires sont présentes
    if (!isset($_POST['plugin_colors']) || !isset($_POST['global_color_palette'])) {
      wp_send_json_error('Data missing');
      return;
    }

    // Décoder et valider les couleurs du plugin
    $plugin_colors = json_decode(stripslashes($_POST['plugin_colors']), true);
    if (!is_array($plugin_colors)) {
      wp_send_json_error('Invalid plugin colors format');
      return;
    }

    // Valider la palette de couleurs globale
    $global_color_palette = sanitize_text_field($_POST['global_color_palette']);
    if (!in_array($global_color_palette, [ConstBlockOrphicOptionValue::GLOBAL_COLOR_PALETTE_CLASSIC, ConstBlockOrphicOptionValue::GLOBAL_COLOR_PALETTE_CUSTOM])) {
      wp_send_json_error('Invalid global color palette');
      return;
    }

    try {
      Orphic_Wp_Block_Option_Script::create_css_file_custom($plugin_colors);
    } catch (Exception $e) {
      wp_send_json_error($e->getMessage());
      return;
    }

    // Mettre à jour les options
    if ($global_color_palette === ConstBlockOrphicOptionValue::GLOBAL_COLOR_PALETTE_CUSTOM) {
      update_option(ConstBlockOrphicOptionName::PLUGIN_COLORS_CUSTOM, $plugin_colors);
      update_option(ConstBlockOrphicOptionName::PLUGIN_COLORS, $plugin_colors);
    } else {
      update_option(ConstBlockOrphicOptionName::PLUGIN_COLORS, self::DEFAULT_COLORS);
    }
    update_option(ConstBlockOrphicOptionName::GLOBAL_COLOR_PALETTE, $global_color_palette);

    wp_send_json_success('Colors saved successfully');
  }

  function save_active_blocks()
  {
    // Vérifier si les données nécessaires sont présentes
    if (!isset($_POST['active_blocks'])) {
      wp_send_json_error('Data missing');
      return;
    }
    $active_blocks = json_decode(stripslashes($_POST['active_blocks']));

    if (!$active_blocks && !is_array($active_blocks)) {
      wp_send_json_error('Incorrect data');
      return;
    }

    $active_blocks = array_map('sanitize_text_field', $active_blocks);

    update_option(ConstBlockOrphicOptionName::ACTIVE_BLOCKS, $active_blocks);

    wp_send_json_success('Active blocks saved successfully');
    return;
  }

  function save_breakpoint_settings()
  {
    if (!isset($_POST['breakpoint_settings'])) {
      wp_send_json_error('Data missing');
      return;
    }
    $breakpoint_settings = json_decode(stripslashes($_POST['breakpoint_settings']));
    update_option(ConstBlockOrphicOptionName::BREAKPOINT_MOBILE, $breakpoint_settings->mobile);
    update_option(ConstBlockOrphicOptionName::BREAKPOINT_TABLET_MIN, $breakpoint_settings->tabletMin);
    update_option(ConstBlockOrphicOptionName::BREAKPOINT_TABLET_MAX, $breakpoint_settings->tabletMax);
    update_option(ConstBlockOrphicOptionName::BREAKPOINT_DESKTOP, $breakpoint_settings->desktop);

    wp_send_json_success('Breakpoint settings saved successfully');
    return;
  }

  function save_active_modules()
  {
    // Vérifier si les données nécessaires sont présentes
    if (!isset($_POST['active_modules'])) {
      wp_send_json_error('Data missing');
      return;
    }
    $active_modules = json_decode(stripslashes($_POST['active_modules']));

    if (!$active_modules && !is_array($active_modules)) {
      wp_send_json_error('Incorrect data');
      return;
    }

    $active_modules = array_map('sanitize_text_field', $active_modules);

    update_option(ConstBlockOrphicOptionName::ACTIVE_MODULES, $active_modules);

    wp_send_json_success('Active modules saved successfully');
    return;
  }

  function save_google_api_key()
  {
    if (!isset($_POST['google_api_key'])) {
      wp_send_json_error('Data missing');
      return;
    }
    update_option(ConstBlockVariable::GOOGLE_MAP_API_KEY, $_POST['google_api_key']);
    wp_send_json_success('Google API key saved successfully');
    return;
  }

  // Enregistrement du Custom Post Type FAQ
  function create_faq_post_type()
  {

    // Only register if the block is selected in the options
    $active_blocks = get_option(ConstBlockOrphicOptionName::ACTIVE_BLOCKS);
    if (!in_array('faq', $active_blocks)) return;

    $labels = array(
      'name'               => 'FAQs',
      'singular_name'      => 'FAQ',
      'menu_name'          => 'FAQs',
      'add_new'            => 'Ajouter une FAQ',
      'add_new_item'       => 'Ajouter une nouvelle FAQ',
      'edit_item'          => 'Modifier la FAQ',
      'new_item'           => 'Nouvelle FAQ',
      'view_item'          => 'Voir la FAQ',
      'search_items'       => 'Rechercher dans les FAQs',
      'not_found'          => 'Aucune FAQ trouvée',
      'not_found_in_trash' => 'Aucune FAQ trouvée dans la corbeille'
    );

    $args = array(
      'labels'              => $labels,
      'public'              => false, // Pas de partie publique
      'publicly_queryable'  => false, // Pas de requêtes publiques
      'show_ui'             => true, // Interface admin uniquement
      'show_in_menu'        => true,
      'query_var'           => false, // Pas de variable de requête
      'rewrite'             => false, // Pas de réécriture d'URL
      'capability_type'     => 'post',
      'has_archive'         => false, // Pas d'archives
      'hierarchical'        => false,
      'menu_position'       => 5,
      'menu_icon'           => 'dashicons-format-chat',
      'supports'            => array('title', 'editor'),
      'show_in_rest'        => true, // Garder Gutenberg actif
    );

    register_post_type('faq', $args);
  }

  // Enregistrement de la taxonomie pour le filtrage
  function create_faq_taxonomy()
  {

    // Only register if the block is selected in the options
    $active_blocks = get_option(ConstBlockOrphicOptionName::ACTIVE_BLOCKS);
    if (!in_array('faq', $active_blocks)) return;

    $labels = array(
      'name'              => 'Catégories FAQ',
      'singular_name'     => 'Catégorie FAQ',
      'search_items'      => 'Rechercher des catégories',
      'all_items'         => 'Toutes les catégories',
      'parent_item'       => 'Catégorie parente',
      'parent_item_colon' => 'Catégorie parente:',
      'edit_item'         => 'Modifier la catégorie',
      'update_item'       => 'Mettre à jour la catégorie',
      'add_new_item'      => 'Ajouter une nouvelle catégorie',
      'new_item_name'     => 'Nom de la nouvelle catégorie',
      'menu_name'         => 'Catégories'
    );

    $args = array(
      'hierarchical'      => true,
      'public'            => false, // Pas de partie publique
      'labels'            => $labels,
      'show_ui'           => true,
      'show_admin_column' => true,
      'query_var'         => false,
      'rewrite'           => false,
      'show_in_rest'      => true, // Pour pouvoir utiliser la taxonomie dans Gutenberg
    );

    register_taxonomy('faq_category', array('faq'), $args);
  }

  function create_search_bar_post_type()
  {
    $active_blocks = get_option(ConstBlockOrphicOptionName::ACTIVE_BLOCKS);
    if (!in_array('search-bar', $active_blocks)) return;

    $labels = array(
      'name' => 'Search Bars',
      'singular_name' => 'Search Bar',
      'all_items' => 'All Search Bars',
      'menu_name' => 'Search Bars',
      'add_new' => 'Add New',
      'add_new_item' => 'Add New Search Bar',
      'edit_item' => 'Edit Search Bar',
    );

    $args = array(
      'hierarchical' => false,
      'labels' => $labels,
      'public' => false,
      'show_ui' => true,
      'show_admin_column' => true,
      'query_var' => false,
      'rewrite' => false,
      'show_in_rest' => true,
      'supports' => array('title'),
    );

    register_post_type('search_bar_orphic_ui', $args);
  }
}
