<?php

namespace MovieEngine\Frontend;

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

class Query {

    public function __construct() {
        add_action('pre_get_posts', [$this, 'modify_query']);
        add_action('init', [$this, 'add_playlist_rewrite']);
        add_action('init', [$this, 'add_player_endpoint']);
        add_filter('query_vars', [$this, 'add_playlist_query_vars']);
        add_action('template_redirect', [$this, 'playlist_template_redirect'], 1);
        add_action('template_redirect', [$this, 'player_page_redirect'], 1);
    }


    public function add_playlist_rewrite() {
        $options = get_option('movie_engine_player_settings', []);
        $slug = isset($options['playlist_slug']) && !empty($options['playlist_slug']) ? trim($options['playlist_slug'], '/') : 'movie-engine-playlist';

        add_rewrite_rule($slug . '/?$', 'index.php?movie_engine_playlist_page=1', 'top');
        add_rewrite_tag('%movie_engine_playlist_page%', '([^&]+)');
    }


    public function add_player_endpoint() {
        add_rewrite_endpoint('player', EP_PERMALINK);

        if (get_option('movie_engine_player_endpoint_flush')) {
            return;
        }

        update_option('movie_engine_flush_rewrite_rules', true);
        update_option('movie_engine_player_endpoint_flush', true);
    }


    public function add_playlist_query_vars($vars) {
        $vars[] = 'movie_engine_playlist_page';
        $vars[] = 'playlist';
        $vars[] = 'v';
        $vars[] = 'player';
        return $vars;
    }


    public function playlist_template_redirect() {
        if (get_query_var('movie_engine_playlist_page')) {
            \MovieEngine\Utils\TemplateLoader::get_template_part('pages/page-playlist');
            exit;
        }
    }


    /**
     * Handle player page template redirect
     */
    public function player_page_redirect() {
        global $wp_query;

        if (!isset($wp_query->query_vars['player'])) {
            return;
        }

        $post = get_queried_object();
        if (!$post || !($post instanceof \WP_Post)) {
            return;
        }

        $post_id = $post->ID;
        $post_type = $post->post_type;

        if (!in_array($post_type, ['movie_engine_movie', 'movie_engine_series', 'movie_engine_episode'])) {
            return;
        }

        // Security check: If restricted and no partial paywall (preview), redirect back to main page
        $is_restricted = \MovieEngine\Payments\Membership::is_restricted($post_id);
        $partial_paywall_duration = apply_filters('movie_engine_partial_paywall_duration', false, $post_id);

        if ($is_restricted && !$partial_paywall_duration) {
            wp_safe_redirect(get_permalink($post_id));
            exit;
        }

        \MovieEngine\Utils\TemplateLoader::get_template_part('pages/player-page');
        exit;
    }


