<?php

namespace SoftMultimediaPlayer;

defined('ABSPATH') || exit();

class Statistics {
    private static $instance = null;

    public function __construct() {
        add_action('wp_ajax_smp_get_statistics', array($this, 'get_statistics'));

        add_action('wp_dashboard_setup', [$this, 'dashboard_widgets']);

        add_action('wp_ajax_smp_insert_log', [$this, 'insert_log']);
        add_action('wp_ajax_nopriv_smp_insert_log', [$this, 'insert_log']);

        // Export statistics
        add_action('wp_ajax_smp_export_statistics', [$this, 'export_statistics']);
    }

    public function get_statistics() {

        check_ajax_referer('multimedia-player', 'nonce');

        $start_date = isset($_POST['start_date']) ? sanitize_text_field($_POST['start_date']) : '';
        $end_date = isset($_POST['end_date']) ? sanitize_text_field($_POST['end_date']) : '';

        if (!$start_date || !$end_date) {
            wp_send_json_error(__('Invalid date range.', 'soft-multimedia-player'));
        }

        $logs = $this->get_logs($start_date, $end_date);

        // Get top users
        $top_users = $this->get_top_users($start_date, $end_date);

        // Get top countries
        $top_countries = $this->get_top_countries($start_date, $end_date);

        // Get top browsers
        $top_browsers = $this->get_top_browsers($start_date, $end_date);

        // Get top devices
        $top_devices = $this->get_top_devices($start_date, $end_date);

        // Get top players
        $top_players = $this->get_top_players($start_date, $end_date);

        // Get top tracks
        $top_tracks = $this->get_top_tracks($start_date, $end_date);

        wp_send_json_success([
            'logs' => $logs,
            'players' => $top_players,
            'stations' => $top_tracks,
            'users' => $top_users,
            'countries' => $top_countries,
            'browsers' => $top_browsers,
            'devices' => $top_devices,
        ]);
    }

    /**
     * Retrieves log entries from the statistics database table within a specified date range.
     *
     * This function queries the statistics table to fetch logs based on the provided start and end dates.
     * Optionally, a limit can be specified to control the number of results returned. Each log entry
     * contains information such as player ID, player type, track details, user information, and other
     * metadata like browser, OS, device, and duration.
     *
     * @param string $start_date The start date of the range in 'Y-m-d' format.
     * @param string $end_date   The end date of the range in 'Y-m-d' format.
     * @param int    $limit      Optional. The maximum number of log entries to retrieve. Default is -1 for no limit.
     *
     * @return array An array of log data, where each entry is an associative array with keys like 'player_id',
     *               'player_type', 'track', 'action', 'ip', 'user_id', 'country', 'browser', 'os', 'device',
     *               'page', 'duration', and 'date'.
     */
    public function get_logs($start_date, $end_date, $limit = -1) {
        global $wpdb;

        $table = "{$wpdb->prefix}smp_statistics";

        $sql = "
        SELECT 
            player_id,
            player_type,
            track,
            action,
            ip,
            user_id,
            country,
            page,
            duration,
            os, 
            device,
            browser,
            timestamp as date
        FROM $table
        WHERE timestamp BETWEEN %s AND %s
        ORDER BY timestamp ASC
    ";

        $params = [$start_date . ' 00:00:00', $end_date . ' 23:59:59'];

        if ($limit !== -1) {
            $sql .= " LIMIT %d";
            $params[] = (int)$limit;
        }

        $logs = $wpdb->get_results($wpdb->prepare($sql, ...$params), ARRAY_A);

        $data = [];

        if (!empty($logs)) {
            $players = smp_get_players();

            foreach ($logs as $log) {
                $user_name = __('Anonymous', 'soft-multimedia-player');

                if ($log['user_id']) {
                    $user = get_user_by('id', $log['user_id']);
                    $user_name = $user->user_login ?? $user_name;
                }

                $player_id = $log['player_id'];
                $player_title = '';
                $track_title = '';

                $filtered_players = wp_list_filter($players, ['id' => $player_id]);

                if (!empty($filtered_players)) {
                    $player = reset($filtered_players);
                    $player_title = $player['title'] ?? '';

                    if (! empty($player['config']['items'][$log['track']])) {
                        $station_config = $player['config']['items'][$log['track']];
                        $track_title  = $station_config['title'] ?? '';
                    }
                }

                $data[] = [
                    'player_id'         => $player_id,
                    'player_type'       => $log['player_type'],
                    'player_title'      => $player_title,
                    'track'             => $log['track'],
                    'track_title'       => $track_title,
                    'action'            => $log['action'],
                    'ip'                => $log['ip'],
                    'user_id'           => $log['user_id'],
                    'country'           => $log['country'],
                    'username'          => $user_name,
                    'browser'           => $log['browser'],
                    'os'                => $log['os'],
                    'device'            => $log['device'],
                    'page'              => $log['page'],
                    'duration'          => $log['duration'],
                    'date'              => $log['date'],
                ];
            }
        }
        return $data;
    }

