<?php

namespace App\Services;

use App\Models\Order;
use App\Models\OrderItem;
use App\Models\Product;
use App\Models\Seller;
use App\Models\Commission;
use App\Models\Wallet;
use App\Models\WalletTransaction;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;

class SellerOrderService
{
    protected WalletService $walletService;

    public function __construct()
    {
        $this->walletService = new WalletService();
    }

    /**
     * Traiter les produits seller dans une commande
     * - Attribue seller_id aux order_items
     * - Calcule la commission de la plateforme
     * - Crédite le wallet du seller (montant - commission)
     * - Envoie les notifications aux sellers
     */
    public function processSellerItems(Order $order): array
    {
        $results = [
            'total_seller_items' => 0,
            'total_seller_amount' => 0,
            'total_platform_commission' => 0,
            'sellers_credited' => [],
            'errors' => []
        ];

        try {
            DB::beginTransaction();

            // Charger les items avec les produits
            $order->load('orderItems.product');

            foreach ($order->orderItems as $item) {
                // Vérifier si le produit appartient à un seller
                $product = $item->product;
                
                if (!$product) {
                    continue;
                }

                // Si le produit a un seller_id, c'est un produit vendeur
                if ($product->seller_id) {
                    $seller = Seller::find($product->seller_id);
                    
                    if (!$seller) {
                        Log::warning('Seller not found for product', [
                            'product_id' => $product->id,
                            'seller_id' => $product->seller_id
                        ]);
                        continue;
                    }

                    // Calculer les montants
                    $itemTotal = floatval($item->total_price);
                    $commissionRate = floatval($seller->commission_rate ?? 10); // 10% par défaut
                    $platformCommission = ($itemTotal * $commissionRate) / 100;
                    $sellerAmount = $itemTotal - $platformCommission;

                    // Mettre à jour l'order_item
                    $item->update([
                        'seller_id' => $seller->id,
                        'seller_commission' => $platformCommission,
                        'seller_amount' => $sellerAmount,
                        'seller_paid' => false
                    ]);

                    // Accumuler les montants par seller
                    if (!isset($results['sellers_credited'][$seller->id])) {
                        $results['sellers_credited'][$seller->id] = [
                            'seller' => $seller,
                            'amount' => 0,
                            'commission' => 0,
                            'items' => []
                        ];
                    }
                    $results['sellers_credited'][$seller->id]['amount'] += $sellerAmount;
                    $results['sellers_credited'][$seller->id]['commission'] += $platformCommission;
                    $results['sellers_credited'][$seller->id]['items'][] = $item;

                    $results['total_seller_items']++;
                    $results['total_seller_amount'] += $sellerAmount;
                    $results['total_platform_commission'] += $platformCommission;

                    Log::info('Seller item processed', [
                        'order_id' => $order->id,
                        'item_id' => $item->id,
                        'product_id' => $product->id,
                        'seller_id' => $seller->id,
                        'item_total' => $itemTotal,
                        'commission_rate' => $commissionRate,
                        'platform_commission' => $platformCommission,
                        'seller_amount' => $sellerAmount
                    ]);
                }
            }

            // IMPORTANT: Créer les transactions en PENDING (pas de crédit immédiat)
            // Le crédit réel se fait uniquement après approbation de la preuve de livraison par l'admin
            // Voir Admin\OrderController::approveDeliveryProof()
            
            // Créer des transactions en attente pour chaque seller
            foreach ($results['sellers_credited'] as $sellerId => $sellerData) {
                $seller = $sellerData['seller'];
                $amount = $sellerData['amount'];
                
                if (!$seller->user) {
                    continue;
                }
                
                // Créer ou obtenir le wallet du seller
                $wallet = Wallet::firstOrCreate(
                    ['user_id' => $seller->user_id],
                    ['balance' => 0, 'pending_balance' => 0, 'currency' => 'XOF']
                );
                
                // Ajouter au pending_balance (pas au balance)
                $wallet->increment('pending_balance', $amount);
                
                // Créer la transaction en PENDING
                WalletTransaction::create([
                    'wallet_id' => $wallet->id,
                    'user_id' => $seller->user_id,
                    'type' => 'seller_sale',
                    'amount' => $amount,
                    'balance_before' => $wallet->balance,
                    'balance_after' => $wallet->balance, // Ne change pas car pending
                    'currency' => $wallet->currency,
                    'status' => 'pending', // EN ATTENTE de validation
                    'reference' => 'PND-' . strtoupper(uniqid()),
                    'description' => "Vente en attente - Commande #{$order->order_number} (Commission {$seller->commission_rate}% déduite)",
                    'metadata' => [
                        'order_id' => $order->id,
                        'order_number' => $order->order_number,
                        'seller_id' => $seller->id,
                        'gross_amount' => $sellerData['amount'] + $sellerData['commission'],
                        'commission_rate' => $seller->commission_rate,
                        'commission_amount' => $sellerData['commission'],
                        'awaiting_delivery_proof' => true
                    ]
                ]);
                
                Log::info('Pending seller transaction created', [
                    'seller_id' => $seller->id,
                    'user_id' => $seller->user_id,
                    'amount' => $amount,
                    'order_id' => $order->id
                ]);
            }
            
            // Mettre à jour le seller_amount de la commande (pour tracking en attente)
            if ($results['total_seller_amount'] > 0) {
                $order->update([
                    'seller_amount' => $results['total_seller_amount']
                ]);
            }

            // Mettre à jour le seller_id principal de la commande (si un seul seller)
            if (count($results['sellers_credited']) === 1) {
                $sellerId = array_key_first($results['sellers_credited']);
                $order->update(['seller_id' => $sellerId]);
            }

            // Mettre à jour les statistiques des sellers et envoyer notifications
            foreach ($results['sellers_credited'] as $sellerData) {
                $seller = $sellerData['seller'];
                $seller->increment('total_sales', count($sellerData['items']));
                $seller->increment('total_revenue', $sellerData['amount']);
                
                // Notification de nouvelle commande au seller
                if ($seller->user_id) {
                    NotificationService::sellerNewOrder(
                        $seller->user_id,
                        $order->order_number,
                        $sellerData['amount'] + $sellerData['commission'], // Montant brut
                        count($sellerData['items'])
                    );
                }
            }

            DB::commit();

            Log::info('Seller order processing completed', [
                'order_id' => $order->id,
                'total_items' => $results['total_seller_items'],
                'total_amount' => $results['total_seller_amount'],
                'total_commission' => $results['total_platform_commission'],
                'sellers_count' => count($results['sellers_credited'])
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            $results['errors'][] = $e->getMessage();
            Log::error('Error processing seller items', [
                'order_id' => $order->id,
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
        }

        return $results;
    }

    /**
     * Créditer les wallets des sellers après paiement confirmé
     */
    public function creditSellersWallets(Order $order, array &$results): void
    {
        foreach ($results['sellers_credited'] as $sellerId => &$sellerData) {
            $seller = $sellerData['seller'];
            $amount = $sellerData['amount'];

            try {
                // Récupérer l'utilisateur associé au seller
                $user = $seller->user;

                if (!$user) {
                    $results['errors'][] = "User not found for seller {$seller->id}";
                    Log::warning('User not found for seller', ['seller_id' => $seller->id]);
                    continue;
                }

                // Créditer le wallet du seller
                $this->walletService->credit(
                    $user,
                    $amount,
                    'seller_sale',
                    "Vente produit - Commande #{$order->order_number} (Commission {$seller->commission_rate}% déduite)",
                    [
                        'order_id' => $order->id,
                        'order_number' => $order->order_number,
                        'seller_id' => $seller->id,
                        'gross_amount' => $sellerData['amount'] + $sellerData['commission'],
                        'commission_rate' => $seller->commission_rate,
                        'commission_amount' => $sellerData['commission']
                    ]
                );

                // Marquer les items comme payés
                foreach ($sellerData['items'] as $item) {
                    $item->update([
                        'seller_paid' => true,
                        'seller_paid_at' => now()
                    ]);
                }

                // Créer un enregistrement de commission pour tracking
                Commission::create([
                    'user_id' => $user->id,
                    'order_id' => $order->id,
                    'type' => 'seller_sale',
                    'level' => 0,
                    'amount' => $amount,
                    'status' => 'approved',
                    'description' => "Revenu vente - Commande #{$order->order_number} (Net après {$seller->commission_rate}% commission)"
                ]);

                $sellerData['credited'] = true;

                Log::info('Seller wallet credited', [
                    'seller_id' => $seller->id,
                    'user_id' => $user->id,
                    'amount' => $amount,
                    'order_id' => $order->id
                ]);

            } catch (\Exception $e) {
                $results['errors'][] = "Failed to credit seller {$seller->id}: " . $e->getMessage();
                Log::error('Failed to credit seller wallet', [
                    'seller_id' => $seller->id,
                    'error' => $e->getMessage()
                ]);
            }
        }
    }

    /**
     * Traiter une commande déjà payée (pour les paiements confirmés a posteriori)
     */
    public function processPaymentConfirmation(Order $order): array
    {
        // Si pas de seller items à traiter, retourner
        $sellerItems = OrderItem::where('order_id', $order->id)
            ->whereNotNull('seller_id')
            ->where('seller_paid', false)
            ->get();

        if ($sellerItems->isEmpty()) {
            return ['message' => 'No unpaid seller items found'];
        }

        $results = [
            'credited_count' => 0,
            'credited_amount' => 0,
            'errors' => []
        ];

        foreach ($sellerItems as $item) {
            try {
                $seller = $item->seller;
                if (!$seller || !$seller->user) {
                    continue;
                }

                $this->walletService->credit(
                    $seller->user,
                    $item->seller_amount,
                    'seller_sale',
                    "Vente produit - Commande #{$order->order_number}",
                    ['order_id' => $order->id, 'item_id' => $item->id]
                );

                $item->update([
                    'seller_paid' => true,
                    'seller_paid_at' => now()
                ]);

                $results['credited_count']++;
                $results['credited_amount'] += $item->seller_amount;

            } catch (\Exception $e) {
                $results['errors'][] = $e->getMessage();
            }
        }

        return $results;
    }

    /**
     * Récupérer les commandes pour un seller spécifique
     */
    public function getSellerOrders(Seller $seller, array $filters = [])
    {
        $query = Order::whereHas('orderItems', function ($q) use ($seller) {
            $q->where('seller_id', $seller->id);
        })
        ->with(['user', 'orderItems' => function ($q) use ($seller) {
            $q->where('seller_id', $seller->id)->with('product');
        }]);

        // Appliquer les filtres
        if (!empty($filters['status'])) {
            $query->where('status', $filters['status']);
        }

        if (!empty($filters['payment_status'])) {
            $query->where('payment_status', $filters['payment_status']);
        }

        if (!empty($filters['date_from'])) {
            $query->whereDate('created_at', '>=', $filters['date_from']);
        }

        if (!empty($filters['date_to'])) {
            $query->whereDate('created_at', '<=', $filters['date_to']);
        }

        if (!empty($filters['search'])) {
            $search = $filters['search'];
            $query->where(function ($q) use ($search) {
                $q->where('order_number', 'like', "%{$search}%")
                  ->orWhere('customer_name', 'like', "%{$search}%")
                  ->orWhere('customer_email', 'like', "%{$search}%");
            });
        }

        return $query->orderBy('created_at', 'desc');
    }

    /**
     * Calculer les statistiques de ventes pour un seller
     */
    public function getSellerStats(Seller $seller): array
    {
        $items = OrderItem::where('seller_id', $seller->id);
        
        return [
            'total_orders' => Order::whereHas('orderItems', fn($q) => $q->where('seller_id', $seller->id))->count(),
            'total_items_sold' => $items->sum('quantity'),
            'total_gross_revenue' => $items->sum('total_price'),
            'total_commission_paid' => $items->sum('seller_commission'),
            'total_net_revenue' => $items->sum('seller_amount'),
            'pending_orders' => Order::whereHas('orderItems', fn($q) => $q->where('seller_id', $seller->id))
                ->where('status', 'pending')->count(),
            'processing_orders' => Order::whereHas('orderItems', fn($q) => $q->where('seller_id', $seller->id))
                ->where('status', 'processing')->count(),
            'delivered_orders' => Order::whereHas('orderItems', fn($q) => $q->where('seller_id', $seller->id))
                ->where('status', 'delivered')->count(),
        ];
    }
}