    public function modify_query($query) {
        if (is_admin() || ! $query->is_main_query()) {
            return;
        }

        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- GET request for search/filter params
        $is_me_search = (isset($_GET['movie_engine_search']) && $_GET['movie_engine_search'] == '1');

        if (
            $query->is_post_type_archive(['movie_engine_movie', 'movie_engine_series', 'movie_engine_episode', 'movie_engine_person']) ||
            is_tax(get_object_taxonomies(['movie_engine_movie', 'movie_engine_series', 'movie_engine_episode', 'movie_engine_year', 'movie_engine_genre'])) ||
            $query->is_search() ||
            $is_me_search
        ) {

            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            $series_id = isset($_GET['series_id']) ? intval($_GET['series_id']) : 0;
            if ($series_id) {
                $meta_query = $query->get('meta_query') ?: [];
                $meta_query[] = [
                    'key'   => '_movie_engine_series_id',
                    'value' => $series_id,
                ];
                $query->set('meta_query', $meta_query);
            }

            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            $season = isset($_GET['season']) ? intval($_GET['season']) : 0;
            if ($season) {
                $meta_query = $query->get('meta_query') ?: [];
                $meta_query[] = [
                    'key'   => '_movie_engine_season_number',
                    'value' => $season,
                ];
                $query->set('meta_query', $meta_query);
            }
            $design_settings = get_option('movie_engine_design_settings', []);

            if ($query->is_search()) {
                // phpcs:ignore WordPress.Security.NonceVerification.Recommended
                $is_movie_engine_search = isset($_GET['movie_engine_search']) && $_GET['movie_engine_search'] == '1';
                $current_post_type = $query->get('post_type');

                if ($is_movie_engine_search || (is_array($current_post_type) && in_array('movie_engine_movie', $current_post_type))) {
                    $limit = isset($design_settings['search_items_per_page']) ? intval($design_settings['search_items_per_page']) : 20;
                    $query->set('posts_per_page', $limit);
                }
            } else {
                $limit = isset($design_settings['archive_items_per_page']) ? intval($design_settings['archive_items_per_page']) : 20;
                $query->set('posts_per_page', $limit);
            }

            // --- MovieEngine Filter Support for Main Query ---
            
            // Check if this is a MovieEngine search/filter request (even on a static page)
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- GET request for search/filter params
            $is_me_search = (isset($_GET['movie_engine_search']) && $_GET['movie_engine_search'] == '1');

            // Taxonomy Filters (Genre, Year)
            $tax_query = $query->get('tax_query') ?: [];
            
            // Genre Filter
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- GET request for filter params
            $genre = isset($_GET['movie_engine_genre']) ? sanitize_text_field(wp_unslash($_GET['movie_engine_genre'])) : '';
            if (!empty($genre)) {
                $tax_query[] = [
                    'taxonomy' => 'movie_engine_genre',
                    'field'    => 'slug',
                    'terms'    => $genre,
                ];
            }

            // Year Filter
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- GET request for filter params
            $year = isset($_GET['movie_engine_year']) ? sanitize_text_field(wp_unslash($_GET['movie_engine_year'])) : '';
            if (!empty($year)) {
                $tax_query[] = [
                    'taxonomy' => 'movie_engine_year',
                    'field'    => 'slug',
                    'terms'    => $year,
                ];
            }

            if (!empty($tax_query)) {
                $query->set('tax_query', $tax_query);
            }

            // Post Type Filter
            // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- GET request for filter params
            $me_post_type = isset($_GET['me_post_type']) ? sanitize_text_field(wp_unslash($_GET['me_post_type'])) : (isset($_GET['post_type']) ? sanitize_text_field(wp_unslash($_GET['post_type'])) : '');
            if (!empty($me_post_type)) {
                $query->set('post_type', $me_post_type);
            } elseif ($is_me_search) {
                // Default post types for MovieEngine search if none specified
                $query->set('post_type', ['movie_engine_movie', 'movie_engine_series']);
            }

            if ($query->is_search()) {
                // phpcs:ignore WordPress.Security.NonceVerification.Recommended
                $is_movie_engine_search = isset($_GET['movie_engine_search']) && $_GET['movie_engine_search'] == '1';
                $current_post_type = $query->get('post_type');

                if ($is_movie_engine_search || (is_array($current_post_type) && in_array('movie_engine_movie', $current_post_type))) {

                    // phpcs:ignore WordPress.Security.NonceVerification.Recommended
                    if (empty($_GET['post_type'])) {
                        $query->set('post_type', ['movie_engine_movie', 'movie_engine_series']);
                    }
                }
            }

            // phpcs:ignore WordPress.Security.NonceVerification.Recommended
            $orderby_param = isset($_GET['orderby']) ? sanitize_text_field(wp_unslash($_GET['orderby'])) : '';

            if (! empty($orderby_param)) {
                $orderby = $orderby_param;

                switch ($orderby) {
                    case 'title':
                        $query->set('orderby', 'title');
                        $query->set('order', 'ASC');
                        break;
                    case 'rating':
                        $query->set('meta_key', '_movie_engine_rating');
                        $query->set('orderby', 'meta_value_num');
                        $query->set('order', 'DESC');
                        break;
                    case 'views':
                        $query->set('meta_key', '_movie_engine_views');
                        $query->set('orderby', 'meta_value_num');
                        $query->set('order', 'DESC');
                        break;
                    case 'upcoming':
                        $query->set('meta_key', '_movie_engine_release_date');
                        $query->set('orderby', 'meta_value');
                        $query->set('order', 'ASC');
                        $query->set('meta_query', [
                            [
                                'key'     => '_movie_engine_release_date',
                                'value'   => gmdate('Y-m-d'),
                                'compare' => '>',
                                'type'    => 'DATE'
                            ]
                        ]);
                        break;
                    case 'date':
                    default:
                        $query->set('orderby', 'date');
                        $query->set('order', 'DESC');
                        break;
                }
            }
        }
    }