    /**
     * Retrieves top players, sorted by the number of plays.
     *
     * @param string $start_date The start date of the range.
     * @param string $end_date   The end date of the range.
     * @param int    $limit      The number of players to retrieve. Default -1.
     *
     * @return array An array of player statistics.
     */
    public function get_top_players($start_date, $end_date, $limit = -1) {
        global $wpdb;

        $table = $wpdb->prefix . 'smp_statistics';
        $players_table = $wpdb->prefix . 'smp_players';

        $sql = "
            SELECT
                s.player_id,
                p.title AS player_title,
                COUNT(s.id) AS total_plays,
                COUNT(DISTINCT s.ip) AS total_users
            FROM {$table} s
            LEFT JOIN {$players_table} p ON s.player_id = p.id
            WHERE s.action = 'play_start'
        ";

        $params = [];

        if (!empty($start_date) && !empty($end_date)) {
            $sql .= " AND s.timestamp BETWEEN %s AND %s";
            $params[] = "{$start_date} 00:00:00";
            $params[] = "{$end_date} 23:59:59";
        }

        $sql .= " GROUP BY s.player_id ORDER BY total_plays DESC";

        if ($limit > 0) {
            $sql .= " LIMIT %d";
            $params[] = (int)$limit;
        }

        $play_stats = $wpdb->get_results($wpdb->prepare($sql, ...$params), ARRAY_A);

        $duration_sql = "
            SELECT 
                player_id, SUM(duration) as total_duration
            FROM {$table}
            WHERE action = 'play_end'
        ";

        $duration_params = [];

        if (!empty($start_date) && !empty($end_date)) {
            $duration_sql .= " AND timestamp BETWEEN %s AND %s";
            $duration_params[] = "{$start_date} 00:00:00";
            $duration_params[] = "{$end_date} 23:59:59";
        }

        $duration_sql .= " GROUP BY player_id";

        $durations = $wpdb->get_results($wpdb->prepare($duration_sql, ...$duration_params), OBJECT_K);

        // Merge durations
        foreach ($play_stats as &$row) {
            $player_id = $row['player_id'];
            $row['total_duration'] = isset($durations[$player_id]) ? (int)$durations[$player_id]->total_duration : 0;
        }

        return $play_stats;
    }

    public function get_top_tracks($start_date, $end_date, $limit = -1) {
        global $wpdb;

        $stats_table = "{$wpdb->prefix}smp_statistics";
        $players_table = "{$wpdb->prefix}smp_players";

        $start_datetime = $start_date . ' 00:00:00';
        $end_datetime = $end_date . ' 23:59:59';

        $sql = "
            SELECT
                s.track,
                p.id AS player_id,
                p.title AS player_title,
                COUNT(s.id) AS total_plays,
                COUNT(DISTINCT s.ip) AS total_users
            FROM {$stats_table} s
            LEFT JOIN {$players_table} p ON s.player_id = p.id
            WHERE s.action = 'play_start'
        ";

        $params = [];

        if (!empty($start_date) && !empty($end_date)) {
            $sql .= " AND s.timestamp BETWEEN %s AND %s";
            $params[] = "{$start_date} 00:00:00";
            $params[] = "{$end_date} 23:59:59";
        }

        $sql .= " GROUP BY s.track, p.id, p.title ORDER BY total_plays DESC";

        if ($limit > 0) {
            $sql .= " LIMIT %d";
            $params[] = (int)$limit;
        }

        $play_stats = $wpdb->get_results($wpdb->prepare($sql, ...$params), ARRAY_A);

        // Get total duration from "play_end"
        $duration_sql = "
            SELECT 
                track, SUM(duration) as total_duration
            FROM {$stats_table}
            WHERE action = 'play_end'
        ";

        $duration_params = [];

        if (!empty($start_date) && !empty($end_date)) {
            $duration_sql .= " AND timestamp BETWEEN %s AND %s";
            $duration_params[] = "{$start_date} 00:00:00";
            $duration_params[] = "{$end_date} 23:59:59";
        }

        $duration_sql .= " GROUP BY track";

        $durations = $wpdb->get_results($wpdb->prepare($duration_sql, ...$duration_params), OBJECT_K);

        $players = smp_get_players();
        $top_tracks = [];

        foreach ($play_stats as $row) {
            $track_id = $row['track'];
            $player_id = $row['player_id'];

            $player = wp_list_filter($players, ['id' => $player_id]);
            if (empty($player)) continue;

            $player = reset($player);
            $items_config = $player['config']['items'][$track_id] ?? null;

            if (empty($items_config)) continue;

            $top_tracks[] = [
                'player_id'         => $player['id'],
                'player_title'      => $player['title'],
                'track'             => $track_id,
                'track_title'       => $items_config['title'] ?? '',
                'track_thumbnail'   => $items_config['thumbnail'] ?? '',
                'total_plays'       => (int)$row['total_plays'],
                'total_users'       => (int)$row['total_users'],
                'total_duration'    => isset($durations[$track_id]) ? (int)$durations[$track_id]->total_duration : 0,
            ];
        }

        return $top_tracks;
    }

