<?php

namespace MovieEngine\Utils;

if (! defined("ABSPATH")) {
    exit; // Exit if accessed directly
}

class Helpers {

    /**
     * Null-safe wp_kses_post wrapper for PHP 8.1+ compatibility.
     * Prevents "Passing null to parameter #3 ($subject) of type array|string is deprecated" in kses.php.
     * Handles null, false (e.g. from get_the_term_list), and other non-string values.
     *
     * @param string|false|null $data Content to filter.
     * @return string Filtered content.
     */
    public static function kses_post($data) {
        return wp_kses_post(($data !== null && $data !== false) ? (string) $data : '');
    }

    public static function get_movie_rating($post_id) {
        return get_post_meta($post_id, '_movie_engine_rating', true);
    }

    public static function format_runtime($minutes) {
        $hours = floor($minutes / 60);
        $min   = $minutes % 60;
        return sprintf('%dh %dm', $hours, $min);
    }


    public static function get_terms_by_post_type($taxonomy, $post_type) {
        return self::get_filtered_terms($taxonomy, ['post_type' => $post_type]);
    }

    public static function get_filtered_terms($taxonomy, $args = []) {
        global $wpdb;

        $post_type = $args['post_type'] ?? '';
        $filters   = $args['filters'] ?? [];

        $where = ["tt.taxonomy = %s", "p.post_status = 'publish'"];
        $sql_args = [$taxonomy];

        if (!empty($post_type)) {
            if (!is_array($post_type)) {
                $post_type = strpos($post_type, ',') !== false ? array_map('trim', explode(',', $post_type)) : [$post_type];
            }
            $placeholders = implode(', ', array_fill(0, count($post_type), '%s'));
            $where[] = "p.post_type IN ($placeholders)";
            $sql_args = array_merge($sql_args, $post_type);
        }

        if (!empty($filters)) {
            foreach ($filters as $tax => $slug) {
                if (empty($slug) || $tax === $taxonomy) continue;

                $where[] = "p.ID IN (
                    SELECT sub_tr.object_id 
                    FROM {$wpdb->term_relationships} sub_tr
                    INNER JOIN {$wpdb->term_taxonomy} sub_tt ON sub_tr.term_taxonomy_id = sub_tt.term_taxonomy_id
                    INNER JOIN {$wpdb->terms} sub_t ON sub_tt.term_id = sub_t.term_id
                    WHERE sub_tt.taxonomy = %s AND sub_t.slug = %s
                )";
                $sql_args[] = sanitize_key($tax);
                $sql_args[] = sanitize_title($slug);
            }
        }

        $where_sql = implode(' AND ', $where);

        $cache_key = 'movie_engine_filtered_terms_' . md5($taxonomy . serialize($args));
        $term_ids = wp_cache_get($cache_key, 'movie_engine');

        if (false === $term_ids) {
            $query_template = "
                SELECT DISTINCT t.term_id
                FROM {$wpdb->terms} t
                INNER JOIN {$wpdb->term_taxonomy} tt ON t.term_id = tt.term_id
                INNER JOIN {$wpdb->term_relationships} tr ON tt.term_taxonomy_id = tr.term_taxonomy_id
                INNER JOIN {$wpdb->posts} p ON tr.object_id = p.ID
                WHERE %s
                ORDER BY t.name ASC
            ";

            // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
            $final_query = sprintf($query_template, $where_sql);

            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared
            $term_ids = $wpdb->get_col($wpdb->prepare($final_query, $sql_args));
            wp_cache_set($cache_key, $term_ids, 'movie_engine', 3600);
        }

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