    public static function get_related_posts($post_id, $limit = 6, $relation_type = 'genre') {
        $post_type = get_post_type($post_id);

        $args = [
            'post_type'      => $post_type,
            'posts_per_page' => $limit,
            // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_post__not_in
            'post__not_in'   => [$post_id],
            'orderby'        => 'rand',
        ];

        $design_settings = get_option('movie_engine_design_settings', []);
        $relation_logic = $design_settings['movie_related_logic'] ?? $relation_type;

        switch ($relation_logic) {
            case 'director':
                $directors = wp_get_post_terms($post_id, 'movie_engine_director', ['fields' => 'ids']);
                if (!empty($directors) && !is_wp_error($directors)) {
                    // phpcs:ignore WordPress.DB.SlowDBQuery
                    $args['tax_query'] = [
                        [
                            'taxonomy' => 'movie_engine_director',
                            'field'    => 'term_id',
                            'terms'    => $directors,
                        ]
                    ];
                }
                break;

            case 'cast':
                $cast = get_post_meta($post_id, '_movie_engine_cast', true);
                if (!empty($cast) && is_array($cast)) {
                    $cast_names = array_column($cast, 'name');
                    if (!empty($cast_names)) {
                        // phpcs:ignore WordPress.DB.SlowDBQuery
                        $args['meta_query'] = [
                            [
                                'key'     => '_movie_engine_cast',
                                'value'   => $cast_names[0],
                                'compare' => 'LIKE'
                            ]
                        ];
                    }
                }
                break;

            case 'tags':
                $tags = wp_get_post_terms($post_id, 'movie_engine_tag', ['fields' => 'ids']);
                if (!empty($tags) && !is_wp_error($tags)) {
                    // phpcs:ignore WordPress.DB.SlowDBQuery
                    $args['tax_query'] = [
                        [
                            'taxonomy' => 'movie_engine_tag',
                            'field'    => 'term_id',
                            'terms'    => $tags,
                        ]
                    ];
                }
                break;

            case 'year':
                $years = wp_get_post_terms($post_id, 'movie_engine_year', ['fields' => 'ids']);
                if (!empty($years) && !is_wp_error($years)) {
                    // phpcs:ignore WordPress.DB.SlowDBQuery
                    $args['tax_query'] = [
                        [
                            'taxonomy' => 'movie_engine_year',
                            'field'    => 'term_id',
                            'terms'    => $years,
                        ]
                    ];
                }
                break;

            case 'country':
                $countries = wp_get_post_terms($post_id, 'movie_engine_country', ['fields' => 'ids']);
                if (!empty($countries) && !is_wp_error($countries)) {
                    // phpcs:ignore WordPress.DB.SlowDBQuery
                    $args['tax_query'] = [
                        [
                            'taxonomy' => 'movie_engine_country',
                            'field'    => 'term_id',
                            'terms'    => $countries,
                        ]
                    ];
                }
                break;

            case 'language':
                $languages = wp_get_post_terms($post_id, 'movie_engine_language', ['fields' => 'ids']);
                if (!empty($languages) && !is_wp_error($languages)) {
                    // phpcs:ignore WordPress.DB.SlowDBQuery
                    $args['tax_query'] = [
                        [
                            'taxonomy' => 'movie_engine_language',
                            'field'    => 'term_id',
                            'terms'    => $languages,
                        ]
                    ];
                }
                break;

            case 'mixed':
                $genres = wp_get_post_terms($post_id, 'movie_engine_genre', ['fields' => 'ids']);
                $directors = wp_get_post_terms($post_id, 'movie_engine_director', ['fields' => 'ids']);

                $tax_queries = [];
                if (!empty($genres) && !is_wp_error($genres)) {
                    $tax_queries[] = [
                        'taxonomy' => 'movie_engine_genre',
                        'field'    => 'term_id',
                        'terms'    => $genres,
                    ];
                }
                if (!empty($directors) && !is_wp_error($directors)) {
                    $tax_queries[] = [
                        'taxonomy' => 'movie_engine_director',
                        'field'    => 'term_id',
                        'terms'    => $directors,
                    ];
                }

                if (!empty($tax_queries)) {
                    // phpcs:ignore WordPress.DB.SlowDBQuery
                    $args['tax_query'] = $tax_queries;
                    $args['tax_query']['relation'] = 'OR';
                }
                break;

            case 'genre':
            default:
                $genres = wp_get_post_terms($post_id, 'movie_engine_genre', ['fields' => 'ids']);
                if (!empty($genres) && !is_wp_error($genres)) {
                    // phpcs:ignore WordPress.DB.SlowDBQuery
                    $args['tax_query'] = [
                        [
                            'taxonomy' => 'movie_engine_genre',
                            'field'    => 'term_id',
                            'terms'    => $genres,
                        ]
                    ];
                }
                break;
        }

        return new \WP_Query($args);
    }