    public function get_top_users($start_date, $end_date, $limit = -1) {
        global $wpdb;

        $table = $wpdb->prefix . 'smp_statistics';

        $sql = "
		SELECT 
			user_id,
			ip,
			country,
			COUNT(id) AS total_plays,
			COUNT(DISTINCT user_id) AS total_users,
			SUM(duration) AS total_duration
		FROM $table
		WHERE timestamp BETWEEN %s AND %s
		GROUP BY ip
		ORDER BY total_plays DESC
	";

        $params = [$start_date . ' 00:00:00', $end_date . ' 23:59:59'];

        if ($limit !== -1) {
            $sql .= " LIMIT %d";
            $params[] = (int)$limit;
        }

        $results = $wpdb->get_results($wpdb->prepare($sql, ...$params), ARRAY_A);

        $data = [];

        if (!empty($results)) {
            foreach ($results as $result) {
                $gravatar = '<img src="' . esc_url(SOFT_MULTIMEDIA_PLAYER_ASSETS . '/images/user-icon.png') . '" height="32px" />';
                $name = __('Anonymous', 'soft-multimedia-player');

                if ($result['user_id']) {
                    $user = get_user_by('id', $result['user_id']);
                    if ($user) {
                        $name = $user->user_login;

                        if (function_exists('get_wp_user_avatar') && !empty($user->user_email)) {
                            $gravatar = get_wp_user_avatar($user->user_email, 32);
                        } else {
                            $gravatar = get_avatar($user->user_email, 32);
                        }
                    }
                }

                $data[] = [
                    'user_id' => $result['user_id'],
                    'ip' => $result['ip'],
                    'country' => $result['country'],
                    'avatar' => $gravatar,
                    'name' => $name,
                    'total_plays' => (int)$result['total_plays'],
                    'total_duration' => (int)$result['total_duration'],
                ];
            }
        }

        return $data;
    }

    public function get_top_countries($start_date, $end_date, $limit = -1) {
        global $wpdb;

        $table = $wpdb->prefix . 'smp_statistics';

        $sql = "
		SELECT 
			country,
			COUNT(id) AS total_plays,
			COUNT(DISTINCT ip) AS total_users,
			SUM(duration) AS total_duration
		FROM $table
		WHERE timestamp BETWEEN %s AND %s
		GROUP BY country
		ORDER BY total_plays DESC
	";

        $params = [$start_date . ' 00:00:00', $end_date . ' 23:59:59'];

        if ($limit !== -1) {
            $sql .= " LIMIT %d";
            $params[] = (int)$limit;
        }

        $top_countries = $wpdb->get_results($wpdb->prepare($sql, ...$params), ARRAY_A);

        return $top_countries;
    }

