<?php
declare(strict_types=1);

namespace WP_AUX\Entities\Posts;

use WP_AUX\Entities\AuxFramework\Partials\CardEntity;
use WP_AUX\Entities\AuxCF\OptionsFields\PostType\PostTypeArchiveFieldEntity;
use WP_AUX\Entities\AuxCF\OptionsFields\PostType\PostTypeOptionsFeaturedPostsFieldEntity;
use WP_AUX\Entities\AuxCF\PageFields\Taxonomy\TaxonomyFeaturedPostsFieldEntity;
use WP_AUX\Services\PostService;
use WP_AUX\Services\PostTypeService;
use WP_AUX\Services\StoryService;
use WP_AUX\Services\TaxonomyTermsService;

/**
 * Entity for retrieving featured posts and producing AUX Card entities for rendering
 * @since 1.0.0
 */
class FeaturedPostsEntity
{
  protected array $posts = [];
  protected string $label = '';
  /**
   * @var string[]
   */
  protected array $postTypes = [];

  public function __construct() {
    $posts = [];

    $queriedObject = get_queried_object();
    if (isset($queriedObject->term_id)) {
      $posts = TaxonomyTermsService::getTermField(
        TaxonomyFeaturedPostsFieldEntity::$name,
        $queriedObject->term_id
      );
    } elseif ($queriedObject instanceof \WP_Post_Type) {
      $posts = PostTypeService::getArchiveOption(
        $queriedObject->name,
        PostTypeOptionsFeaturedPostsFieldEntity::class
      );
    }

    if ($posts) {
      $this->posts = $posts;
      $this->prepareDataFromPosts();
    }
  }

  /**
   * Prepare all of the featured posts data from the posts array
   * @since 1.0.0
   */
  protected function prepareDataFromPosts(): void
  {
    $labelKey = 'name';
    if (count($this->posts) === 1) {
      $labelKey = 'singular_name';
    }

    $postTypes = [];
    foreach ($this->posts as $featuredPost) {
      $postTypes[] = $featuredPost->post_type;
    }
    $this->postTypes = array_unique($postTypes);

    if (count($this->postTypes) === 1) {
      $this->label = PostService::getPostTypeLabel($postTypes[0], $labelKey);
    } else {
      $this->label = PostService::getPostTypeLabel('post', $labelKey);
    }
  }

  /**
   * Get all of the AUX cards for the featured posts
   *
   * After every post card is created, the 'aux/featured_post_card' action is run on the card.
   * The card entity and the featured \WP_Post item for the card are the two arguments
   * passed with this action.
   *
   * @return CardEntity[]
   * @since 1.0.0
   */
  public function getCards(): array
  {
    $cards = [];

    foreach ($this->posts as $featuredPost) {
      $card = PostService::postCard($featuredPost, true, false, true);
      $card
        ->addStyle('read-time', 'on-dark')
        ->setSubheader(StoryService::getOriginalDate($featuredPost));

      do_action('aux/featured_post_card', $card, $featuredPost);

      $cards[$featuredPost->ID] = $card;
    }

    return $cards;
  }

  /**
   * Get the compiled HTML for all the featured posts
   * @since 1.0.0
   */
  public function getCardsContent(): string
  {
    $cardsContent = '';

    $cards = $this->getCards();
    foreach ($cards as $card) {
      $cardsContent .= $card;
    }

    return $cardsContent;
  }

  /**
   * Get the label for the featured posts
   *
   * If the there is more than one post type featured, the label will be the plural
   * label of the 'post' type if there is more than one featured post, or the singular
   * label of the 'post' type if there is only one featrued post.
   *
   * If there is only one post type featured, the label will be the plural label
   * of the post type if there is more than one featured post, or the singular label
   * of the post type if there is only one featured post.
   *
   * @since 1.0.0
   */
  public function getLabel(): string
  {
    return $this->label;
  }

  /**
   * Get a list of all of the post types that are featured
   * @return string[]
   * @since 1.0.0
   */
  public function getPostTypes(): array
  {
    return $this->postTypes;
  }

  /**
   * Get the number of featured posts
   * @since 1.0.0
   */
  public function getCount(): int
  {
    return count($this->posts);
  }
}
