<?php

namespace App\Services;

use Illuminate\Support\Facades\Log;

/**
 * Service d'analyse d'images
 * Fournit des analyses basiques des images (dimensions, format, couleurs dominantes)
 */
class ImageAnalyzer
{
    /**
     * Analyser une image en base64
     *
     * @param string $base64Image L'image encodée en base64
     * @return array Les résultats de l'analyse
     */
    public static function analyze(string $base64Image): array
    {
        try {
            // Décoder l'image base64
            $imageData = base64_decode($base64Image);
            
            if (!$imageData) {
                return self::getEmptyAnalysis('Impossible de décoder l\'image');
            }

            // Créer une ressource image
            $image = @imagecreatefromstring($imageData);
            
            if (!$image) {
                return self::getEmptyAnalysis('Format d\'image non supporté');
            }

            // Obtenir les dimensions
            $width = imagesx($image);
            $height = imagesy($image);
            
            // Calculer le ratio d'aspect
            $aspectRatio = $width / max($height, 1);
            
            // Détecter les couleurs dominantes (échantillonnage simple)
            $dominantColors = self::extractDominantColors($image, $width, $height);
            
            // Calculer la luminosité moyenne
            $brightness = self::calculateAverageBrightness($image, $width, $height);
            
            // Déterminer si l'image est claire ou sombre
            $isLight = $brightness > 128;
            
            // Déterminer l'orientation
            $orientation = 'square';
            if ($aspectRatio > 1.2) {
                $orientation = 'landscape';
            } elseif ($aspectRatio < 0.8) {
                $orientation = 'portrait';
            }
            
            // Libérer la mémoire
            imagedestroy($image);

            return [
                'success' => true,
                'dimensions' => [
                    'width' => $width,
                    'height' => $height,
                    'aspect_ratio' => round($aspectRatio, 2),
                ],
                'orientation' => $orientation,
                'brightness' => [
                    'value' => round($brightness),
                    'is_light' => $isLight,
                    'description' => $isLight ? 'claire' : 'sombre',
                ],
                'dominant_colors' => $dominantColors,
                'quality_score' => self::calculateQualityScore($width, $height),
                'recommendations' => self::generateRecommendations($width, $height, $brightness),
                'analyzed_at' => now()->toIso8601String(),
            ];

        } catch (\Exception $e) {
            Log::warning('ImageAnalyzer error: ' . $e->getMessage());
            return self::getEmptyAnalysis($e->getMessage());
        }
    }

    /**
     * Extraire les couleurs dominantes de l'image
     */
    protected static function extractDominantColors($image, int $width, int $height, int $sampleSize = 5): array
    {
        $colors = [];
        $stepX = max(1, intval($width / 10));
        $stepY = max(1, intval($height / 10));
        
        // Échantillonner des points de l'image
        for ($x = 0; $x < $width; $x += $stepX) {
            for ($y = 0; $y < $height; $y += $stepY) {
                $rgb = imagecolorat($image, $x, $y);
                $r = ($rgb >> 16) & 0xFF;
                $g = ($rgb >> 8) & 0xFF;
                $b = $rgb & 0xFF;
                
                // Simplifier la couleur (regrouper les couleurs similaires)
                $r = intval($r / 32) * 32;
                $g = intval($g / 32) * 32;
                $b = intval($b / 32) * 32;
                
                $colorKey = sprintf('#%02X%02X%02X', $r, $g, $b);
                
                if (!isset($colors[$colorKey])) {
                    $colors[$colorKey] = 0;
                }
                $colors[$colorKey]++;
            }
        }
        
        // Trier par fréquence
        arsort($colors);
        
        // Retourner les couleurs les plus fréquentes
        $topColors = array_slice(array_keys($colors), 0, $sampleSize);
        
        return array_map(function ($hex) {
            return [
                'hex' => $hex,
                'name' => self::getColorName($hex),
            ];
        }, $topColors);
    }