    public function get_top_browsers($start_date, $end_date, $limit = -1) {
        global $wpdb;

        $table = $wpdb->prefix . 'smp_statistics';

        $sql = "
		SELECT 
			browser,
			COUNT(id) AS total_plays,
			COUNT(DISTINCT ip) AS total_users,
			SUM(duration) AS total_duration
		FROM $table
		WHERE timestamp BETWEEN %s AND %s
		GROUP BY browser
		ORDER BY total_plays DESC
	";

        $params = [$start_date . ' 00:00:00', $end_date . ' 23:59:59'];

        if ($limit !== -1) {
            $sql .= " LIMIT %d";
            $params[] = (int)$limit;
        }

        $top_browsers = $wpdb->get_results($wpdb->prepare($sql, ...$params), ARRAY_A);

        return $top_browsers;
    }

    public function get_top_devices($start_date, $end_date, $limit = -1) {
        global $wpdb;

        $table = $wpdb->prefix . 'smp_statistics';

        $sql = "
		SELECT 
			device,
			COUNT(id) AS total_plays,
			COUNT(DISTINCT ip) AS total_users,
			SUM(duration) AS total_duration
		FROM $table
		WHERE timestamp BETWEEN %s AND %s
		GROUP BY device
		ORDER BY total_plays DESC
	";

        $params = [$start_date . ' 00:00:00', $end_date . ' 23:59:59'];

        if ($limit !== -1) {
            $sql .= " LIMIT %d";
            $params[] = (int)$limit;
        }

        $top_devices = $wpdb->get_results($wpdb->prepare($sql, ...$params), ARRAY_A);

        return $top_devices;
    }

