<?php

namespace MovieEngine\Admin\Dashboard;

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

class Analytics {

    public static function get_dashboard_data() {
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
        $period = isset($_GET['period']) ? absint($_GET['period']) : 7;
        if (!in_array($period, [7, 30, 90])) {
            $period = 7;
        }

        return [
            'period'      => $period,
            'labels'      => self::get_date_labels($period),
            'revenue'     => self::get_revenue_over_time($period),
            'content'     => self::get_content_over_time($period),
            'top_content' => self::get_most_watched(),
            'top_users'   => self::get_top_spenders(),
            'top_searches' => self::get_popular_searches(),
            'stats'       => self::get_overview_stats(),
        ];
    }

    private static function get_overview_stats() {
        global $wpdb;
        $tx_stats = apply_filters('movie_engine_transaction_stats', [
            'revenue' => 0,
            'sales'   => 0
        ]);

        $cache_key = 'movie_engine_analytics_subscribers';
        $subscribers = wp_cache_get($cache_key, 'movie_engine');

        if (false === $subscribers) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
            $subscribers = $wpdb->get_var($wpdb->prepare(
                "SELECT COUNT(DISTINCT user_id) FROM $wpdb->usermeta WHERE meta_key = %s AND meta_value != %s",
                '_movie_engine_active_plan',
                ''
            ));
            wp_cache_set($cache_key, $subscribers, 'movie_engine', 3600);
        }

        $cache_key = 'movie_engine_analytics_total_views';
        $total_views = wp_cache_get($cache_key, 'movie_engine');

        if (false === $total_views) {
            // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
            $total_views = $wpdb->get_var($wpdb->prepare(
                "SELECT SUM(CAST(meta_value AS UNSIGNED)) FROM $wpdb->postmeta WHERE meta_key = %s",
                '_movie_engine_views'
            ));
            wp_cache_set($cache_key, $total_views, 'movie_engine', 3600);
        }
        $total_views = (int) $total_views;

        $total_users = count_users()['total_users'];
        $conversion_rate = ($total_users > 0) ? ($subscribers / $total_users) * 100 : 0;

        return [
            'revenue'     => $tx_stats['revenue'],
            'sales'       => $tx_stats['sales'],
            'subscribers' => (int) $subscribers,
            'total_views' => $total_views,
            'conversion_rate' => number_format($conversion_rate, 1),
            'currency'    => get_option('movie_engine_payments_settings', [])['movie_engine_currency'] ?? (get_option('movie_engine_payments_settings', [])['currency'] ?? 'USD'),
        ];
    }

    private static function get_revenue_over_time($days = 7) {
        global $wpdb;

        // If not Pro, return zeros without caching so a Pro request can still
        // fetch and cache real transaction data later.
        if (!apply_filters('movie_engine_is_pro', false)) {
            return array_fill(0, $days, 0.0);
        }

        $cache_key = 'movie_engine_analytics_revenue_' . $days;
        $results = wp_cache_get($cache_key, 'movie_engine');

        if (false === $results) {
            $results = [];
            for ($i = $days - 1; $i >= 0; $i--) {
                $date = gmdate('Y-m-d', strtotime("-$i days"));

                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
                $revenue = $wpdb->get_var($wpdb->prepare(
                    "SELECT SUM(amount) FROM {$wpdb->prefix}movie_engine_transactions WHERE DATE(created_at) = %s AND status IN (%s, %s)",
                    $date,
                    'completed',
                    'Completed'
                ));
                $results[] = (float)($revenue ?: 0);
            }
            wp_cache_set($cache_key, $results, 'movie_engine', 3600);
        }
        return $results;
    }

    private static function get_content_over_time($days = 7) {
        global $wpdb;
        $cache_key = 'movie_engine_analytics_content_' . $days;
        $results = wp_cache_get($cache_key, 'movie_engine');

        if (false === $results) {
            $results = [];
            for ($i = $days - 1; $i >= 0; $i--) {
                $date = gmdate('Y-m-d', strtotime("-$i days"));
                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
                $count = $wpdb->get_var($wpdb->prepare(
                    "SELECT COUNT(ID) FROM $wpdb->posts WHERE DATE(post_date) = %s AND post_type IN (%s, %s) AND post_status = %s",
                    $date,
                    'movie_engine_movie',
                    'movie_engine_series',
                    'publish'
                ));
                $results[] = (int) $count;
            }
            wp_cache_set($cache_key, $results, 'movie_engine', 3600);
        }
        return $results;
    }

    private static function get_date_labels($days = 7) {
        $labels = [];
        $format = ($days > 30) ? 'M d' : 'D';
        for ($i = $days - 1; $i >= 0; $i--) {
            $labels[] = gmdate($format, strtotime("-$i days"));
        }
        return $labels;
    }

    private static function get_top_spenders($limit = 5) {
        global $wpdb;

        $cache_key = 'movie_engine_analytics_top_spenders_' . $limit;
        $results = wp_cache_get($cache_key, 'movie_engine');

        if (false === $results) {
            if (!apply_filters('movie_engine_is_pro', false)) {
                $results = [];
            } else {
                // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery
                $results = $wpdb->get_results($wpdb->prepare(
                    "SELECT user_id, SUM(amount) as total_spent, COUNT(id) as tx_count 
                     FROM {$wpdb->prefix}movie_engine_transactions 
                     WHERE status = %s
                     GROUP BY user_id 
                     ORDER BY total_spent DESC 
                     LIMIT %d",
                    'completed',
                    $limit
                ));
            }

            if (is_wp_error($results) || empty($results)) {
                $results = [];
            }

            wp_cache_set($cache_key, $results, 'movie_engine', 3600);
        }

        $users = [];
        if ($results) {
            foreach ($results as $r) {
                $user_info = get_userdata($r->user_id);
                if ($user_info) {
                    $users[] = [
                        'name' => $user_info->display_name,
                        'email' => $user_info->user_email,
                        'spent' => $r->total_spent,
                        'count' => $r->tx_count,
                        'avatar' => get_avatar_url($r->user_id)
                    ];
                }
            }
        }
        return $users;
    }

    private static function get_popular_searches($limit = 5) {
        $stats = get_option('movie_engine_search_stats', []);
        return array_slice($stats, 0, $limit, true);
    }
    private static function get_most_watched($limit = 5) {
        $args = [
            'post_type'      => ['movie_engine_movie', 'movie_engine_series'],
            'posts_per_page' => $limit,
            // phpcs:ignore WordPress.DB.SlowDBQuery
            'meta_key'       => '_movie_engine_views',
            'orderby'        => 'meta_value_num',
            'order'          => 'DESC',
            'post_status'    => 'publish',
        ];

        $query = new \WP_Query($args);
        $results = [];

        if ($query->have_posts()) {
            foreach ($query->posts as $post) {
                $views = get_post_meta($post->ID, '_movie_engine_views', true);
                $results[] = [
                    'id'    => $post->ID,
                    'title' => $post->post_title,
                    'views' => (int) $views ?: 0,
                    'link'  => esc_url(get_edit_post_link($post->ID)),
                ];
            }
        }
        wp_reset_postdata();

        return $results;
    }
}