    /**
     * Get posts by type (trending, new_releases, upcoming, related)
     * 
     * @param string $type The type of posts to retrieve
     * @param int $limit Number of posts to retrieve
     * @param int $exclude_id Post ID to exclude
     * @return \WP_Query
     */
    public static function get_posts_by_type($type, $limit = 6, $exclude_id = 0, $post_types = null) {

        if ($post_types === null) {
            $post_types = ['movie_engine_movie', 'movie_engine_series'];
        }

        $args = [
            'post_type'      => $post_types,
            'posts_per_page' => $limit,
            'post_status'    => 'publish',
        ];

        if ($exclude_id > 0) {
            // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_post__not_in
            $args['post__not_in'] = [$exclude_id];
        }

        switch ($type) {
            case 'trending':
                // phpcs:ignore WordPress.DB.SlowDBQuery
                $args['meta_key'] = '_movie_engine_views';
                $args['orderby'] = 'meta_value_num';
                $args['order'] = 'DESC';
                break;

            case 'new_releases':
                $args['orderby'] = 'date';
                $args['order'] = 'DESC';
                break;

            case 'upcoming':
                // phpcs:ignore WordPress.DB.SlowDBQuery
                $args['meta_key'] = '_movie_engine_release_date';
                $args['orderby'] = 'meta_value';
                $args['order'] = 'ASC';
                // phpcs:ignore WordPress.DB.SlowDBQuery
                $args['meta_query'] = [
                    [
                        'key'     => '_movie_engine_release_date',
                        'value'   => gmdate('Y-m-d'),
                        'compare' => '>',
                        'type'    => 'DATE'
                    ]
                ];
                break;

            case 'related':
                if ($exclude_id > 0) {
                    return self::get_related_posts($exclude_id, $limit);
                }
                break;

            default:
                $args['orderby'] = 'date';
                $args['order'] = 'DESC';
                break;
        }

        return new \WP_Query($args);
    }
}
