<?php

namespace App\Http\Controllers\Firebase;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Yajra\DataTables\Facades\DataTables;
use Carbon\Carbon;
use Illuminate\Support\Facades\Auth;
use App\Helpers\AppConfig;



class ReservationController extends Controller
{
    /**
     * Affiche la liste des réservations
     */
    public function index(Request $request)
    {
        $firestore = app('firebase.firestore');
        $collection = $firestore->collection('reservations');
        $documents = $collection->documents();

        $reservations = [];
        foreach ($documents as $document) {
            if ($document->exists()) {
                $data = $document->data();
                $data['id'] = $document->id();

                // Formater les dates
                $dateFields = ['createdAt', 'updatedAt', 'paidAt'];
                foreach ($dateFields as $field) {
                    if (isset($data[$field])) {
                        if ($data[$field] instanceof \Google\Cloud\Core\Timestamp) {
                            $dateTime = $data[$field]->get();
                            $data[$field] = Carbon::instance($dateTime)->format('d/m/Y H:i:s');
                        } else {
                            $data[$field] = Carbon::parse($data[$field])->format('d/m/Y H:i:s');
                        }
                    }
                }

                // Récupérer les infos client et chauffeur si besoin
                $data['clientName'] = $this->getUserName($data['clientId'] ?? null);
                $data['driverName'] = $this->getUserName($data['driverId'] ?? null);

                $reservations[] = $data;
            }
        }

         if ($request->ajax()) {
            return DataTables::of($reservations)
                ->addIndexColumn()
                ->addColumn('trip_info', function ($row) {
                    $trip = $row['tripDetails'] ?? [];
                    return ($trip['departureCity'] ?? 'N/A') . ' → ' . ($trip['arrivalCity'] ?? 'N/A');
                })
                ->addColumn('departureTime', function ($row) {
				    $tripDetails = $row['tripDetails'] ?? [];

				    return $tripDetails['departureTime'] ?? 'N/A';
				        
				})
                ->addColumn('client_info', function ($row) {
                    return $row['clientName'] ?? $row['clientId'] ?? '-';
                })
                ->addColumn('compagnie', function ($row) {
				    $tripDetails = $row['tripDetails'] ?? [];

				    return $tripDetails['driverName'] ?? 'N/A';
				        
				})
                ->addColumn('passengers_count', function ($row) {
                    $passengers = $row['passengers'] ?? [];
                    return count($passengers);
                })
                ->addColumn('price', function ($row) {
                    return number_format($row['totalPrice'] ?? 0, 0, ',', ' ');
                })
                ->addColumn('status_badge', function ($row) {
                    $status = $row['status'] ?? 'unknown';
                    return $status;
                })
                ->addColumn('payment', function ($row) {
                    return $row['paymentMethod'] ?? '-';
                })
                ->addColumn('created_at', function ($row) {
                    return $row['createdAt'] ?? '-';
                })
                ->addColumn('action', function ($row) {
                    return '<a href="' . route('reservations.show', $row['id']) . '" class="btn btn-info btn-sm">Voir</a>';
                })
                ->rawColumns(['action'])
                ->make(true);
        }


        return view('firebase.reservations.index');
    }

    /**
     * Affiche les détails d'une réservation
     */
    public function show($reservationId)
    {
        $firestore = app('firebase.firestore');
        
        $reservationDoc = $firestore->collection('reservations')->document($reservationId)->snapshot();
        
        if (!$reservationDoc->exists()) {
            return redirect()->route('reservations.index')->with('error', 'Réservation non trouvée');
        }

        $reservation = $reservationDoc->data();
        $reservation['id'] = $reservationDoc->id();

        // Formater les dates
        $dateFields = ['createdAt', 'updatedAt', 'paidAt'];
        foreach ($dateFields as $field) {
            if (isset($reservation[$field])) {
                if ($reservation[$field] instanceof \Google\Cloud\Core\Timestamp) {
                    $dateTime = $reservation[$field]->get();
                    $reservation[$field] = Carbon::instance($dateTime)->format('d/m/Y H:i:s');
                }
            }
        }

        // Récupérer les noms
        $reservation['clientName'] = $this->getUserName($reservation['clientId'] ?? null);
        $reservation['driverName'] = $this->getUserName($reservation['driverId'] ?? null);

        return view('firebase.reservations.show', compact('reservation'));
    }

    /**
     * Récupère le nom d'un utilisateur
     */
    private function getUserName($userId)
    {
        if (!$userId) return null;
        
        try {
            $firestore = app('firebase.firestore');
            $userDoc = $firestore->collection('userProfiles')->document($userId)->snapshot();
            
            if ($userDoc->exists()) {
                $userData = $userDoc->data();
                return $userData['displayName'] ?? $userData['email'] ?? $userId;
            }
        } catch (\Exception $e) {
            // Log error
        }
        
        return $userId;
    }