    public function export_statistics() {
        if (!current_user_can('manage_options')) {
            wp_send_json_error(__('You do not have permission to perform this action', 'soft-multimedia-player'));
        }

        $start_date = !empty($_POST['start_date']) ? sanitize_text_field($_POST['start_date']) : '';
        $end_date = !empty($_POST['end_date']) ? sanitize_text_field($_POST['end_date']) : '';

        $end_date = $end_date . ' 23:59:59';

        $type = !empty($_POST['type']) ? sanitize_text_field($_POST['type']) : 'all';

        if ('all' == $type) {
            $this->export_all_data($start_date, $end_date);
        } else if ('users' == $type) {
            $data = $this->get_top_users($start_date, $end_date);

            $flattened_data = [];
            foreach ($data as $item) {
                $flattened_data[] = [
                    __('User ID', 'soft-multimedia-player')         => $item['user_id'],
                    __('Name', 'soft-multimedia-player')            => $item['name'],
                    __('IP', 'soft-multimedia-player')              => $item['ip'],
                    __('Country', 'soft-multimedia-player')         => $item['country'],
                    __('Total Plays', 'soft-multimedia-player')     => $item['total_plays'],
                    __('Total Duration', 'soft-multimedia-player')  => $item['total_duration'],
                ];
            }

            $file_name = 'top-users-' . time() . '.csv';
            $file_path = sys_get_temp_dir() . '/' . $file_name;

            $this->create_csv_file($file_path, $flattened_data);

            $file_url = 'tmp/' . $file_name;

            if (!is_dir('tmp')) {
                mkdir('tmp', 0755, true);
            }

            if (file_exists($file_path)) {
                copy($file_path, $file_url);
            }

            unlink($file_path);

            wp_send_json_success([
                'success' => true,
                'url' => $file_url,
            ]);

            exit;
        } else if ('countries' == $type) {
            $data = $this->get_top_countries($start_date, $end_date);

            $flattened_data = [];
            foreach ($data as $user) {
                $flattened_data[] = [
                    __('Country', 'soft-multimedia-player') => $user['country'],
                    __('Total Users', 'soft-multimedia-player') => $user['total_users'],
                    __('Total Plays', 'soft-multimedia-player') => $user['total_plays'],
                    __('Total Duration', 'soft-multimedia-player') => $user['total_duration'],
                ];
            }

            $file_name = 'top-countries-' . time() . '.csv';
            $file_path = sys_get_temp_dir() . '/' . $file_name;

            $this->create_csv_file($file_path, $flattened_data);

            $file_url = 'tmp/' . $file_name;

            if (!is_dir('tmp')) {
                mkdir('tmp', 0755, true);
            }

            if (file_exists($file_path)) {
                copy($file_path, $file_url);
            }

            unlink($file_path);

            wp_send_json_success([
                'success' => true,
                'url' => $file_url,
            ]);

            exit;
        } else if ('browsers' == $type) {
            $data = $this->get_top_browsers($start_date, $end_date);

            $flattened_data = [];
            foreach ($data as $item) {
                $flattened_data[] = [
                    __('Browser', 'soft-multimedia-player')         => $item['browser'],
                    __('Total Users', 'soft-multimedia-player')     => $item['total_users'],
                    __('Total Plays', 'soft-multimedia-player')     => $item['total_plays'],
                    __('Total Duration', 'soft-multimedia-player')  => $item['total_duration'],
                ];
            }

            $file_name = 'top-browsers-' . time() . '.csv';
            $file_path = sys_get_temp_dir() . '/' . $file_name;

            $this->create_csv_file($file_path, $flattened_data);

            $file_url = 'tmp/' . $file_name;

            if (!is_dir('tmp')) {
                mkdir('tmp', 0755, true);
            }

            if (file_exists($file_path)) {
                copy($file_path, $file_url);
            }

            unlink($file_path);

            wp_send_json_success([
                'success' => true,
                'url' => $file_url,
            ]);

            exit;
        } else if ('devices' == $type) {
            $data = $this->get_top_devices($start_date, $end_date);

            $flattened_data = [];
            foreach ($data as $item) {
                $flattened_data[] = [
                    __('Device', 'soft-multimedia-player')          => $item['device'],
                    __('Total Users', 'soft-multimedia-player')     => $item['total_users'],
                    __('Total Plays', 'soft-multimedia-player')     => $item['total_plays'],
                    __('Total Duration', 'soft-multimedia-player')  => $item['total_duration'],
                ];
            }

            $file_name = 'top-devices-' . time() . '.csv';
            $file_path = sys_get_temp_dir() . '/' . $file_name;

            $this->create_csv_file($file_path, $flattened_data);

            $file_url = 'tmp/' . $file_name;

            if (!is_dir('tmp')) {
                mkdir('tmp', 0755, true);
            }

            if (file_exists($file_path)) {
                copy($file_path, $file_url);
            }

            unlink($file_path);

            wp_send_json_success([
                'success' => true,
                'url' => $file_url,
            ]);

            exit;
        } else if ('players' == $type) {
            $data = $this->get_top_players($start_date, $end_date);

            $flattened_data = [];
            foreach ($data as $item) {
                $flattened_data[] = [
                    __('Player', 'soft-multimedia-player')          => $item['player_title'],
                    __('Total Users', 'soft-multimedia-player')     => $item['total_users'],
                    __('Total Plays', 'soft-multimedia-player')     => $item['total_plays'],
                    __('Total Duration', 'soft-multimedia-player')  => $item['total_duration'],
                ];
            }

            $file_name = 'top-players-' . time() . '.csv';
            $file_path = sys_get_temp_dir() . '/' . $file_name;

            $this->create_csv_file($file_path, $flattened_data);

            $file_url = 'tmp/' . $file_name;

            if (!is_dir('tmp')) {
                mkdir('tmp', 0755, true);
            }

            if (file_exists($file_path)) {
                copy($file_path, $file_url);
            }

            unlink($file_path);

            wp_send_json_success([
                'success' => true,
                'url' => $file_url,
            ]);

            exit;
        } else if ('tracks' == $type) {
            $data = $this->get_top_tracks($start_date, $end_date);

            $flattened_data = [];
            foreach ($data as $item) {
                $flattened_data[] = [
                    __('Track', 'soft-multimedia-player')           => $item['track_title'],
                    __('Player', 'soft-multimedia-player')          => $item['player_title'],
                    __('Total Users', 'soft-multimedia-player')     => $item['total_users'],
                    __('Total Plays', 'soft-multimedia-player')     => $item['total_plays'],
                    __('Total Duration', 'soft-multimedia-player')  => $item['total_duration'],
                ];
            }

            $file_name = 'top-tracks-users-' . time() . '.csv';
            $file_path = sys_get_temp_dir() . '/' . $file_name;

            $this->create_csv_file($file_path, $flattened_data);

            $file_url = 'tmp/' . $file_name;

            if (!is_dir('tmp')) {
                mkdir('tmp', 0755, true);
            }

            if (file_exists($file_path)) {
                copy($file_path, $file_url);
            }

            unlink($file_path);

            wp_send_json_success([
                'success' => true,
                'url' => $file_url,
            ]);

            exit;
        } else if ('logs' == $type) {
            $data = $this->get_logs($start_date, $end_date);

            $flattened_data = [];
            foreach ($data as $event) {
                $flattened_data[] = [
                    __('Action', 'soft-multimedia-player')      => $event['action'],
                    __('Player', 'soft-multimedia-player')      => $event['player_title'],
                    __('Track', 'soft-multimedia-player')       => $event['track_title'],
                    __('Page', 'soft-multimedia-player')        => $event['page'],
                    __('User IP', 'soft-multimedia-player')     => $event['ip'],
                    __('User ID', 'soft-multimedia-player')     => $event['user_id'],
                    __('Country', 'soft-multimedia-player')     => isset($event['country']) ? $event['country'] : '',
                    __('Duration', 'soft-multimedia-player')    => isset($event['duration']) ? $event['duration'] : '',
                    __('Date', 'soft-multimedia-player')        => date('Y-m-d H:i a', strtotime($event['date'])),
                ];
            }

            $file_name = 'event-logs-' . time() . '.csv';
            $file_path = sys_get_temp_dir() . '/' . $file_name;

            $this->create_csv_file($file_path, $flattened_data);

            $file_url = 'tmp/' . $file_name;

            if (!is_dir('tmp')) {
                mkdir('tmp', 0755, true);
            }

            if (file_exists($file_path)) {
                copy($file_path, $file_url);
            }

            unlink($file_path);

            wp_send_json_success([
                'success' => true,
                'url' => $file_url,
            ]);

            exit;
        } else {
            wp_send_json_error(__('Invalid export type', 'soft-multimedia-player'));
        }
    }

