<?php
declare(strict_types=1);

namespace WP_AUX\Entities;

use WP_AUX\Services\HeadService;

class AcfFieldGroupsViewerEntity
{
  public const AUX_COMPONENT_PREFIX = 'AUX';
  public const AUX_STATE_KEY = 'auxState';

  protected array $acfAuxIds = [];
  protected array $acfNotAuxIds = [];
  protected ?int $auxState = null;

  protected function __construct() {
    $this->auxState = self::getRequestedAuxState();
    $this->acfAuxIds = self::getAcfIds();
    $this->acfNotAuxIds = self::getAcfIds(true);
  }

  public function getAuxState(): ?int {
    return $this->auxState;
  }

  public function getAcfAuxIds(): array
  {
    return $this->acfAuxIds;
  }

  public function getAcfNotAuxIds(): array
  {
    return $this->acfNotAuxIds;
  }

  public static function acfListQuery(\WP_Query $query): void {
    $acfFieldGroupsViewer = self::instance();
    $auxState = $acfFieldGroupsViewer->getAuxState();

    if (
      null !== $auxState &&
      $query->is_main_query()
    ) {
      $query->query_vars['post__in'] = $auxState ? $acfFieldGroupsViewer->getAcfAuxIds() : $acfFieldGroupsViewer->getAcfNotAuxIds();
    }
  }

  public static function acfListViewsFilter(array $views): array
  {
    $acfFieldGroupsViewer = self::instance();

    if (!$acfFieldGroupsViewer->getAcfAuxIds()) {
      return $views;
    }

    $auxState = $acfFieldGroupsViewer->getAuxState();

    $acfOptions = [
      1 => count($acfFieldGroupsViewer->getAcfAuxIds()),
      0 => count($acfFieldGroupsViewer->getAcfNotAuxIds()),
    ];

    foreach ($acfOptions as $auxValue => $idsCount) {
      $label = $auxValue ? 'AUX Components' : 'Standard Field Groups';
      $attrString = '';

      if ($auxValue === $auxState) {
        $attrString = ' class="current" aria-current="page"';
      }

      $queryString = self::AUX_STATE_KEY . '=' . $auxValue;

      $views[] = sprintf(
        '<a href="edit.php?post_type=acf-field-group&%s" %s>%s <span class="count">(%s)</span></a>',
        $queryString, $attrString, $label, $idsCount
      );
    }

    return $views;
  }

  protected static function getAcfIds(bool $not = false) {
    global $wpdb;

    $prefix = self::AUX_COMPONENT_PREFIX;
    $operator = $not ? 'NOT LIKE' : 'LIKE';

    return (array) $wpdb->get_col("SELECT ID FROM $wpdb->posts WHERE post_title {$operator} '{$prefix} %' AND post_type = 'acf-field-group' AND post_status != 'auto-draft' ");
  }

  protected static function getRequestedAuxState(): ?int
  {
    if (!isset($_GET[self::AUX_STATE_KEY])) {
      return null;
    }

    return intval($_GET[self::AUX_STATE_KEY]);
  }

  public static function isAcfFieldGroupsListScreen(): bool
  {
    global $pagenow;
    return 'edit.php' === $pagenow && 'acf-field-group' === @$_GET['post_type'];
  }

  public static function isAcfFieldGroupsPostScreen(): bool
  {
    global $pagenow;

    return (
      ('post.php' === $pagenow && isset($_GET['post']) && 'acf-field-group' === get_post_type($_GET['post'])) ||
      ('post-new.php' === $pagenow && isset($_GET['post_type']) && 'acf-field-group' === $_GET['post_type'])
    );
  }

  protected static function appendAuxState(string $url, int $auxState): string
  {
    return $url . '&' . self::AUX_STATE_KEY . '=' . $auxState;
  }

  public static function register(): void
  {
    add_action('admin_init', function() {
      if (!self::isAcfFieldGroupsListScreen() && !self::isAcfFieldGroupsPostScreen()) {
        return;
      }

      $auxFieldGroupsViewer = self::instance();

      $inlineScript = [
        "const AUX_COMPONENT_PREFIX = '". self::AUX_COMPONENT_PREFIX . "';",
        "const AUX_STATE_KEY = '". self::AUX_STATE_KEY . "';",
      ];
      wp_add_inline_script('acf-submenu', join("\n", $inlineScript), 'before');

      add_action('views_edit-acf-field-group', [self::class, 'acfListViewsFilter']);
      add_action('parse_query', [self::class, 'acfListQuery']);

      if (null !== $auxFieldGroupsViewer->getAuxState()) {
        add_filter('admin_url', function(string $url) use ($auxFieldGroupsViewer) {
          if (substr_count($url, 'post-new.php?post_type=acf-field-group')) {
            return self::appendAuxState($url, $auxFieldGroupsViewer->getAuxState());
          }

          return $url;
        });

        if (self::isAcfFieldGroupsListScreen()) {
          add_filter('get_edit_post_link', function(string $url) use ($auxFieldGroupsViewer) {
            return self::appendAuxState($url, $auxFieldGroupsViewer->getAuxState());
          });
        }
      }
    });
  }

  public static function instance(): AcfFieldGroupsViewerEntity
  {
    static $instance;

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

    return $instance;
  }
}