    /**
 * Annuler une réservation
 * TODO: on doit gerer apres les politiques d'annulations, les autres moyens de paiements
 * @param Request $request
 * @param string $reservationId
 * @return \Illuminate\Http\JsonResponse
 */
    public function cancel(Request $request, $reservationId)
    {

        // Récupérer des valeurs de configuration
        //-------------------------------------------------------------------
        $isRemboursableWallet = AppConfig::get('busOptions.estRemboursableViaWallet', false);
        $minHours = AppConfig::get('busOptions.CANCELLATION_MIN_HOURS_BEFORE_DEPARTURE', 72);
        $currency = AppConfig::get('currency', 'FCFA');
        $appName = AppConfig::get('applicationName', 'Ticko');

        //----------------------------------------------------------------------------

        // Vérifier quel type d'application
        // if (AppConfig::get('baseApp.isBUS')) {
        //     // Logique pour BUS
        // } elseif (AppConfig::get('baseApp.isCOV')) {
        //     // Logique pour COV
        // }


        $userConnected = Auth::user();
        $userId = $userConnected->id;

        try {
            $firestore = app('firebase.firestore');
            
            // 1. Récupérer la réservation
            $reservationRef = $firestore->collection('reservations')->document($reservationId);
            $reservationSnapshot = $reservationRef->snapshot();
            
            if (!$reservationSnapshot->exists()) {
                return response()->json([
                    'success' => false,
                    'error' => 'Réservation non trouvée'
                ], 404);
            }

            $reservation = $reservationSnapshot->data();
            
            // 2. Vérifier que la réservation peut être annulée , ce qui peut etre annuler est ce qui est confirmed
            $currentStatus = $reservation['status'] ?? null;
            
            if (!in_array($currentStatus, ['confirmed'])) { // if (!in_array($currentStatus, ['pending', 'confirmed']))
                return response()->json([
                    'success' => false,
                    'error' => 'Cette réservation ne peut pas être annulée (statut: ' . $currentStatus . ')'
                ], 400);
            }

            // 3. Récupérer le wallet du client
            $clientId = $reservation['clientId'] ?? null;
            if (!$clientId) {
                return response()->json([
                    'success' => false,
                    'error' => 'Client non identifié'
                ], 400);
            }

            // Chercher le wallet du client
            $walletsCollection = $firestore->collection('wallets');
            $walletQuery = $walletsCollection->where('userId', '=', $clientId);
            $walletDocuments = $walletQuery->documents();
            
            $walletRef = null;
            $walletData = null;
            
            foreach ($walletDocuments as $doc) {
                if ($doc->exists()) {
                    $walletRef = $walletsCollection->document($doc->id());
                    $walletData = $doc->data();
                    break;
                }
            }

            // 4. Si paiement par wallet, rembourser
            $paymentMethod = $reservation['paymentMethod'] ?? null;
            $totalPrice = $reservation['totalPrice'] ?? 0;
            $refundAmount = $totalPrice; // Remboursement total
            
            if ($isRemboursableWallet && $paymentMethod === 'wallet' && $totalPrice > 0 && $walletRef) {
                // Mettre à jour le solde du wallet
                $currentBalance = $walletData['balance'] ?? 0;
                $newBalance = $currentBalance + $refundAmount;
                 
                // Créer la transaction de remboursement
                $transactionData = [
                    'walletId' => $walletRef->id(),
                    'amount' => $refundAmount,
                    'type' => 'refund',
                    'reference' => $reservationId,
                    'createdAt' => new \Google\Cloud\Core\Timestamp(new \DateTime())
                ];
                
                $firestore->collection('wallet_transactions')->add($transactionData);
                
                // Mettre à jour le wallet
                $walletRef->set([
                    'balance' => $newBalance,
                    'updatedAt' => new \Google\Cloud\Core\Timestamp(new \DateTime())
                ], ['merge' => true]);
            }

            // 5. Libérer les sièges dans le trajet
            $tripId = $reservation['tripId'] ?? null;
            $seatsReserved = $reservation['seatsReserved'] ?? 1;
            
            if ($tripId) {
                $tripRef = $firestore->collection('trips')->document($tripId);
                $tripSnapshot = $tripRef->snapshot();
                
                if ($tripSnapshot->exists()) {
                    $tripData = $tripSnapshot->data();
                    $availableSeats = $tripData['availableSeats'] ?? 0;
                    
                    // Remettre les sièges disponibles
                    $tripRef->set([
                        'availableSeats' => $availableSeats + $seatsReserved,
                        'updatedAt' => new \Google\Cloud\Core\Timestamp(new \DateTime())
                    ], ['merge' => true]);
                }
            }

            // 6. Mettre à jour le statut de la réservation
            $reservationRef->set([
                'status' => 'cancelled',
                'updatedAt' => new \Google\Cloud\Core\Timestamp(new \DateTime()),
                'cancelledAt' => new \Google\Cloud\Core\Timestamp(new \DateTime()),
                'refundAmount' => $paymentMethod === 'wallet' ? $refundAmount : 0,
                'refundStatus' => $paymentMethod === 'wallet' ? 'completed' : 'not_applicable'
            ], ['merge' => true]);

            // 7. Log de l'annulation (optionnel)

            $cancellationLog = [
                'reservationId' => $reservationId,
                'clientId' => $clientId,
                'userConnectedId' => $userId,
                'userConnectedEmail' => $userConnected->email,
                'cancelledAt' => new \Google\Cloud\Core\Timestamp(new \DateTime()),
                'reason' => $request->input('reason', 'Annulation par l\'utilisateur'),
                'refunded' => $paymentMethod === 'wallet',
                'refundAmount' => $refundAmount
            ];
            
            // Optionnel: stocker dans une collection de logs
            $firestore->collection('cancellation_logs')->add($cancellationLog);

            return response()->json([
                'success' => true,
                'message' => 'Réservation annulée avec succès',
                'data' => [
                    'reservation_id' => $reservationId,
                    'refunded' => $paymentMethod === 'wallet',
                    'refund_amount' => $refundAmount,
                    'new_status' => 'cancelled'
                ]
            ]);

        } catch (\Exception $e) {
            \Log::error('Erreur lors de l\'annulation de la réservation: ' . $e->getMessage(), [
                'reservation_id' => $reservationId,
                'trace' => $e->getTraceAsString()
            ]);

            return response()->json([
                'success' => false,
                'error' => 'Erreur lors de l\'annulation: ' . $e->getMessage()
            ], 500);
        }
    }


