<?php
/**
 * Savings Tracker Service
 *
 * Centralized tracking for all Mamba optimization savings including
 * image optimization, HTML minification, and database cleanup metrics.
 *
 * @package Mamba\Support
 * @since   1.0.0
 */

namespace Mamba\Support;

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

/**
 * Class SavingsTracker
 *
 * Centralized savings tracking for all Mamba optimizations:
 * - Image optimization savings (WebP/AVIF conversions)
 * - HTML minification savings
 * - Database cleanup rows
 * - Cache request savings (derived from cache hits)
 *
 * @since 1.0.0
 */
final class SavingsTracker {
    
    private const OPTION_KEY = 'mamba_savings_stats';
    
    /**
     * Get default stats structure
     */
    private static function getDefaults(): array {
        return [
            'image' => [
                'total_bytes_saved' => 0,
                'images_optimized' => 0,
                'webp_count' => 0,
                'avif_count' => 0,
                'last_updated' => 0,
            ],
            'minify' => [
                'total_bytes_saved' => 0,
                'pages_minified' => 0,
                'last_updated' => 0,
            ],
            'db' => [
                'total_rows_cleaned' => 0,
                'tasks_run' => 0,
                'last_updated' => 0,
            ],
            'monthly_reset' => date('Y-m'),
        ];
    }
    
    /**
     * Get all savings stats
     */
    public static function getStats(): array {
        $stats = get_option(self::OPTION_KEY, self::getDefaults());
        
        // Ensure structure is valid
        $defaults = self::getDefaults();
        foreach ($defaults as $key => $value) {
            if (!isset($stats[$key])) {
                $stats[$key] = $value;
            } elseif (is_array($value)) {
                foreach ($value as $subKey => $subValue) {
                    if (!isset($stats[$key][$subKey])) {
                        $stats[$key][$subKey] = $subValue;
                    }
                }
            }
        }
        
        // Monthly reset check
        $currentMonth = date('Y-m');
        if (($stats['monthly_reset'] ?? '') !== $currentMonth) {
            $stats = self::getDefaults();
            $stats['monthly_reset'] = $currentMonth;
            update_option(self::OPTION_KEY, $stats, false);
        }
        
        return $stats;
    }
    
    /**
     * Track image optimization savings
     */
    public static function trackImageSavings(int $originalBytes, int $optimizedBytes, string $format = 'webp'): void {
        if ($originalBytes <= 0 || $optimizedBytes <= 0) {
            return;
        }
        
        $saved = max(0, $originalBytes - $optimizedBytes);
        if ($saved === 0) {
            return;
        }
        
        $stats = self::getStats();
        $stats['image']['total_bytes_saved'] += $saved;
        $stats['image']['images_optimized']++;
        $stats['image']['last_updated'] = time();
        
        if ($format === 'webp') {
            $stats['image']['webp_count']++;
        } elseif ($format === 'avif') {
            $stats['image']['avif_count']++;
        }
        
        update_option(self::OPTION_KEY, $stats, false);
    }
    
    /**
     * Track HTML minification savings
     */
    public static function trackMinifySavings(int $originalBytes, int $minifiedBytes): void {
        if ($originalBytes <= 0 || $minifiedBytes <= 0) {
            return;
        }
        
        $saved = max(0, $originalBytes - $minifiedBytes);
        if ($saved === 0) {
            return;
        }
        
        $stats = self::getStats();
        $stats['minify']['total_bytes_saved'] += $saved;
        $stats['minify']['pages_minified']++;
        $stats['minify']['last_updated'] = time();
        
        update_option(self::OPTION_KEY, $stats, false);
    }
    
    /**
     * Track database cleanup
     */
    public static function trackDbCleanup(int $rowsCleaned): void {
        if ($rowsCleaned <= 0) {
            return;
        }
        
        $stats = self::getStats();
        $stats['db']['total_rows_cleaned'] += $rowsCleaned;
        $stats['db']['tasks_run']++;
        $stats['db']['last_updated'] = time();
        
        update_option(self::OPTION_KEY, $stats, false);
    }
    
    /**
     * Get requests saved from cache hits
     * This is derived from existing cache stats, not stored separately
     */
    public static function getRequestsSaved(): int {
        $cacheStats = get_option('mamba_cache_stats', ['cache_hits' => 0]);
        return (int)($cacheStats['cache_hits'] ?? 0);
    }
    
