<?php
declare(strict_types=1);

namespace WP_AUX\Entities;

use WP_AUX\Services\ShortcodeService;

/**
 * Handles the registration of AUX shortcodes, and settings for non-AUX shortcodes
 * @since 1.0.0
 */
class ShortcodesEntity
{
  protected array $auxShortcodes = [];
  protected array $globalShortcodes = [];

  protected function __construct() {}

  /**
   * Add settings for a global (non-AUX) shortcode
   * @since 1.0.1
   */
  public function addGlobalShortcodeData(string $shortcodeName, array $data): void
  {
    $currentData = $this->globalShortcodes[$shortcodeName] ?? [];
    $this->globalShortcodes[$shortcodeName] = array_replace_recursive($currentData, $data);
  }

  /**
   * Get settings for a global (non-AUX) shortcode
   * @since 1.0.1
   */
  public function getGlobalShortcodeData(string $shortcodeName): array
  {
    return $this->globalShortcodes[$shortcodeName] ?? [];
  }

  /**
   * Test if a shortcode is an AUX shortcode
   * @since 1.0.1
   */
  public function isAuxShortcode(string $shortcodeName): bool
  {
    if (isset($this->auxShortcodes[$shortcodeName])) {
      return true;
    }

    global $shortcode_tags;
    $shortcode = @$shortcode_tags[$shortcodeName];

    // Ensure $shortcode is an array and $shortcode[0] is a string before using strpos
    if (!is_array($shortcode) || !isset($shortcode[0]) || !is_string($shortcode[0])) {
      return false;
    }

    return strpos($shortcode[0], 'WP_AUX') === 0;
  }

  /**
   * Pre-register an AUX shortcode from a shortcode file
   * @since 1.0.0
   */
  public function preregisterShortcode(string $shortcodeFile): ?array
  {
    $shortcodeName = pathinfo($shortcodeFile, PATHINFO_FILENAME);

    if (isset($this->auxShortcodes[$shortcodeName])) {
      return null;
    }

    $data = ShortcodeService::getShortcodeData($shortcodeFile);

    $this->auxShortcodes[$shortcodeName] = [
      'file' => $shortcodeFile,
      'data' => $data,
    ];

    if (!empty($data['Alias'])) {
      $aliases = explode(',', $data['Alias']);

      foreach ($aliases as $alias) {
        $alias = trim($alias);

        $this->auxShortcodes[$alias] = [
          'file' => $shortcodeFile,
          'data' => $data,
        ];
      }
    }

    return $this->auxShortcodes[$shortcodeName];
  }

  /**
   * Add all pre-registered AUX shortcodes to Wordpress
   * @since 1.0.0
   */
  public function addShortcodes(): void
  {
    foreach ($this->auxShortcodes as $shortcodeName => $shortcodeData) {
      add_shortcode($shortcodeName, [ ShortcodeService::class, 'doShortcode' ]);
    }
  }

  /**
   * Get AUX shortcode data
   * @since 1.0.0
   */
  public function getShortcode(string $shortcodeName): ?array
  {
    return @$this->auxShortcodes[$shortcodeName];
  }

  /**
   * Get the file path of an AUX shortcode
   * @since 1.0.0
   */
  public function getShortcodeFile(string $shortcodeName): ?string
  {
    return @$this->auxShortcodes[$shortcodeName]['file'];
  }

  /**
   * Get the one instance of the AUX shortcodes handler
   * @since 1.0.0
   */
  public static function instance(): static
  {
    static $instance;

    if (is_null($instance)) {
      $instance = new static();
    }

    return $instance;
  }
}
