<?php
namespace IntentDeep\VirtualFiles\Traits;

/**
 * Helper trait for analytics data processing
 */
trait AnalyticsHelper {

    /**
     * Get total views across all files
     */
    private function getTotalViews(): int {
        global $wpdb;

        $total = $wpdb->get_var(
            "SELECT SUM(meta_value) FROM {$wpdb->postmeta}
             WHERE meta_key = '_vf_access_count'
             AND meta_value != ''"
        );

        return $total ? intval($total) : 0;
    }

    /**
     * Get total views for a specific date range
     */
    private function getViewsForDateRange(string $start_date, string $end_date): int {
        $files = $this->getAllVirtualFiles();
        $total = 0;

        foreach ($files as $file) {
            $daily_stats = get_post_meta($file->ID, '_vf_analytics_daily', true);
            if (!is_array($daily_stats)) {
                continue;
            }

            foreach ($daily_stats as $date => $views) {
                if ($date >= $start_date && $date <= $end_date) {
                    $total += intval($views);
                }
            }
        }

        return $total;
    }

    /**
     * Get views timeline for last N days
     *
     * @param int $days Number of days to retrieve
     * @return array Array with dates as keys and view counts as values
     */
    private function getViewsTimeline(int $days = 30): array {
        $timeline = [];
        $files = $this->getAllVirtualFiles();

        // Initialize timeline with zeros
        for ($i = $days - 1; $i >= 0; $i--) {
            $date = date('Y-m-d', strtotime("-{$i} days"));
            $timeline[$date] = 0;
        }

        // Aggregate views from all files
        foreach ($files as $file) {
            $daily_stats = get_post_meta($file->ID, '_vf_analytics_daily', true);
            if (!is_array($daily_stats)) {
                continue;
            }

            foreach ($daily_stats as $date => $views) {
                if (isset($timeline[$date])) {
                    $timeline[$date] += intval($views);
                }
            }
        }

        return $timeline;
    }

    /**
     * Get top files by views
     *
     * @param int $limit Number of files to return
     * @param int $days Number of days to consider (0 = all time)
     * @return array Array of file objects with view counts
     */
    private function getTopFiles(int $limit = 5, int $days = 0): array {
        $files = $this->getAllVirtualFiles();
        $file_stats = [];

        foreach ($files as $file) {
            $filename = get_post_meta($file->ID, '_vf_filename', true);
            if (empty($filename)) {
                continue;
            }

            if ($days > 0) {
                // Get views for specific date range
                $start_date = date('Y-m-d', strtotime("-{$days} days"));
                $end_date = date('Y-m-d');
                $views = $this->getFileViewsForDateRange($file->ID, $start_date, $end_date);
            } else {
                // Get all-time views
                $views = intval(get_post_meta($file->ID, '_vf_access_count', true));
            }

            $mime_type = get_post_meta($file->ID, '_vf_mime_type', true);
            // Strip charset from MIME type (e.g., "application/json; charset=utf-8" -> "application/json")
            $mime_type = preg_replace('/;\s*charset=.*/i', '', $mime_type);

            $file_stats[] = [
                'id' => $file->ID,
                'filename' => $filename,
                'views' => $views,
                'last_accessed' => get_post_meta($file->ID, '_vf_last_accessed', true),
                'status' => get_post_meta($file->ID, '_vf_status', true),
                'mime_type' => $mime_type,
            ];
        }

        // Sort by views descending
        usort($file_stats, function($a, $b) {
            return $b['views'] - $a['views'];
        });

        return array_slice($file_stats, 0, $limit);
    }

    /**
     * Get views for a specific file in a date range
     */
    private function getFileViewsForDateRange(int $file_id, string $start_date, string $end_date): int {
        $daily_stats = get_post_meta($file_id, '_vf_analytics_daily', true);
        if (!is_array($daily_stats)) {
            return 0;
        }

        $total = 0;
        foreach ($daily_stats as $date => $views) {
            if ($date >= $start_date && $date <= $end_date) {
                $total += intval($views);
            }
        }

        return $total;
    }

    /**
     * Get file type distribution
     *
     * @return array Array with file extensions as keys and view counts as values
     */
    private function getFileTypeDistribution(): array {
        $files = $this->getAllVirtualFiles();
        $distribution = [];

        foreach ($files as $file) {
            $filename = get_post_meta($file->ID, '_vf_filename', true);
            $views = intval(get_post_meta($file->ID, '_vf_access_count', true));

            if (empty($filename)) {
                continue;
            }

            // Extract extension
            $extension = pathinfo($filename, PATHINFO_EXTENSION);
            $extension = strtolower($extension);

            if (!isset($distribution[$extension])) {
                $distribution[$extension] = 0;
            }

            $distribution[$extension] += $views;
        }

        // Sort by views descending
        arsort($distribution);

        return $distribution;
    }