    public function export_all_data($start_date, $end_date) {

        // Top users
        $user_items = $this->get_top_users($start_date, $end_date);

        $top_user_items = [];
        foreach ($user_items as $item) {
            $top_user_items[] = [
                __('User ID', 'soft-multimedia-player')         => $item['user_id'],
                __('Name', 'soft-multimedia-player')            => $item['name'],
                __('IP', 'soft-multimedia-player')              => $item['ip'],
                __('Country', 'soft-multimedia-player')         => $item['country'],
                __('Total Plays', 'soft-multimedia-player')     => $item['total_plays'],
                __('Total Duration', 'soft-multimedia-player')  => $item['total_duration'],
            ];
        }

        // Top countries
        $countries = $this->get_top_countries($start_date, $end_date);

        $top_country_items = [];

        foreach ($countries as $item) {
            $top_country_items[] = [
                __('Country', 'soft-multimedia-player')         => $item['country'],
                __('Total Users', 'soft-multimedia-player')     => $item['total_users'],
                __('Total Plays', 'soft-multimedia-player')     => $item['total_plays'],
                __('Total Duration', 'soft-multimedia-player')  => $item['total_duration'],
            ];
        }

        // Top browsers
        $browsers = $this->get_top_browsers($start_date, $end_date);

        $top_browser_items = [];

        foreach ($browsers as $item) {
            $top_browser_items[] = [
                __('Browser', 'soft-multimedia-player')         => $item['browser'],
                __('Total Users', 'soft-multimedia-player')     => $item['total_users'],
                __('Total Plays', 'soft-multimedia-player')     => $item['total_plays'],
                __('Total Duration', 'soft-multimedia-player')  => $item['total_duration'],
            ];
        }

        // Top devices
        $devices = $this->get_top_devices($start_date, $end_date);

        $top_device_items = [];

        foreach ($devices as $item) {
            $top_device_items[] = [
                __('Device', 'soft-multimedia-player')          => $item['device'],
                __('Total Users', 'soft-multimedia-player')     => $item['total_users'],
                __('Total Plays', 'soft-multimedia-player')     => $item['total_plays'],
                __('Total Duration', 'soft-multimedia-player')  => $item['total_duration'],
            ];
        }

        // Top players
        $players = $this->get_top_players($start_date, $end_date);

        $top_player_items = [];

        foreach ($players as $item) {
            $top_player_items[] = [
                __('Player', 'soft-multimedia-player')          => $item['player_title'],
                __('Total Users', 'soft-multimedia-player')     => $item['total_users'],
                __('Total Plays', 'soft-multimedia-player')     => $item['total_plays'],
                __('Total Duration', 'soft-multimedia-player')  => $item['total_duration'],
            ];
        }

        // Top Tracks
        $tracks = $this->get_top_tracks($start_date, $end_date);

        foreach ($tracks as $item) {
            $top_station_items[] = [
                __('Track', 'soft-multimedia-player')         => $item['track_title'],
                __('Player', 'soft-multimedia-player')          => $item['player_title'],
                __('Total Users', 'soft-multimedia-player')         => $item['total_users'],
                __('Total Plays', 'soft-multimedia-player')     => $item['total_plays'],
                __('Total Duration', 'soft-multimedia-player')  => $item['total_duration'],
            ];
        }


        //Event Logs
        $logs = $this->get_logs($start_date, $end_date);

        $flattened_logs = [];
        foreach ($logs as $log) {
            $flattened_logs[] = [
                __('Action', 'soft-multimedia-player')      => $log['action'],
                __('Player', 'soft-multimedia-player')      => $log['player_title'],
                __('Track', 'soft-multimedia-player')     => $log['track_title'],
                __('Page', 'soft-multimedia-player')        => $log['page'],
                __('User IP', 'soft-multimedia-player')     => $log['ip'],
                __('User ID', 'soft-multimedia-player')     => $log['user_id'],
                __('Country', 'soft-multimedia-player')     => isset($log['country']) ? $log['country'] : '',
                __('Duration', 'soft-multimedia-player')    => isset($log['duration']) ? $log['duration'] : '',
                __('Date', 'soft-multimedia-player')        => date('Y-m-d H:i a', strtotime($log['date'])),
            ];
        }

        // Generate unique file names
        $top_users_file_name = 'top-users-' . time() . '.csv';
        $top_countries_file_name = 'top-countries-' . time() . '.csv';
        $top_browsers_file_name = 'top-browsers-' . time() . '.csv';
        $top_devices_file_name = 'top-devices-' . time() . '.csv';
        $top_players_file_name = 'top-players-' . time() . '.csv';
        $top_tracks_file_name = 'top-tracks-' . time() . '.csv';
        $event_logs_file_name = 'event-logs-' . time() . '.csv';

        // Create temporary file paths
        $top_users_file_path = sys_get_temp_dir() . '/' . $top_users_file_name;
        $top_countries_file_path = sys_get_temp_dir() . '/' . $top_countries_file_name;
        $top_browsers_file_path = sys_get_temp_dir() . '/' . $top_browsers_file_name;
        $top_devices_file_path = sys_get_temp_dir() . '/' . $top_devices_file_name;
        $top_players_file_path = sys_get_temp_dir() . '/' . $top_players_file_name;
        $top_tracks_file_path = sys_get_temp_dir() . '/' . $top_tracks_file_name;
        $event_logs_file_path = sys_get_temp_dir() . '/' . $event_logs_file_name;

        // Create CSV files
        $this->create_csv_file($top_users_file_path, $top_user_items);
        $this->create_csv_file($top_countries_file_path, $top_country_items);
        $this->create_csv_file($top_browsers_file_path, $top_browser_items);
        $this->create_csv_file($top_devices_file_path, $top_device_items);
        $this->create_csv_file($top_players_file_path, $top_player_items);
        $this->create_csv_file($top_tracks_file_path, $top_station_items);
        $this->create_csv_file($event_logs_file_path, $flattened_logs);

        // Create a zip file
        $zip_file_name = 'statistics-' . time() . '.zip';
        $zip_file_path = sys_get_temp_dir() . '/' . $zip_file_name;

        $zip = new \ZipArchive();

        if ($zip->open($zip_file_path, \ZipArchive::CREATE) === true) {
            $zip->addFile($top_users_file_path, $top_users_file_name);
            $zip->addFile($top_countries_file_path, $top_countries_file_name);
            $zip->addFile($top_browsers_file_path, $top_browsers_file_name);
            $zip->addFile($top_devices_file_path, $top_devices_file_name);
            $zip->addFile($top_players_file_path, $top_players_file_name);
            $zip->addFile($top_tracks_file_path, $top_tracks_file_name);
            $zip->addFile($event_logs_file_path, $event_logs_file_name);
            $zip->close();
        }

        // Save the zip file in a temporary location
        $zip_file_url = 'tmp/' . $zip_file_name;
        if (!is_dir('tmp')) {
            mkdir('tmp', 0755, true);
        }

        if (file_exists($zip_file_path)) {
            copy($zip_file_path, $zip_file_url);
        }

        // Clean up temporary files
        unlink($top_users_file_path);
        unlink($top_countries_file_path);
        unlink($top_browsers_file_path);
        unlink($top_devices_file_path);
        unlink($top_players_file_path);
        unlink($top_tracks_file_path);
        unlink($event_logs_file_path);
        unlink($zip_file_path);

        // Send the zip file URL in the AJAX response
        wp_send_json_success([
            'success' => true,
            'url' => $zip_file_url,
        ]);

        exit;
    }

