<?php

namespace App\Services;

use App\Models\AiTask;
use App\Models\AiReport;
use App\Models\Product;
use App\Models\Order;
use App\Models\User;
use App\Models\MonthlySalesTracking;
use App\Models\Commission;
use App\Models\Setting;
use App\Models\FeatureToggle;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class AiService
{
    protected $apiKey;
    protected $baseUrl = 'https://api.openai.com/v1';

    public function __construct()
    {
        $this->apiKey = env('OPENAI_API_KEY');
    }

    public function isEnabled(): bool
    {
        return FeatureToggle::isEnabled('ai_assistant');
    }

    /**
     * Générer des insights sur les données AMM
     */
    public function getAmmInsights(): array
    {
        $ammRequired = floatval(Setting::get('minimum_monthly_purchase', 50000));
        $currentMonth = now()->month;
        $currentYear = now()->year;

        // Membres avec AMM validé
        $membersWithAmm = MonthlySalesTracking::where('year', $currentYear)
            ->where('month', $currentMonth)
            ->where('has_met_amm', true)
            ->count();

        // Membres sans AMM
        $totalActiveMembers = User::where('role', 'member')->where('is_active', true)->count();
        $membersWithoutAmm = $totalActiveMembers - $membersWithAmm;

        // Taux de conformité
        $conformityRate = $totalActiveMembers > 0 ? round(($membersWithAmm / $totalActiveMembers) * 100, 1) : 0;

        // Membres proches de l'AMM (> 50%)
        $almostThere = MonthlySalesTracking::where('year', $currentYear)
            ->where('month', $currentMonth)
            ->where('has_met_amm', false)
            ->where('total_purchase_amount', '>=', $ammRequired * 0.5)
            ->count();

        $insights = [];

        // Analyse automatique
        if ($conformityRate < 30 && now()->day >= 15) {
            $insights[] = [
                'type' => 'critical',
                'message' => "Seulement {$conformityRate}% des membres ont atteint leur AMM et nous sommes déjà mi-mois. Action urgente requise.",
                'recommendation' => "Envoyez des rappels personnalisés aux {$membersWithoutAmm} membres concernés."
            ];
        }

        if ($almostThere > 0) {
            $insights[] = [
                'type' => 'opportunity',
                'message' => "{$almostThere} membres sont à plus de 50% de leur AMM.",
                'recommendation' => "Contactez-les en priorité, ils sont plus susceptibles de compléter leur achat."
            ];
        }

        // Comparer avec le mois précédent
        $lastMonthWithAmm = MonthlySalesTracking::where('year', now()->subMonth()->year)
            ->where('month', now()->subMonth()->month)
            ->where('has_met_amm', true)
            ->count();

        if ($lastMonthWithAmm > $membersWithAmm && now()->day >= 20) {
            $insights[] = [
                'type' => 'warning',
                'message' => "Ce mois a moins de conformité AMM que le mois dernier ({$membersWithAmm} vs {$lastMonthWithAmm}).",
                'recommendation' => "Analysez les causes possibles et intensifiez les rappels."
            ];
        }

        return [
            'stats' => [
                'members_with_amm' => $membersWithAmm,
                'members_without_amm' => $membersWithoutAmm,
                'conformity_rate' => $conformityRate,
                'almost_there' => $almostThere,
                'amm_required' => $ammRequired,
            ],
            'insights' => $insights,
        ];
    }

    /**
     * Obtenir les membres à contacter en priorité pour l'AMM
     */
    public function getMembersToContactForAmm(int $limit = 20): array
    {
        $ammRequired = floatval(Setting::get('minimum_monthly_purchase', 50000));
        $currentMonth = now()->month;
        $currentYear = now()->year;

        return User::where('role', 'member')
            ->where('is_active', true)
            ->whereNotIn('id', function($q) use ($currentYear, $currentMonth) {
                $q->select('user_id')
                    ->from('monthly_sales_tracking')
                    ->where('year', $currentYear)
                    ->where('month', $currentMonth)
                    ->where('has_met_amm', true);
            })
            ->get()
            ->map(function($member) use ($ammRequired, $currentYear, $currentMonth) {
                $tracking = MonthlySalesTracking::where('user_id', $member->id)
                    ->where('year', $currentYear)
                    ->where('month', $currentMonth)
                    ->first();
                
                $totalPurchase = $tracking ? $tracking->total_purchase_amount : 0;
                $percentage = min(100, round(($totalPurchase / $ammRequired) * 100, 1));
                
                return [
                    'id' => $member->id,
                    'name' => $member->name,
                    'email' => $member->email,
                    'phone' => $member->phone,
                    'whatsapp' => $member->whatsapp,
                    'total_purchase' => $totalPurchase,
                    'remaining' => max(0, $ammRequired - $totalPurchase),
                    'percentage' => $percentage,
                    'priority' => $percentage >= 75 ? 'high' : ($percentage >= 50 ? 'medium' : 'low'),
                ];
            })
            ->filter(fn($m) => $m['remaining'] > 0)
            ->sortByDesc('percentage')
            ->take($limit)
            ->values()
            ->toArray();
    }

    /**
     * Analyse des performances du réseau MLM
     */
    public function getNetworkPerformanceInsights(): array
    {
        $insights = [];

        // Leaders inactifs
        $inactiveLeaders = User::where('role', 'member')
            ->whereHas('referrals')
            ->whereDoesntHave('orders', function($q) {
                $q->where('created_at', '>=', now()->subMonths(2));
            })
            ->count();

        if ($inactiveLeaders > 0) {
            $insights[] = [
                'type' => 'warning',
                'title' => 'Leaders Inactifs',
                'message' => "{$inactiveLeaders} parrains n'ont pas commandé depuis 2 mois.",
                'action' => 'Contactez ces leaders pour comprendre les raisons de leur inactivité.'
            ];
        }

        // Membres orphelins (sans parrain)
        $orphanMembers = User::where('role', 'member')
            ->where('is_active', true)
            ->whereNull('sponsor_id')
            ->count();

        if ($orphanMembers > 10) {
            $insights[] = [
                'type' => 'info',
                'title' => 'Membres Sans Parrain',
                'message' => "{$orphanMembers} membres n'ont pas de parrain assigné.",
                'action' => 'Envisagez de leur assigner un mentor ou parrain actif.'
            ];
        }

        // Top performers
        $topPerformer = User::where('role', 'member')
            ->withCount('referrals')
            ->orderBy('referrals_count', 'desc')
            ->first();

        if ($topPerformer && $topPerformer->referrals_count > 5) {
            $insights[] = [
                'type' => 'success',
                'title' => 'Top Performer',
                'message' => "{$topPerformer->name} est votre meilleur parrain avec {$topPerformer->referrals_count} filleuls.",
                'action' => 'Valorisez ce membre et utilisez-le comme exemple.'
            ];
        }

        return $insights;
    }

    /**
     * Analyse des produits
     */
    public function getProductInsights(): array
    {
        $insights = [];

        // Produits populaires mais pas achetés
        $popularNotBought = Product::where('is_active', true)
            ->where('views_count', '>', 100)
            ->where('sales_count', '<', 5)
            ->get();

        if ($popularNotBought->count() > 0) {
            $insights[] = [
                'type' => 'opportunity',
                'title' => 'Opportunité de Conversion',
                'message' => "{$popularNotBought->count()} produits ont beaucoup de vues mais peu de ventes.",
                'products' => $popularNotBought->take(5)->pluck('name'),
                'action' => 'Analysez les prix, descriptions ou photos de ces produits.'
            ];
        }

        // Produits mal notés
        $lowRated = Product::where('is_active', true)
            ->where('reviews_count', '>', 0)
            ->where('rating', '<', 3)
            ->count();

        if ($lowRated > 0) {
            $insights[] = [
                'type' => 'warning',
                'title' => 'Produits Mal Notés',
                'message' => "{$lowRated} produits ont une note inférieure à 3/5.",
                'action' => 'Améliorez la qualité ou retirez ces produits du catalogue.'
            ];
        }

        // Stock faible
        $lowStock = Product::where('is_active', true)
            ->whereColumn('stock', '<', 'low_stock_threshold')
            ->count();

        if ($lowStock > 0) {
            $insights[] = [
                'type' => 'warning',
                'title' => 'Stock Faible',
                'message' => "{$lowStock} produits ont un stock sous le seuil d'alerte.",
                'action' => 'Réapprovisionnez ces produits rapidement.'
            ];
        }

        return $insights;
    }

    /**
     * Génère une description de produit par IA
     */
    public function generateProductDescription(Product $product): ?string
    {
        if (!$this->isEnabled()) {
            return null;
        }

        $task = AiTask::create([
            'task_type' => 'product_description',
            'taskable_type' => Product::class,
            'taskable_id' => $product->id,
            'input_data' => [
                'name' => $product->name,
                'category' => $product->category?->name ?? 'General',
                'price' => $product->price,
            ],
        ]);

        try {
            $task->markStarted();

            $response = $this->chat([
                ['role' => 'system', 'content' => 'Tu es un expert en rédaction de descriptions produits e-commerce. Génère une description attrayante, professionnelle et optimisée SEO en français.'],
                ['role' => 'user', 'content' => "Génère une description pour ce produit:\nNom: {$product->name}\nCatégorie: {$product->category?->name}\nPrix: {$product->price} XOF\n\nLa description doit être engageante, mettre en avant les bénéfices, et faire environ 150 mots."]
            ]);

            if ($response) {
                $task->markCompleted(['description' => $response]);
                return $response;
            }
        } catch (\Exception $e) {
            $task->markFailed($e->getMessage());
            Log::error('AI Product Description Error', ['error' => $e->getMessage()]);
        }

        return null;
    }

    /**
     * Generate product description from form data (before product is created)
     */
    public function generateDescriptionFromData(string $name, ?string $categoryName = null, ?float $price = null, ?string $imageBase64 = null): ?string
    {
        if (!FeatureToggle::isEnabled('ai_product_descriptions')) {
            return null;
        }

        $config = FeatureToggle::getConfig('ai_product_descriptions');
        $useVision = $config['use_vision_api'] ?? false;

        try {
            // Determine tone based on price
            $tone = 'professionnel et engageant';
            if ($price) {
                if ($price >= 100000) {
                    $tone = 'premium et luxueux';
                } elseif ($price >= 50000) {
                    $tone = 'professionnel avec emphase sur la qualité';
                } elseif ($price <= 10000) {
                    $tone = 'accessible et pratique';
                }
            }

            $categoryInfo = $categoryName ? "Catégorie: {$categoryName}\n" : "";
            
            // OPTION 2: Vision API (analyse image)
            if ($useVision && $imageBase64) {
                return $this->generateDescriptionWithVision($name, $categoryName, $price, $imageBase64, $tone, $config);
            }
            
            // OPTION 1: Text only (gratuit)
            $response = $this->chat([
                ['role' => 'system', 'content' => "Tu es un expert en rédaction de descriptions produits e-commerce. Génère une description attrayante, {$tone} et optimisée SEO en français. NE MENTIONNE JAMAIS le prix en chiffres dans la description."],
                ['role' => 'user', 'content' => "Génère une description pour ce produit:\nNom: {$name}\n{$categoryInfo}\nLa description doit être engageante, mettre en avant les bénéfices et caractéristiques, et faire environ 100-150 mots. N'inclus PAS le prix dans la description."]
            ]);

            return $response;
        } catch (\Exception $e) {
            Log::error('AI Description Generation Error', ['error' => $e->getMessage()]);
            return null;
        }
    }

    /**
     * Generate description with image analysis (Option 2 - Vision API)
     */
    protected function generateDescriptionWithVision(string $name, ?string $categoryName, ?float $price, string $imageBase64, string $tone, array $config): ?string
    {
        $provider = $config['vision_provider'] ?? 'openai';
        $apiKey = $config['api_key'] ?? env('OPENAI_API_KEY');

        if (!$apiKey) {
            throw new \Exception('API Key manquante pour Vision API');
        }

        $categoryInfo = $categoryName ? " dans la catégorie {$categoryName}" : "";
        
        try {
            if ($provider === 'openai') {
                // OpenAI Vision API
                $response = Http::withHeaders([
                    'Authorization' => 'Bearer ' . $apiKey,
                    'Content-Type' => 'application/json',
                ])->post('https://api.openai.com/v1/chat/completions', [
                    'model' => 'gpt-4-vision-preview',
                    'messages' => [
                        [
                            'role' => 'system',
                            'content' => "Tu es un expert en rédaction de descriptions produits e-commerce. Génère une description {$tone} et optimisée SEO en français basée sur l'analyse visuelle de l'image. NE MENTIONNE JAMAIS le prix en chiffres."
                        ],
                        [
                            'role' => 'user',
                            'content' => [
                                [
                                    'type' => 'text',
                                    'text' => "Analyse cette image de produit nommé '{$name}'{$categoryInfo} et génère une description commerciale de 100-150 mots. Décris PRÉCISÉMENT ce que tu vois : couleurs, matériaux, forme, style, détails visuels. Mets en avant les bénéfices. N'inclus PAS le prix."
                                ],
                                [
                                    'type' => 'image_url',
                                    'image_url' => [
                                        'url' => $imageBase64
                                    ]
                                ]
                            ]
                        ]
                    ],
                    'max_tokens' => 500
                ]);

                if ($response->successful()) {
                    return $response->json()['choices'][0]['message']['content'] ?? null;
                }
                
                throw new \Exception('OpenAI Vision API error: ' . $response->body());
                
            } elseif ($provider === 'claude') {
                // Claude Vision API (Anthropic)
                $response = Http::withHeaders([
                    'x-api-key' => $apiKey,
                    'anthropic-version' => '2023-06-01',
                    'Content-Type' => 'application/json',
                ])->post('https://api.anthropic.com/v1/messages', [
                    'model' => 'claude-3-opus-20240229',
                    'max_tokens' => 500,
                    'messages' => [
                        [
                            'role' => 'user',
                            'content' => [
                                [
                                    'type' => 'image',
                                    'source' => [
                                        'type' => 'base64',
                                        'media_type' => 'image/jpeg',
                                        'data' => preg_replace('/^data:image\/\w+;base64,/', '', $imageBase64)
                                    ]
                                ],
                                [
                                    'type' => 'text',
                                    'text' => "Analyse cette image de produit nommé '{$name}'{$categoryInfo}. Génère une description commerciale {$tone} de 100-150 mots en français. Décris PRÉCISÉMENT ce que tu vois : couleurs, matériaux, forme, style. Mets en avant les bénéfices. N'inclus PAS le prix en chiffres."
                                ]
                            ]
                        ]
                    ]
                ]);

                if ($response->successful()) {
                    return $response->json()['content'][0]['text'] ?? null;
                }
                
                throw new \Exception('Claude Vision API error: ' . $response->body());
            }
        } catch (\Exception $e) {
            Log::error('Vision API Error', ['provider' => $provider, 'error' => $e->getMessage()]);
            throw $e;
        }

        return null;
    }

    public function getProductRecommendations(User $user, int $limit = 5): array
    {
        if (!$this->isEnabled()) {
            return [];
        }

        $recentOrders = $user->orders()->with('items.product')->latest()->take(5)->get();
        $purchasedProducts = $recentOrders->flatMap(fn($o) => $o->items->pluck('product.name'))->unique()->take(10)->toArray();

        if (empty($purchasedProducts)) {
            return Product::where('is_active', true)->inRandomOrder()->take($limit)->get()->toArray();
        }

        try {
            $response = $this->chat([
                ['role' => 'system', 'content' => 'Tu es un système de recommandation e-commerce. Réponds uniquement avec des catégories de produits séparées par des virgules.'],
                ['role' => 'user', 'content' => "L'utilisateur a acheté: " . implode(', ', $purchasedProducts) . "\n\nSuggère 5 catégories de produits complémentaires."]
            ]);

            return Product::where('is_active', true)
                ->inRandomOrder()
                ->take($limit)
                ->get()
                ->toArray();
        } catch (\Exception $e) {
            Log::error('AI Recommendations Error', ['error' => $e->getMessage()]);
            return [];
        }
    }

    public function moderateContent(string $content): array
    {
        if (!$this->isEnabled()) {
            return ['approved' => true, 'reason' => null];
        }

        try {
            $response = $this->chat([
                ['role' => 'system', 'content' => 'Tu es un modérateur de contenu. Analyse le texte et réponds en JSON: {"approved": true/false, "reason": "raison si rejeté"}'],
                ['role' => 'user', 'content' => "Analyse ce contenu pour détecter du spam, contenu inapproprié ou offensant:\n\n{$content}"]
            ]);

            $result = json_decode($response, true);
            return $result ?? ['approved' => true, 'reason' => null];
        } catch (\Exception $e) {
            Log::error('AI Moderation Error', ['error' => $e->getMessage()]);
            return ['approved' => true, 'reason' => null];
        }
    }

    public function detectStagnantLeaders(): array
    {
        if (!$this->isEnabled()) {
            return [];
        }

        $leaders = User::where('role', 'member')
            ->whereHas('referrals')
            ->with(['referrals', 'commissions' => function($q) {
                $q->where('created_at', '>=', now()->subMonths(3));
            }])
            ->get();

        $stagnant = [];
        foreach ($leaders as $leader) {
            $recentCommissions = $leader->commissions->sum('amount');
            $totalReferrals = $leader->referrals->count();
            
            if ($totalReferrals >= 3 && $recentCommissions < 10000) {
                $stagnant[] = [
                    'user' => $leader,
                    'referrals' => $totalReferrals,
                    'recent_commissions' => $recentCommissions,
                    'recommendation' => 'Proposer une formation ou des incentives pour relancer l\'activité',
                ];
            }
        }

        return $stagnant;
    }

    public function generateSalesSummary(string $period = 'monthly'): ?string
    {
        if (!$this->isEnabled()) {
            return null;
        }

        $startDate = match($period) {
            'weekly' => now()->startOfWeek(),
            'monthly' => now()->startOfMonth(),
            'quarterly' => now()->startOfQuarter(),
            default => now()->startOfMonth(),
        };

        $orders = Order::where('created_at', '>=', $startDate)->get();
        $totalSales = $orders->sum('total_amount');
        $orderCount = $orders->count();
        $avgOrder = $orderCount > 0 ? $totalSales / $orderCount : 0;

        $topProducts = Product::withCount(['orderItems as sales_count' => function($q) use ($startDate) {
            $q->whereHas('order', fn($o) => $o->where('created_at', '>=', $startDate));
        }])->orderByDesc('sales_count')->take(5)->get();

        try {
            $response = $this->chat([
                ['role' => 'system', 'content' => 'Tu es un analyste commercial. Génère un résumé analytique concis et professionnel en français.'],
                ['role' => 'user', 'content' => "Génère un résumé des ventes:\n- Période: {$period}\n- Total ventes: " . number_format($totalSales) . " XOF\n- Nombre commandes: {$orderCount}\n- Panier moyen: " . number_format($avgOrder) . " XOF\n- Top produits: " . $topProducts->pluck('name')->implode(', ')]
            ]);

            return $response;
        } catch (\Exception $e) {
            Log::error('AI Sales Summary Error', ['error' => $e->getMessage()]);
            return null;
        }
    }

    public function suggestPricing(Product $product): ?array
    {
        if (!$this->isEnabled()) {
            return null;
        }

        $similarProducts = Product::where('category_id', $product->category_id)
            ->where('id', '!=', $product->id)
            ->where('is_active', true)
            ->get();

        $avgPrice = $similarProducts->avg('price') ?? $product->price;
        $minPrice = $similarProducts->min('price') ?? $product->price * 0.7;
        $maxPrice = $similarProducts->max('price') ?? $product->price * 1.3;

        return [
            'current_price' => $product->price,
            'average_market_price' => round($avgPrice, 0),
            'suggested_min' => round($minPrice, 0),
            'suggested_max' => round($maxPrice, 0),
            'recommendation' => $product->price < $avgPrice ? 'Votre prix est compétitif' : 'Envisagez de réduire le prix pour rester compétitif',
        ];
    }

    public function generateAiReport(string $type, string $period): AiReport
    {
        $periodDates = $this->getPeriodDates($period);
        
        $data = match($type) {
            'sales' => $this->getSalesData($periodDates['start'], $periodDates['end']),
            'mlm' => $this->getMlmData($periodDates['start'], $periodDates['end']),
            'products' => $this->getProductsData($periodDates['start'], $periodDates['end']),
            default => [],
        };

        $insights = [];
        $recommendations = [];

        if ($this->isEnabled()) {
            try {
                $response = $this->chat([
                    ['role' => 'system', 'content' => 'Tu es un analyste business. Génère des insights et recommandations en JSON: {"insights": ["insight1", "insight2"], "recommendations": ["rec1", "rec2"]}'],
                    ['role' => 'user', 'content' => "Analyse ces données et génère des insights:\n" . json_encode($data, JSON_PRETTY_PRINT)]
                ]);

                $parsed = json_decode($response, true);
                $insights = $parsed['insights'] ?? [];
                $recommendations = $parsed['recommendations'] ?? [];
            } catch (\Exception $e) {
                Log::error('AI Report Generation Error', ['error' => $e->getMessage()]);
            }
        }

        return AiReport::create([
            'report_type' => $type,
            'period' => $period,
            'period_start' => $periodDates['start'],
            'period_end' => $periodDates['end'],
            'data' => $data,
            'insights' => $insights,
            'recommendations' => $recommendations,
        ]);
    }

    protected function chat(array $messages): ?string
    {
        if (!$this->apiKey) {
            return null;
        }

        $response = Http::withHeaders([
            'Authorization' => 'Bearer ' . $this->apiKey,
            'Content-Type' => 'application/json',
        ])->post($this->baseUrl . '/chat/completions', [
            'model' => 'gpt-4o-mini',
            'messages' => $messages,
            'max_tokens' => 1000,
            'temperature' => 0.7,
        ]);

        if ($response->successful()) {
            return $response->json('choices.0.message.content');
        }

        throw new \Exception('AI API Error: ' . $response->body());
    }

    protected function getPeriodDates(string $period): array
    {
        return match($period) {
            'daily' => ['start' => now()->startOfDay(), 'end' => now()->endOfDay()],
            'weekly' => ['start' => now()->startOfWeek(), 'end' => now()->endOfWeek()],
            'monthly' => ['start' => now()->startOfMonth(), 'end' => now()->endOfMonth()],
            'quarterly' => ['start' => now()->startOfQuarter(), 'end' => now()->endOfQuarter()],
            'yearly' => ['start' => now()->startOfYear(), 'end' => now()->endOfYear()],
            default => ['start' => now()->startOfMonth(), 'end' => now()->endOfMonth()],
        };
    }

    protected function getSalesData($start, $end): array
    {
        $orders = Order::whereBetween('created_at', [$start, $end])->get();
        return [
            'total_revenue' => $orders->sum('total_amount'),
            'order_count' => $orders->count(),
            'average_order' => $orders->count() > 0 ? $orders->sum('total_amount') / $orders->count() : 0,
        ];
    }

    protected function getMlmData($start, $end): array
    {
        return [
            'new_members' => User::whereBetween('created_at', [$start, $end])->where('role', 'member')->count(),
            'total_commissions' => \App\Models\Commission::whereBetween('created_at', [$start, $end])->sum('amount'),
        ];
    }

    protected function getProductsData($start, $end): array
    {
        return [
            'new_products' => Product::whereBetween('created_at', [$start, $end])->count(),
            'active_products' => Product::where('is_active', true)->count(),
        ];
    }

    /**
     * Alias pour generateAiReport - utilisé par AiController
     */
    public function generateAnalyticsReport(string $type, string $period): AiReport
    {
        return $this->generateAiReport($type, $period);
    }
}