    /**
     * Get average views per file
     */
    private function getAverageViewsPerFile(): float {
        $files = $this->getAllVirtualFiles();
        $count = count($files);

        if ($count === 0) {
            return 0;
        }

        $total_views = $this->getTotalViews();
        return round($total_views / $count, 1);
    }

    /**
     * Get most viewed file
     *
     * @return array|null Array with file info or null if no files
     */
    private function getMostViewedFile(): ?array {
        $top_files = $this->getTopFiles(1);
        return !empty($top_files) ? $top_files[0] : null;
    }

    /**
     * Get analytics summary
     *
     * @return array Summary statistics
     */
    public function getAnalyticsSummary(): array {
        $total_views = $this->getTotalViews();
        $active_files = $this->getActiveFileCount();
        $most_viewed = $this->getMostViewedFile();
        $avg_views = $this->getAverageViewsPerFile();

        // Get views for today
        $today = date('Y-m-d');
        $views_today = $this->getViewsForDateRange($today, $today);

        // Get views for last 7 days for trend calculation
        $week_ago = date('Y-m-d', strtotime('-7 days'));
        $views_last_7_days = $this->getViewsForDateRange($week_ago, $today);

        // Calculate trend (compare last 7 days to previous 7 days)
        $two_weeks_ago = date('Y-m-d', strtotime('-14 days'));
        $views_previous_7_days = $this->getViewsForDateRange($two_weeks_ago, $week_ago);

        $trend = 0;
        if ($views_previous_7_days > 0) {
            $trend = round((($views_last_7_days - $views_previous_7_days) / $views_previous_7_days) * 100, 1);
        } elseif ($views_last_7_days > 0) {
            $trend = 100;
        }

        return [
            'total_views' => $total_views,
            'views_today' => $views_today,
            'views_last_7_days' => $views_last_7_days,
            'trend_percentage' => $trend,
            'active_files' => $active_files,
            'most_viewed_file' => $most_viewed,
            'average_views_per_file' => $avg_views,
        ];
    }

    /**
     * Get all virtual files (helper method)
     */
    private function getAllVirtualFiles(): array {
        return get_posts([
            'post_type' => 'idep_virtual_file',
            'posts_per_page' => -1,
            'post_status' => 'publish',
        ]);
    }

    /**
     * Get hourly views for today (for hourly chart)
     */
    private function getTodayHourlyViews(): array {
        $files = $this->getAllVirtualFiles();
        $hourly_data = [];

        // Initialize 24 hours with zeros
        for ($i = 0; $i < 24; $i++) {
            $hourly_data[sprintf('%02d', $i)] = 0;
        }

        $today = date('Y-m-d');

        foreach ($files as $file) {
            $hourly_stats = get_post_meta($file->ID, '_vf_analytics_hourly', true);
            if (!is_array($hourly_stats)) {
                continue;
            }

            foreach ($hourly_stats as $datetime => $views) {
                // Format: "2025-12-01-14"
                if (strpos($datetime, $today) === 0) {
                    $hour = substr($datetime, -2);
                    if (isset($hourly_data[$hour])) {
                        $hourly_data[$hour] += intval($views);
                    }
                }
            }
        }

        return $hourly_data;
    }

    /**
     * Track a file view (enhanced tracking for analytics)
     *
     * @param int $post_id The file post ID
     */
    private function trackFileViewAnalytics(int $post_id): void {
        // Update total count
        $access_count = (int) get_post_meta($post_id, '_vf_access_count', true);
        update_post_meta($post_id, '_vf_access_count', $access_count + 1);
        update_post_meta($post_id, '_vf_last_accessed', current_time('mysql'));

        // Update daily stats
        $daily_stats = get_post_meta($post_id, '_vf_analytics_daily', true);
        if (!is_array($daily_stats)) {
            $daily_stats = [];
        }

        $today = date('Y-m-d');
        if (!isset($daily_stats[$today])) {
            $daily_stats[$today] = 0;
        }
        $daily_stats[$today]++;

        // Keep only last 90 days
        $cutoff_date = date('Y-m-d', strtotime('-90 days'));
        foreach ($daily_stats as $date => $count) {
            if ($date < $cutoff_date) {
                unset($daily_stats[$date]);
            }
        }

        update_post_meta($post_id, '_vf_analytics_daily', $daily_stats);

        // Update hourly stats
        $hourly_stats = get_post_meta($post_id, '_vf_analytics_hourly', true);
        if (!is_array($hourly_stats)) {
            $hourly_stats = [];
        }

        $current_hour = date('Y-m-d-H');
        if (!isset($hourly_stats[$current_hour])) {
            $hourly_stats[$current_hour] = 0;
        }
        $hourly_stats[$current_hour]++;

        // Keep only last 7 days of hourly data
        $cutoff_hour = date('Y-m-d-H', strtotime('-7 days'));
        foreach ($hourly_stats as $datetime => $count) {
            if ($datetime < $cutoff_hour) {
                unset($hourly_stats[$datetime]);
            }
        }

        update_post_meta($post_id, '_vf_analytics_hourly', $hourly_stats);
    }
}