    /**
     * Get total data saved across all optimizations (in bytes)
     */
    public static function getTotalBytesSaved(): int {
        $stats = self::getStats();
        return (int)($stats['image']['total_bytes_saved'] ?? 0) + 
               (int)($stats['minify']['total_bytes_saved'] ?? 0);
    }
    
    /**
     * Format bytes to human readable string
     */
    public static function formatBytes(int $bytes, int $precision = 1): string {
        if ($bytes <= 0) {
            return '0 B';
        }
        
        $units = ['B', 'KB', 'MB', 'GB', 'TB'];
        $pow = floor(log($bytes) / log(1024));
        $pow = min($pow, count($units) - 1);
        
        $value = $bytes / pow(1024, $pow);
        
        return round($value, $precision) . ' ' . $units[$pow];
    }
    
    /**
     * Get image savings summary for display
     */
    public static function getImageSavingsSummary(): array {
        $stats = self::getStats();
        $image = $stats['image'];
        
        return [
            'bytes_saved' => (int)($image['total_bytes_saved'] ?? 0),
            'bytes_saved_formatted' => self::formatBytes((int)($image['total_bytes_saved'] ?? 0)),
            'images_optimized' => (int)($image['images_optimized'] ?? 0),
            'webp_count' => (int)($image['webp_count'] ?? 0),
            'avif_count' => (int)($image['avif_count'] ?? 0),
            'last_updated' => (int)($image['last_updated'] ?? 0),
        ];
    }
    
    /**
     * Get minification savings summary for display
     */
    public static function getMinifySavingsSummary(): array {
        $stats = self::getStats();
        $minify = $stats['minify'];
        
        return [
            'bytes_saved' => (int)($minify['total_bytes_saved'] ?? 0),
            'bytes_saved_formatted' => self::formatBytes((int)($minify['total_bytes_saved'] ?? 0)),
            'pages_minified' => (int)($minify['pages_minified'] ?? 0),
            'last_updated' => (int)($minify['last_updated'] ?? 0),
        ];
    }
    
    /**
     * Get database cleanup summary for display
     */
    public static function getDbCleanupSummary(): array {
        $stats = self::getStats();
        $db = $stats['db'];
        
        return [
            'rows_cleaned' => (int)($db['total_rows_cleaned'] ?? 0),
            'tasks_run' => (int)($db['tasks_run'] ?? 0),
            'last_updated' => (int)($db['last_updated'] ?? 0),
        ];
    }
    
    /**
     * Get complete savings overview for dashboard
     */
    public static function getDashboardSummary(): array {
        $stats = self::getStats();
        $cacheStats = get_option('mamba_cache_stats', ['cache_hits' => 0, 'cache_misses' => 0]);
        
        $totalBytesSaved = self::getTotalBytesSaved();
        $requestsSaved = self::getRequestsSaved();
        
        return [
            'total_bytes_saved' => $totalBytesSaved,
            'total_bytes_saved_formatted' => self::formatBytes($totalBytesSaved),
            'requests_saved' => $requestsSaved,
            'requests_saved_formatted' => number_format_i18n($requestsSaved),
            'image' => self::getImageSavingsSummary(),
            'minify' => self::getMinifySavingsSummary(),
            'db' => self::getDbCleanupSummary(),
            'month' => $stats['monthly_reset'] ?? date('Y-m'),
        ];
    }
    
    /**
     * Reset all savings stats (for testing or manual reset)
     */
    public static function reset(): void {
        update_option(self::OPTION_KEY, self::getDefaults(), false);
    }
    
    /**
     * Reset minification savings only (when minify is disabled)
     */
    public static function resetMinifySavings(): void {
        $stats = self::getStats();
        $stats['minify'] = [
            'total_bytes_saved' => 0,
            'pages_minified' => 0,
            'last_updated' => 0,
        ];
        update_option(self::OPTION_KEY, $stats, false);
    }
    
    /**
     * Reset image savings only (when reverting optimizations)
     */
    public static function resetImageSavings(): void {
        $stats = self::getStats();
        $stats['image'] = [
            'total_bytes_saved' => 0,
            'images_optimized' => 0,
            'webp_count' => 0,
            'avif_count' => 0,
            'last_updated' => 0,
        ];
        update_option(self::OPTION_KEY, $stats, false);
    }
}
