<?php

// If this file is called directly, abort.
if (! defined('ABSPATH')) {
	exit;
}

class PostsController {

	private $taxonomyCache = [];

	public function getPosts() {

		$post_types = get_post_types([
			'public' => true,
			'_builtin' => false,
		]);
		$post_types[] = 'post';

		$exclude = ['page', 'attachment', 'revision', 'nav_menu_item', 'product'];
		$post_types = array_diff($post_types, $exclude);

		$args = [
			'post_type' => $post_types,
			'post_status' => 'publish',
			'numberposts' => -1
		];

		$posts = get_posts($args);

		if (empty($posts)) {
			return [];
		}

		// Caching posts and their taxonomies
		update_post_caches($posts, $post_types, true, true);
		$post_ids = wp_list_pluck($posts, 'ID');
		update_object_term_cache($post_ids, $post_types);

		$author_ids = array_unique(wp_list_pluck($posts, 'post_author'));
		$authors = get_users([
			'include' => $author_ids,
			'fields' => ['ID', 'user_nicename', 'display_name'],
		]);
		$authorsMap = [];
		foreach ($authors as $author) {
			$authorsMap[$author->ID] = [
				'nicename' => $author->display_name ?: $author->user_nicename,
				'url' => esc_url(get_author_posts_url($author->ID))
			];
		}

		$result = [];
		foreach ($posts as $post) {
			$taxonomyData = $this->getPostTaxonomyData($post);

			$result[] = [
				'id' => (int) $post->ID,
				'title' => get_the_title($post->ID) ?? "",
				'link' => get_permalink($post->ID),
				'description' => $post->post_content ?? "",
				'image_path' => $this->getPostImage($post),
				'categories' => $taxonomyData['categories'],
				'tags' => $taxonomyData['tags'],
				'post_date' => $post->post_date,
				'post_modified' => $post->post_modified,
				'author' => isset($authorsMap[$post->post_author]) ? [$post->post_author => $authorsMap[$post->post_author]] : [],
				'post_status' => $post->post_status
			];
		}

		return $result;
	}

	private function getShortDescription($post) {
		if (!empty($post->post_excerpt)) {
			return $post->post_excerpt;
		}
		return mb_substr(strip_tags($post->post_content), 0, 350);
	}

	private function getPostImage($post) {
		$imageId = get_post_thumbnail_id($post->ID);
		if ($imageId) {
			$imageUrl = wp_get_attachment_url($imageId);
			if ($imageUrl) {
				return $imageUrl;
			}
		}
		return null;
	}

	private function getPostTaxonomyData($post) {
		$categories = [];
		$tags = [];

		$post_categories = wp_get_post_terms($post->ID, 'category');
		if (!is_wp_error($post_categories) && !empty($post_categories)) {
			foreach ($post_categories as $term) {
				$categories[$term->term_id] = [
					'name' => $term->name,
					'url'  => esc_url(get_term_link($term)),
				];
			}
		}

		$post_tags = wp_get_post_terms($post->ID, 'post_tag');
		if (!is_wp_error($post_tags) && !empty($post_tags)) {
			foreach ($post_tags as $term) {
				$tags[$term->term_id] = [
					'name' => $term->name,
					'url'  => esc_url(get_term_link($term)),
				];
			}
		}

		if ($post->post_type !== 'post') {
			if (!isset($this->taxonomyCache[$post->post_type])) {
				$this->taxonomyCache[$post->post_type] = get_object_taxonomies($post->post_type, 'objects');
			}

			foreach ($this->taxonomyCache[$post->post_type] as $taxonomyName => $taxonomy) {
				if (in_array($taxonomyName, ['category', 'post_tag'], true)) {
					continue;
				}

				$terms = wp_get_post_terms($post->ID, $taxonomyName);
				if (is_wp_error($terms) || empty($terms)) continue;

				foreach ($terms as $term) {
					$item = [
						'name' => $term->name,
						'url' => esc_url(get_term_link($term)),
					];

					if ($taxonomy->hierarchical) {
						$categories[$term->term_id] = $item;
					} else {
						$tags[$term->term_id] = $item;
					}
				}
			}
		}

		return [
			'categories' => $categories,
			'tags' => $tags,
		];
	}
}