    /**
     * Annulation manuelle d'une réservation (sans remboursement)
     * 
     * @param Request $request
     * @param string $reservationId
     * @return \Illuminate\Http\JsonResponse
     */
    public function cancelManual(Request $request, $reservationId)
    {
        try {
            $firestore = app('firebase.firestore');
            
            // 1. Récupérer la réservation
            $reservationRef = $firestore->collection('reservations')->document($reservationId);
            $reservationSnapshot = $reservationRef->snapshot();
            
            if (!$reservationSnapshot->exists()) {
                return response()->json([
                    'success' => false,
                    'error' => 'Réservation non trouvée'
                ], 404);
            }

            $reservation = $reservationSnapshot->data();
            
            // 2. Vérifier que la réservation peut être annulée
            $currentStatus = $reservation['status'] ?? null;
            
            if (!in_array($currentStatus, ['pending', 'confirmed'])) {
                return response()->json([
                    'success' => false,
                    'error' => 'Cette réservation ne peut pas être annulée (statut: ' . $currentStatus . ')'
                ], 400);
            }

            // 3. Libérer les sièges dans le trajet
            $tripId = $reservation['tripId'] ?? null;
            $seatsReserved = $reservation['seatsReserved'] ?? 1;
            
            if ($tripId) {
                $tripRef = $firestore->collection('trips')->document($tripId);
                $tripSnapshot = $tripRef->snapshot();
                
                if ($tripSnapshot->exists()) {
                    $tripData = $tripSnapshot->data();
                    $availableSeats = $tripData['availableSeats'] ?? 0;
                    
                    // Remettre les sièges disponibles
                    $tripRef->set([
                        'availableSeats' => $availableSeats + $seatsReserved,
                        'updatedAt' => new \Google\Cloud\Core\Timestamp(new \DateTime())
                    ], ['merge' => true]);
                }
            }

            // 4. Mettre à jour le statut de la réservation
            $reservationRef->set([
                'status' => 'cancelled',
                'updatedAt' => new \Google\Cloud\Core\Timestamp(new \DateTime()),
                'cancelledAt' => new \Google\Cloud\Core\Timestamp(new \DateTime()),
                'cancellationType' => 'manual', // Pour distinguer les types d'annulation
                'refunded' => false, // Pas de remboursement
                'cancellationReason' => $request->input('reason', 'Annulation manuelle')
            ], ['merge' => true]);

            // 5. Log de l'annulation manuelle
            $cancellationLog = [
                'reservationId' => $reservationId,
                'cancelledBy' => Auth::id(), // ID de l'admin qui annule
                'cancelledAt' => new \Google\Cloud\Core\Timestamp(new \DateTime()),
                'reason' => $request->input('reason', 'Annulation manuelle'),
                'type' => 'manual',
                'refunded' => false
            ];
            
            // Optionnel: stocker dans une collection de logs
            // $firestore->collection('cancellation_logs')->add($cancellationLog);

            return response()->json([
                'success' => true,
                'message' => 'Réservation annulée manuellement avec succès',
                'data' => [
                    'reservation_id' => $reservationId,
                    'new_status' => 'cancelled',
                    'refunded' => false,
                    'seats_freed' => $seatsReserved
                ]
            ]);

        } catch (\Exception $e) {
            \Log::error('Erreur lors de l\'annulation manuelle: ' . $e->getMessage(), [
                'reservation_id' => $reservationId,
                'trace' => $e->getTraceAsString()
            ]);

            return response()->json([
                'success' => false,
                'error' => 'Erreur lors de l\'annulation manuelle: ' . $e->getMessage()
            ], 500);
        }
    }

}