<?php

namespace MailerPress\Api;

use MailerPress\Core\Attributes\Endpoint;
use WP_Error;
use WP_HTTP_Response;
use WP_REST_Request;
use WP_REST_Response;

class Postype
{
    #[Endpoint(
        'public-post-types',
        methods: 'GET',
        permissionCallback: [Permissions::class, 'canView']
    )]
    public function getPublicPostTypes(WP_REST_Request $request): WP_Error|WP_HTTP_Response|WP_REST_Response
    {
        // Get public post types as objects
        $post_types = get_post_types(
            [
                'public' => true,
                'show_ui' => true,
            ],
            'objects'
        );

        unset(
            $post_types['attachment'],
            $post_types['seopress_rankings'],
            $post_types['seopress_backlinks'],
            $post_types['seopress_404'],
            $post_types['elementor_library'],
            $post_types['customer_discount'],
            $post_types['cuar_private_file'],
            $post_types['cuar_private_page'],
            $post_types['ct_template'],
            $post_types['bricks_template'],
            $post_types['e-floating-buttons']
        );


        $post_types = apply_filters('mailerpress_post_types_public', $post_types);

        $data = [];

        foreach ($post_types as $slug => $post_type) {
            $data[] = [
                'label' => $post_type->labels->name,
                'value' => $slug,
            ];
        }

        return rest_ensure_response($data);
    }


    #[Endpoint(
        'posts',
        methods: 'GET',
        permissionCallback: [Permissions::class, 'canView']
    )]
    public function getPosts(WP_REST_Request $request): WP_Error|WP_HTTP_Response|WP_REST_Response
    {
        $post_type = $request->get_param('postType') ?? 'post';

        if (!post_type_exists($post_type)) {
            return new WP_Error('invalid_post_type', 'Invalid post type.', ['status' => 400]);
        }

        $args = [
            'post_type' => $post_type,
            'post_status' => 'publish',
            'posts_per_page' => $request->get_param('per_page') ?? 10,
            'orderby' => $request->get_param('orderby') ?? 'date',
            'order' => $request->get_param('order') ?? 'DESC',
            's' => $request->get_param('search'),
            'paged' => $request->get_param('page') ?? 1,
            // ✅ Optimization: Suppress filters to avoid heavy hooks from WooCommerce and other plugins
            'suppress_filters' => true,
        ];

        // Handle taxonomy filters
        $taxQuery = [];

        // Get all taxonomies for this post type
        $taxonomies = get_object_taxonomies($post_type, 'objects');

        $taxonomyMap = [];
        foreach ($taxonomies as $taxonomy) {
            // Special mapping for standard taxonomies
            if ($taxonomy->name === 'category') {
                $taxonomyMap['categories'] = $taxonomy;
            } elseif ($taxonomy->name === 'post_tag') {
                $taxonomyMap['tags'] = $taxonomy;
            }

            // Use rest_base as the main key
            $restBase = $taxonomy->rest_base ?? $taxonomy->name;
            $taxonomyMap[$restBase] = $taxonomy;

            // Also map by taxonomy name (for compatibility)
            $taxonomyMap[$taxonomy->name] = $taxonomy;
        }

        // Get all request parameters
        $allParams = $request->get_params();

        // Loop through all parameters to find those that match taxonomies
        foreach ($allParams as $paramKey => $paramValue) {
            // Ignore already processed or non-taxonomy parameters
            if (in_array($paramKey, ['postType', 'per_page', 'orderby', 'order', 'search', 'page', 'author'])) {
                continue;
            }

            // Check if this parameter corresponds to a taxonomy
            if (isset($taxonomyMap[$paramKey]) && !empty($paramValue)) {
                $taxonomy = $taxonomyMap[$paramKey];

                // Convert value to array of IDs
                $termIds = is_array($paramValue) ? $paramValue : explode(',', $paramValue);
                $termIds = array_filter(array_map('intval', $termIds));

                if (!empty($termIds)) {
                    $taxQuery[] = [
                        'taxonomy' => $taxonomy->name,
                        'field' => 'term_id',
                        'terms' => $termIds,
                    ];
                }
            }
        }

        // Add tax_query if taxonomies are specified
        if (!empty($taxQuery)) {
            $args['tax_query'] = $taxQuery;
        }

        // Handle author filters
        $author = $request->get_param('author');
        if (!empty($author)) {
            $authorIds = is_array($author) ? $author : explode(',', $author);
            $args['author__in'] = array_map('intval', $authorIds);
        }

        $query = new \WP_Query($args);

        $data = [];

        foreach ($query->posts as $post) {
            // ensure $post is object WP_Post
            if (is_array($post)) {
                $post = (object)$post;
            }
            $response = rest_ensure_response($post);

            $filtered = apply_filters("mailerpress_rest_prepare_{$post_type}", $response, $post, $request);
            $data[] = $filtered instanceof WP_REST_Response ? $filtered->get_data() : $filtered;
        }

        // Optional: add pagination headers
        $total = (int)$query->found_posts;
        $max_pages = (int)$query->max_num_pages;

        $response = rest_ensure_response($data);
        $response->header('X-WP-Total', $total);
        $response->header('X-WP-TotalPages', $max_pages);

        return $response;
    }
}