    /**
     * Calculer la luminosité moyenne
     */
    protected static function calculateAverageBrightness($image, int $width, int $height): float
    {
        $totalBrightness = 0;
        $samples = 0;
        
        $stepX = max(1, intval($width / 20));
        $stepY = max(1, intval($height / 20));
        
        for ($x = 0; $x < $width; $x += $stepX) {
            for ($y = 0; $y < $height; $y += $stepY) {
                $rgb = imagecolorat($image, $x, $y);
                $r = ($rgb >> 16) & 0xFF;
                $g = ($rgb >> 8) & 0xFF;
                $b = $rgb & 0xFF;
                
                // Formule de luminosité perçue
                $brightness = (0.299 * $r + 0.587 * $g + 0.114 * $b);
                $totalBrightness += $brightness;
                $samples++;
            }
        }
        
        return $samples > 0 ? $totalBrightness / $samples : 0;
    }

    /**
     * Calculer un score de qualité basé sur les dimensions
     */
    protected static function calculateQualityScore(int $width, int $height): array
    {
        $pixels = $width * $height;
        
        // Score basé sur la résolution
        $score = 0;
        $label = 'faible';
        
        if ($pixels >= 4000000) { // 4MP+
            $score = 100;
            $label = 'excellente';
        } elseif ($pixels >= 2000000) { // 2MP+
            $score = 85;
            $label = 'très bonne';
        } elseif ($pixels >= 1000000) { // 1MP+
            $score = 70;
            $label = 'bonne';
        } elseif ($pixels >= 500000) { // 0.5MP+
            $score = 50;
            $label = 'moyenne';
        } elseif ($pixels >= 100000) {
            $score = 30;
            $label = 'faible';
        } else {
            $score = 10;
            $label = 'très faible';
        }
        
        return [
            'score' => $score,
            'label' => $label,
            'megapixels' => round($pixels / 1000000, 2),
        ];
    }

    /**
     * Générer des recommandations pour l'image
     */
    protected static function generateRecommendations(int $width, int $height, float $brightness): array
    {
        $recommendations = [];
        
        // Recommandations de dimension
        if ($width < 800 || $height < 800) {
            $recommendations[] = 'Utiliser une image de résolution plus élevée (minimum 800x800 recommandé)';
        }
        
        // Recommandations de ratio
        $ratio = $width / max($height, 1);
        if ($ratio < 0.5 || $ratio > 2) {
            $recommendations[] = 'Le ratio d\'aspect est très extrême, considérer un recadrage';
        }
        
        // Recommandations de luminosité
        if ($brightness < 50) {
            $recommendations[] = 'L\'image est très sombre, considérer l\'ajustement de la luminosité';
        } elseif ($brightness > 230) {
            $recommendations[] = 'L\'image est très claire/surexposée';
        }
        
        if (empty($recommendations)) {
            $recommendations[] = 'L\'image semble appropriée pour une utilisation e-commerce';
        }
        
        return $recommendations;
    }

    /**
     * Obtenir un nom de couleur approximatif
     */
    protected static function getColorName(string $hex): string
    {
        $hex = ltrim($hex, '#');
        $r = hexdec(substr($hex, 0, 2));
        $g = hexdec(substr($hex, 2, 2));
        $b = hexdec(substr($hex, 4, 2));
        
        // Détection simplifiée des couleurs
        $max = max($r, $g, $b);
        $min = min($r, $g, $b);
        $diff = $max - $min;
        
        // Gris/Noir/Blanc
        if ($diff < 30) {
            if ($max < 50) return 'noir';
            if ($max > 200) return 'blanc';
            return 'gris';
        }
        
        // Couleurs principales
        if ($r >= $g && $r >= $b) {
            if ($g > $b + 30) return 'orange';
            if ($b > $g + 30) return 'rose';
            return 'rouge';
        }
        
        if ($g >= $r && $g >= $b) {
            if ($b > $r + 30) return 'cyan';
            if ($r > $b + 30) return 'jaune';
            return 'vert';
        }
        
        if ($r > $g + 30) return 'violet';
        return 'bleu';
    }

    /**
     * Retourner une analyse vide en cas d'erreur
     */
    protected static function getEmptyAnalysis(string $error = ''): array
    {
        return [
            'success' => false,
            'error' => $error,
            'dimensions' => null,
            'orientation' => null,
            'brightness' => null,
            'dominant_colors' => [],
            'quality_score' => null,
            'recommendations' => ['Impossible d\'analyser cette image'],
            'analyzed_at' => now()->toIso8601String(),
        ];
    }
}
