<?php
/**
 * Image Boost — Statistics Calculator
 */

if (!defined('ABSPATH')) {
    exit;
}

class ImgBoost_Stats {

    /**
     * Get comprehensive dashboard stats.
     *
     * @return array
     */
    public static function get_dashboard_stats() {
        $db_stats = ImgBoost_DB::get_total_stats();

        $total_attachments = self::count_all_images();
        $optimized_count = (int) $db_stats['total_images'];
        
        // Prevent mismatch anomalies
        if ($optimized_count > $total_attachments) {
            $optimized_count = $total_attachments;
        }
        
        $pending_count = max(0, $total_attachments - $optimized_count);

        return [
            'total_images'      => $total_attachments,
            'optimized_count'   => $optimized_count,
            'pending_count'     => $pending_count,
            'total_original'    => (int) $db_stats['total_original'],
            'total_optimized'   => (int) $db_stats['total_optimized'],
            'total_saved'       => (int) $db_stats['total_saved'],
            'total_saved_human' => imgboost_format_bytes((int) $db_stats['total_saved']),
            'avg_savings'       => round((float) $db_stats['avg_savings'], 1),
            'percent_done'      => $total_attachments > 0
                ? round(($optimized_count / $total_attachments) * 100, 1)
                : 0,
            'engine'            => imgboost_get_engine(),
            'webp_support'      => imgboost_supports_webp(),
            'avif_support' => false,
            'chart_data'        => self::get_chart_data(),
        ];
    }

    /**
     * Count all optimizable images in media library (excluding trash).
     *
     * @return int
     */
    public static function count_all_images() {
        global $wpdb;
        
        $cache_key = 'imgboost_count_all_images';
        $cached = wp_cache_get($cache_key, 'imgboost');
        if (false !== $cached) {
            return (int) $cached;
        }

        $query = new WP_Query([
            'post_type'              => 'attachment',
            'post_status'            => 'inherit',
            'post_mime_type'         => ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
            'fields'                 => 'ids',
            'posts_per_page'         => -1,
            'no_found_rows'          => true,
            'update_post_meta_cache' => false,
            'update_post_term_cache' => false,
        ]);
        
        $count = count($query->posts);
        
        wp_cache_set($cache_key, $count, 'imgboost', 1800);
        return $count;
    }

    /**
     * Get list of unoptimized attachment IDs (excluding trash and error status to prevent infinite loop).
     *
     * @param int $limit
     * @param int $offset
     * @return array
     */
    public static function get_unoptimized_ids($limit = 50, $offset = 0) {
        global $wpdb;

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        return $wpdb->get_col($wpdb->prepare(
            "SELECT p.ID FROM {$wpdb->posts} p
             LEFT JOIN {$wpdb->prefix}imgboost_log log ON p.ID = log.attachment_id
             WHERE p.post_type = 'attachment'
             AND p.post_status != 'trash'
             AND p.post_mime_type IN ('image/jpeg', 'image/png', 'image/gif', 'image/webp')
             AND log.id IS NULL
             ORDER BY p.ID DESC
             LIMIT %d OFFSET %d",
            $limit,
            $offset
        ));
    }

    /**
     * Count unoptimized images.
     *
     * @return int
     */
    public static function count_unoptimized() {
        $total = self::count_all_images();
        $optimized = ImgBoost_DB::get_total_stats()['total_images'];
        return max(0, $total - $optimized);
    }

    /**
     * Get breakdown by compression level.
     *
     * @return array
     */
    public static function get_level_breakdown() {
        global $wpdb;
        
        $cache_key = 'imgboost_level_breakdown';
        $cached = wp_cache_get($cache_key, 'imgboost');
        if (false !== $cached) {
            return $cached;
        }

        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $results = $wpdb->get_results(
            "SELECT compression_level, 
                    COUNT(DISTINCT attachment_id) as count,
                    AVG(savings_percent) as avg_savings,
                    SUM(original_size - optimized_size) as total_saved
             FROM {$wpdb->prefix}imgboost_log 
             WHERE status = 'optimized'
             GROUP BY compression_level",
            ARRAY_A
        );

        $breakdown = [];
        if ($results) {
            foreach ($results as $row) {
                $breakdown[$row['compression_level']] = $row;
            }
        }
        
        wp_cache_set($cache_key, $breakdown, 'imgboost', 3600);
        return $breakdown;
    }

    /**
     * Get 30-day savings data for Chart.js.
     */
    public static function get_chart_data() {
        global $wpdb;
        $table = $wpdb->prefix . 'imgboost_log';

        $cache_key = 'imgboost_chart_data';
        $cached = wp_cache_get($cache_key, 'imgboost');
        if (false !== $cached) {
            return $cached;
        }

        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        if ($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $wpdb->esc_like($table))) !== $table) {
            return ['labels' => [], 'data' => []];
        }

        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching
        $results = $wpdb->get_results($wpdb->prepare("
            SELECT DATE(optimized_at) as date_val, SUM(original_size - optimized_size) as saved_bytes 
            FROM {$wpdb->prefix}imgboost_log
            WHERE optimized_at >= %s 
            GROUP BY date_val 
            ORDER BY date_val ASC
        ", gmdate('Y-m-d 00:00:00', strtotime('-30 days'))));

        $data = [];
        // Fill 30 days
        for ($i = 29; $i >= 0; $i--) {
            $current_date = gmdate('Y-m-d', strtotime("-$i days"));
            $data[$current_date] = 0;
        }

        if ($results) {
            foreach ($results as $row) {
                $data[$row->date_val] = round($row->saved_bytes / 1024 / 1024, 2); // Convert to MB
            }
        }

        $chart_data = [
            'labels' => array_map(function($d) { return gmdate('M j', strtotime($d)); }, array_keys($data)),
            'data'   => array_values($data)
        ];

        wp_cache_set($cache_key, $chart_data, 'imgboost', 3600); // Cache for 1 hour
        return $chart_data;
    }
}
