<?php

namespace FleekDash\Controllers\Post;

use FleekDash\Services\ResponseService;

/**
 * Post schema provider
 *
 * Provides schema information about post types and their taxonomies.
 * Used by the frontend to build dynamic forms and filters.
 *
 * @package FleekDash\Controllers\Post
 * @since 2.2.0
 */
class PostSchemaProvider
{
    /**
     * Get all registered post types
     *
     * @param \WP_REST_Request $request
     * @return \WP_REST_Response
     */
    public static function getPostTypes($request)
    {
        try {
            $args = [
                'public' => true
            ];

            if ($request->get_param('show_all')) {
                unset($args['public']);
            }

            $post_types = \get_post_types($args, 'objects');
            $formatted_post_types = [];

            foreach ($post_types as $post_type) {
                $formatted_post_types[] = [
                    'name' => $post_type->name,
                    'label' => $post_type->label,
                    'description' => $post_type->description,
                    'hierarchical' => $post_type->hierarchical,
                    'supports' => get_all_post_type_supports($post_type->name)
                ];
            }

            return ResponseService::success($formatted_post_types);

        } catch (\Exception $e) {
            return ResponseService::error('Failed to fetch post types: ' . $e->getMessage());
        }
    }

    /**
     * Get all taxonomies for a post type
     *
     * @param \WP_REST_Request $request
     * @return \WP_REST_Response
     */
    public static function getTaxonomies($request)
    {
        try {
            $post_type = $request->get_param('post_type') ?? 'post';

            // Check if post type exists
            if (!\post_type_exists($post_type)) {
                return ResponseService::error("Invalid post type: {$post_type}", null, 400);
            }

            // Check cache first (5 minutes TTL)
            $cache_key = 'fleekdash_taxonomies_' . \sanitize_key($post_type);
            $cached = \get_transient($cache_key);

            // Check if cache is stale due to pending invalidation (race condition prevention)
            // If CacheInvalidationManager has scheduled invalidation, don't use stale cache
            if ($cached !== false) {
                // Get cache creation timestamp from separate transient
                // _transient_timeout_* stores expiration time, not creation time
                // We store creation timestamp separately when cache is created
                $cache_timestamp_key = $cache_key . '_timestamp';
                $cache_timestamp = \get_transient($cache_timestamp_key);

                // If timestamp not found, check if invalidation exists before forcing regeneration
                // If no invalidation has occurred, cache is fresh (no need to regenerate)
                // If invalidation exists, force regeneration by setting timestamp to 0
                if ($cache_timestamp === false) {
                    // Check if any invalidation has occurred (use same key as CacheInvalidationManager)
                    $invalidation_version = \get_transient('fleekdash_cache_invalidation_version');
                    if ($invalidation_version === false) {
                        // No invalidation has occurred - cache is fresh even without timestamp
                        return ResponseService::success($cached);
                    }
                    // Invalidation exists - force regeneration (timestamp = 0 will make isCacheStale return true)
                    $cache_timestamp = 0;
                }

                // Check if cache was invalidated after it was created
                $invalidation_manager = \FleekDash\Core\CacheInvalidationManager::getInstance();
                if (!\FleekDash\Core\CacheInvalidationManager::isCacheStale($cache_key, $cache_timestamp)) {
                    return ResponseService::success($cached);
                }
                // Cache is stale - regenerate below
            }

            $taxonomies = get_object_taxonomies($post_type, 'objects');
            $formatted_taxonomies = [];

            foreach ($taxonomies as $taxonomy) {
                // Limit terms per taxonomy for performance
                $terms = \get_terms([
                    'taxonomy' => $taxonomy->name,
                    'hide_empty' => false,
                    'number' => 200
                ]);

                $formatted_terms = [];
                if (!is_wp_error($terms)) {
                    foreach ($terms as $term) {
                        $formatted_terms[] = [
                            'id' => $term->term_id,
                            'name' => $term->name,
                            'slug' => $term->slug,
                            'count' => $term->count
                        ];
                    }
                }

                $formatted_taxonomies[] = [
                    'name' => $taxonomy->name,
                    'label' => $taxonomy->label,
                    'hierarchical' => $taxonomy->hierarchical,
                    'terms' => $formatted_terms
                ];
            }

            // Cache for 5 minutes
            $cache_timestamp = time();
            \set_transient($cache_key, $formatted_taxonomies, 5 * MINUTE_IN_SECONDS);
            // Store creation timestamp separately for accurate staleness detection
            \set_transient($cache_key . '_timestamp', $cache_timestamp, 5 * MINUTE_IN_SECONDS);

            return ResponseService::success($formatted_taxonomies);

        } catch (\Exception $e) {
            return ResponseService::error('Failed to fetch taxonomies: ' . $e->getMessage());
        }
    }
}