    public function create_csv_file($file_path, $data) {
        $file = fopen($file_path, 'w');

        // Add header
        if (!empty($data) && is_array($data)) {
            $first_row = reset($data);
            if (is_array($first_row)) {
                fputcsv($file, array_keys($first_row));
            }
        }

        // Add data
        foreach ($data as $row) {
            if (is_array($row)) {
                fputcsv($file, $row);
            }
        }

        fclose($file);
    }

    public function insert_log() {
        check_ajax_referer('multimedia-player', 'nonce');

        $id             = isset($_POST['id']) ? sanitize_text_field($_POST['id']) : '';
        $type           = isset($_POST['type']) ? sanitize_text_field($_POST['type']) : '';
        $track          = isset($_POST['track']) ? intval($_POST['track']) : 0;
        $action         = isset($_POST['event']) ? sanitize_text_field($_POST['event']) : '';
        $duration       = isset($_POST['duration']) ? intval($_POST['duration']) : 0;
        $userAgent      = isset($_POST['userAgent']) ? sanitize_text_field($_POST['userAgent']) : '';
        $page           = isset($_POST['page']) ? esc_url_raw($_POST['page']) : '';
        $timestamp      = isset($_POST['timestamp']) ? sanitize_text_field($_POST['timestamp']) : current_time('mysql');
        $user_id        = get_current_user_id();
        $ip             = !empty($_REQUEST['ip']) ? sanitize_text_field($_REQUEST['ip']) : '';
        $country        = !empty($_REQUEST['country']) ? sanitize_text_field($_REQUEST['country']) : '';

        if (empty($id) || empty($action)) {
            wp_send_json_error(__('Missing required fields.', 'soft-multimedia-player'));
        }

        // Helpers to parse user agent (you can replace these with libraries if needed)
        $browser = smp_parse_browser__premium_only($userAgent);
        $os = smp_parse_os__premium_only($userAgent);
        $device = smp_parse_device__premium_only($userAgent);

        global $wpdb;
        $table = $wpdb->prefix . 'smp_statistics';

        $wpdb->insert($table, [
            'player_id' => $id,
            'player_type' => $type,
            'track' => $track,
            'action' => $action,
            'duration' => $duration,
            'browser' => $browser,
            'os' => $os,
            'device' => $device,
            'user_id' => $user_id,
            'ip' => $ip,
            'country' => $country,
            'page' => $page,
            'timestamp' => $timestamp,
        ]);

        wp_send_json_success(__('Log saved', 'soft-multimedia-player'));
    }

