<?php

namespace App\Services;

use App\Models\User;
use App\Models\Order;
use App\Models\PoolDistribution;
use App\Models\PoolShare;
use App\Models\Setting;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class PoolService
{
    /**
     * Récupérer les statistiques du pool
     */
    public function getPoolStats($month = null, $year = null)
    {
        $month = $month ?? now()->month;
        $year = $year ?? now()->year;
        
        // Calcul des ventes du mois
        $monthlySales = Order::where('status', 'delivered')
            ->whereMonth('created_at', $month)
            ->whereYear('created_at', $year)
            ->sum('total_amount') ?? 0;
        
        // Pourcentage du pool
        $poolPercentage = floatval(Setting::where('key', 'pool_percentage')->value('value') ?? 10);
        $poolAmount = ($monthlySales * $poolPercentage) / 100;
        
        // Distributeurs actifs
        $activeDistributors = count($this->getActiveDistributors($month, $year));
        
        // Paramètres
        $minimumPurchase = floatval(Setting::where('key', 'minimum_monthly_purchase')->value('value') ?? 100000);
        $minimumReferrals = intval(Setting::where('key', 'minimum_referrals_for_pool')->value('value') ?? 3);
        
        return [
            'month' => $month,
            'year' => $year,
            'monthly_sales' => $monthlySales,
            'pool_percentage' => $poolPercentage,
            'pool_amount' => $poolAmount,
            'active_distributors' => $activeDistributors,
            'minimum_purchase' => $minimumPurchase,
            'minimum_referrals' => $minimumReferrals,
            'period' => Carbon::createFromDate($year, $month, 1)->format('F Y')
        ];
    }
    
    /**
     * Récupérer les distributeurs actifs
     */
    public function getActiveDistributors($month = null, $year = null)
    {
        $month = $month ?? now()->month;
        $year = $year ?? now()->year;
        
        $minimumPurchase = floatval(Setting::where('key', 'minimum_monthly_purchase')->value('value') ?? 100000);
        $minimumReferrals = intval(Setting::where('key', 'minimum_referrals_for_pool')->value('value') ?? 3);
        
        // Utilisateurs actifs
        $users = User::where('is_active', true)->get();
        
        $activeDistributors = [];
        
        foreach ($users as $user) {
            // Ventes personnelles du mois (completed ou delivered)
            $personalSales = Order::where('user_id', $user->id)
                ->whereIn('status', ['completed', 'delivered'])
                ->whereMonth('created_at', $month)
                ->whereYear('created_at', $year)
                ->sum('total_amount') ?? 0;
            
            // Ventes de l'équipe (filleuls)
            $teamSales = 0;
            $activeReferralsWithSales = 0;
            $totalReferrals = 0;
            
            // Récupérer les filleuls actifs via la relation
            try {
                $referrals = $user->referrals()->where('is_active', true)->get();
                $totalReferrals = $referrals->count();
                
                foreach ($referrals as $referral) {
                    $referralSales = Order::where('user_id', $referral->id)
                        ->whereIn('status', ['completed', 'delivered'])
                        ->whereMonth('created_at', $month)
                        ->whereYear('created_at', $year)
                        ->sum('total_amount') ?? 0;
                    
                    if ($referralSales > 0) {
                        $teamSales += $referralSales;
                        $activeReferralsWithSales++;
                    }
                }
            } catch (\Exception $e) {
                Log::warning('Erreur récupération filleuls pour pool: ' . $e->getMessage());
            }
            
            // Total des ventes
            $totalSales = $personalSales + $teamSales;
            
            // Vérifier l'éligibilité :
            // - Ventes totales >= minimum d'achat
            // - Nombre de filleuls actifs (total) >= minimum de filleuls requis
            if ($totalSales >= $minimumPurchase && $totalReferrals >= $minimumReferrals) {
                $activeDistributors[] = [
                    'user' => $user,
                    'personal_sales' => $personalSales,
                    'team_sales' => $teamSales,
                    'total_sales' => $totalSales,
                    'total_referrals' => $totalReferrals,
                    'active_referrals_with_sales' => $activeReferralsWithSales
                ];
            }
        }
        
        return $activeDistributors;
    }
    
    /**
     * Distribuer le pool
     */
    public function distributePool($month = null, $year = null)
    {
        try {
            DB::beginTransaction();
            
            $month = $month ?? now()->subMonth()->month;
            $year = $year ?? now()->subMonth()->year;
            
            // Vérifier si déjà distribué
            $alreadyDistributed = PoolDistribution::where('month', $month)
                ->where('year', $year)
                ->exists();
                
            if ($alreadyDistributed) {
                return [
                    'success' => false,
                    'message' => 'Le pool pour cette période a déjà été distribué.'
                ];
            }
            
            // Récupérer les statistiques
            $stats = $this->getPoolStats($month, $year);
            
            // Récupérer les distributeurs actifs
            $activeDistributors = $this->getActiveDistributors($month, $year);
            
            if (empty($activeDistributors)) {
                return [
                    'success' => false,
                    'message' => 'Aucun distributeur éligible pour la distribution.'
                ];
            }
            
            // Montant total du pool
            $totalPool = $stats['pool_amount'];
            
            // Calculer la part de chaque distributeur
            $totalSalesAll = array_sum(array_column($activeDistributors, 'total_sales'));
            
            if ($totalSalesAll <= 0) {
                return [
                    'success' => false,
                    'message' => 'Ventes totales insuffisantes.'
                ];
            }
            
            $distributions = [];
            
            foreach ($activeDistributors as $distributorData) {
                $user = $distributorData['user'];
                $totalSales = $distributorData['total_sales'];
                
                // Pourcentage de participation
                $percentage = ($totalSales / $totalSalesAll) * 100;
                
                // Montant à recevoir
                $amount = ($percentage / 100) * $totalPool;
                
                // Créer une distribution
                PoolDistribution::create([
                    'user_id' => $user->id,
                    'month' => $month,
                    'year' => $year,
                    'amount' => $amount,
                    'total_pool' => $totalPool,
                    'total_distributors' => count($activeDistributors),
                    'status' => 'distributed'
                ]);
                
                // Créer une part de pool
                $poolShare = PoolShare::create([
                    'user_id' => $user->id,
                    'amount' => $amount,
                    'global_sales' => $stats['monthly_sales'],
                    'user_contribution' => $totalSales,
                    'percentage' => $percentage,
                    'period_start' => Carbon::createFromDate($year, $month, 1)->startOfMonth(),
                    'period_end' => Carbon::createFromDate($year, $month, 1)->endOfMonth(),
                    'status' => 'paid',
                    'notes' => 'Distribution du pool - ' . $stats['period'],
                    'paid_at' => now()
                ]);
                
                // Créditer le wallet si existe
                if ($user->wallet) {
                    $balanceBefore = $user->wallet->balance;
                    $user->wallet->increment('balance', $amount);
                    $user->wallet->increment('total_earned', $amount);
                    $balanceAfter = $balanceBefore + $amount;
                    
                    // Créer une transaction wallet
                    try {
                        \App\Models\WalletTransaction::create([
                            'wallet_id' => $user->wallet->id,
                            'user_id' => $user->id,
                            'type' => 'pool_share',
                            'amount' => $amount,
                            'balance_before' => $balanceBefore,
                            'balance_after' => $balanceAfter,
                            'currency' => 'XOF',
                            'status' => 'completed',
                            'description' => "Part du pool - {$stats['period']}",
                            'reference' => 'POOL-' . $poolShare->id . '-' . time(),
                            'metadata' => json_encode([
                                'period' => $stats['period'],
                                'percentage' => round($percentage, 2),
                                'contribution' => $totalSales
                            ])
                        ]);
                    } catch (\Exception $e) {
                        Log::warning('Erreur création transaction wallet: ' . $e->getMessage());
                    }
                } else {
                    // Créer le wallet s'il n'existe pas
                    $wallet = \App\Models\Wallet::create([
                        'user_id' => $user->id,
                        'balance' => $amount,
                        'total_earned' => $amount,
                        'currency' => 'XOF'
                    ]);
                    
                    try {
                        \App\Models\WalletTransaction::create([
                            'wallet_id' => $wallet->id,
                            'user_id' => $user->id,
                            'type' => 'pool_share',
                            'amount' => $amount,
                            'balance_before' => 0,
                            'balance_after' => $amount,
                            'currency' => 'XOF',
                            'status' => 'completed',
                            'description' => "Part du pool - {$stats['period']}",
                            'reference' => 'POOL-' . $poolShare->id . '-' . time(),
                            'metadata' => json_encode([
                                'period' => $stats['period'],
                                'percentage' => round($percentage, 2),
                                'contribution' => $totalSales
                            ])
                        ]);
                    } catch (\Exception $e) {
                        Log::warning('Erreur création transaction wallet: ' . $e->getMessage());
                    }
                }
                
                $distributions[] = [
                    'user' => $user,
                    'amount' => $amount,
                    'percentage' => $percentage
                ];
            }
            
            DB::commit();
            
            return [
                'success' => true,
                'message' => 'Pool distribué avec succès.',
                'total_amount' => $totalPool,
                'distributors_count' => count($activeDistributors),
                'distributions' => $distributions
            ];
            
        } catch (\Exception $e) {
            DB::rollBack();
            
            Log::error('Erreur distribution pool: ' . $e->getMessage(), [
                'trace' => $e->getTraceAsString()
            ]);
            
            return [
                'success' => false,
                'message' => 'Erreur lors de la distribution: ' . $e->getMessage()
            ];
        }
    }
    
    /**
     * Calculer les estimations pour un distributeur
     */
    public function calculateEstimation(User $user, $month = null, $year = null)
    {
        $month = $month ?? now()->month;
        $year = $year ?? now()->year;
        
        $stats = $this->getPoolStats($month, $year);
        $activeDistributors = $this->getActiveDistributors($month, $year);
        
        $userData = null;
        foreach ($activeDistributors as $distributor) {
            if ($distributor['user']->id === $user->id) {
                $userData = $distributor;
                break;
            }
        }
        
        if (!$userData) {
            return [
                'eligible' => false,
                'reason' => 'Non éligible',
                'estimation' => 0
            ];
        }
        
        $totalSalesAll = array_sum(array_column($activeDistributors, 'total_sales'));
        $percentage = ($userData['total_sales'] / $totalSalesAll) * 100;
        $estimation = ($percentage / 100) * $stats['pool_amount'];
        
        return [
            'eligible' => true,
            'estimation' => $estimation,
            'percentage' => $percentage,
            'personal_sales' => $userData['personal_sales'],
            'team_sales' => $userData['team_sales'],
            'total_sales' => $userData['total_sales'],
            'total_referrals' => $userData['total_referrals'] ?? 0,
            'active_referrals_with_sales' => $userData['active_referrals_with_sales'] ?? 0
        ];
    }
}