        return get_terms([
            'taxonomy'   => $taxonomy,
            'include'    => $term_ids,
            'hide_empty' => false,
        ]);
    }

    public static function format_number($n) {
        if ($n < 1000) return $n;
        $suffix = ['', 'K', 'M', 'B', 'T'];
        $power = floor(log($n, 1000));
        return round($n / (1000 ** $power), 1, PHP_ROUND_HALF_EVEN) . $suffix[$power];
    }

    public static function render_pagination($paged, $total_pages, $param_name = 'paged') {
        if ($total_pages <= 1) return '';

        $design_settings = get_option('movie_engine_design_settings', []);
        $pagination_type = isset($design_settings['pagination_type']) ? $design_settings['pagination_type'] : 'numbers';

        ob_start();
        echo '<nav class="movie-engine-pagination me-ajax-pagination" data-type="' . esc_attr($pagination_type) . '" data-max-pages="' . esc_attr($total_pages) . '" aria-label="' . esc_attr__('Pagination', 'cine-movie-engine') . '">';

        if ($pagination_type === 'load_more' || $pagination_type === 'infinite') {
            if ($paged < $total_pages) {
                echo '<button class="movie-engine-load-more-btn me-btn me-btn-primary" data-paged="' . esc_attr($paged + 1) . '" aria-label="' . esc_attr__('Load more', 'cine-movie-engine') . '">' . esc_html__('Load More', 'cine-movie-engine') . '</button>';
                if ($pagination_type === 'infinite') {
                    echo '<div class="movie-engine-infinite-trigger" aria-hidden="true"></div>';
                }
            }
        } else {
            $big = 999999999;
            $current_url = add_query_arg($param_name, $big);
            $pagination_links = paginate_links([
                'base'      => str_replace($big, '%#%', esc_url($current_url)),
                'format'    => '',
                'current'   => max(1, $paged),
                'total'     => $total_pages,
                'prev_text' => '<span class="fa-solid fa-angle-left" aria-hidden="true"></span><span class="me-sr-only">' . esc_html__('Previous', 'cine-movie-engine') . '</span>',
                'next_text' => '<span class="fa-solid fa-angle-right" aria-hidden="true"></span><span class="me-sr-only">' . esc_html__('Next', 'cine-movie-engine') . '</span>',
            ]);

            if ($pagination_links) {
                $pagination_links = str_replace('class="prev page-numbers"', 'class="prev page-numbers" aria-label="' . esc_attr__('Previous Page', 'cine-movie-engine') . '"', $pagination_links);
                $pagination_links = str_replace('class="next page-numbers"', 'class="next page-numbers" aria-label="' . esc_attr__('Next Page', 'cine-movie-engine') . '"', $pagination_links);
                // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- kses_post sanitizes HTML output
                echo self::kses_post((string) $pagination_links);
            }
        }
        echo '</nav>';
        return ob_get_clean();
    }

    /**
     * Get unique meta values for a post type
     * 
     * @param string $post_type
     * @param string $meta_key
     * @return array
     */
    public static function get_unique_meta_values($post_type, $meta_key) {
        global $wpdb;
        $cache_key = 'movie_engine_unique_meta_' . md5($post_type . $meta_key);
        $values = wp_cache_get($cache_key, 'movie_engine');

        if (false === $values) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.PreparedSQL.NotPrepared
            $values = $wpdb->get_col($wpdb->prepare(
                "SELECT DISTINCT meta_value FROM {$wpdb->postmeta} pm
                 INNER JOIN {$wpdb->posts} p ON p.ID = pm.post_id
                 WHERE p.post_type = %s AND p.post_status = 'publish' AND pm.meta_key = %s AND pm.meta_value != ''
                 ORDER BY pm.meta_value ASC",
                $post_type,
                $meta_key
            ));
            wp_cache_set($cache_key, $values, 'movie_engine', 3600);
        }

        return $values;
    }

    /**
     * Render item badges (Premium, PPV)
     * 
     * @param int $post_id
     * @param string $mode 'card' or 'hero'
     * @return void
     */
    public static function render_badges($post_id, $mode = 'card', $args = []) {
        if (!apply_filters('movie_engine_is_pro', false)) {
            return;
        }

        $show_premium = $args['show_premium_badge'] ?? true;
        $show_ppv     = $args['show_ppv_badge'] ?? true;

        $is_premium = get_post_meta($post_id, '_movie_engine_is_premium', true);
        $is_premium = ($is_premium === '1' || $is_premium === 'yes' || $is_premium === 'true' || $is_premium === true || $is_premium === 1);

        $sale_price = get_post_meta($post_id, '_movie_engine_sale_price', true);
        $rent_price = get_post_meta($post_id, '_movie_engine_rent_price', true);
        $is_ppv = (!empty($sale_price) && floatval($sale_price) > 0) || (!empty($rent_price) && floatval($rent_price) > 0);

        if (!$is_premium && !$is_ppv) {
            return;
        }

        if ($mode === 'hero') {
            if ($is_premium) {
                echo '<span class="movie-engine-meta-badge me-premium-badge"><i class="fa-solid fa-crown"></i> ' . esc_html__('Premium', 'cine-movie-engine') . '</span>';
            }
            if ($is_ppv) {
                echo '<span class="movie-engine-meta-badge me-ppv-badge"><i class="fa-solid fa-bag-shopping"></i> ' . esc_html__('Pay Per View', 'cine-movie-engine') . '</span>';
            }
            return;
        }

        echo '<div class="movie-engine-card-badges">';
        if ($is_premium && $show_premium) {
            echo '<span class="movie-engine-badge-premium" data-tooltip="' . esc_attr__('Premium', 'cine-movie-engine') . '"><i class="fa-solid fa-crown"></i></span>';
        }
        if ($is_ppv && $show_ppv) {
            echo '<span class="movie-engine-badge-ppv" data-tooltip="' . esc_attr__('Pay Per View', 'cine-movie-engine') . '"><i class="fa-solid fa-bag-shopping"></i></span>';
        }
        echo '</div>';
    }
}