    public function dashboard_widgets() {

        if (!current_user_can('manage_options')) {
            return;
        }

        $widget = smp_get_setting('enableDashboardWidget', false);

        if (!$widget) {
            return;
        }

        wp_add_dashboard_widget('multimedia_player_chart', esc_html__('Multimedia Player Stats', 'soft-multimedia-player'), [
            $this,
            'render_dashboard_widget'
        ]);

        // Globalize the metaboxes array, this holds all the widgets for wp-admin.
        global $wp_meta_boxes;

        // Get the regular dashboard widgets array
        // (which already has our new widget but appended at the end).
        $default_dashboard = $wp_meta_boxes['dashboard']['normal']['core'];

        // Backup and delete our new dashboard widget from the end of the array.
        $wp_dark_mode_widget_backup = array('multimedia_player_chart' => $default_dashboard['multimedia_player_chart']);
        unset($default_dashboard['multimedia_player_chart']);

        // Merge the two arrays together so our widget is at the beginning.
        $sorted_dashboard = array_merge($wp_dark_mode_widget_backup, $default_dashboard);

        // Save the sorted array back into the original metaboxes.
        $wp_meta_boxes['dashboard']['normal']['core'] = $sorted_dashboard;
    }

    public function render_dashboard_widget() { ?>
        <div id="smp-chart-widget"></div>
    <?php }

    public static function view() { ?>
        <div id="smp-statistics"></div>
<?php }

    public static function instance() {
        if (is_null(self::$instance)) {
            self::$instance = new self();
        }

        return self::$instance;
    }
}

Statistics::instance();
