GOOD SHELL MAS BOY
Server: Apache/2.4.52 (Ubuntu)
System: Linux vmi1836763.contaboserver.net 5.15.0-130-generic #140-Ubuntu SMP Wed Dec 18 17:59:53 UTC 2024 x86_64
User: www-data (33)
PHP: 8.4.10
Disabled: NONE
Upload Files
File: /var/www/console.fixgini.com/app/Http/Controllers/BookFormController.php
<?php

namespace App\Http\Controllers;

use Carbon\Carbon;
use App\Models\Gig;
use App\Models\Wallet;
use GuzzleHttp\Client;
use App\Mail\BookingAction;
use App\Models\BookingForm;
use App\Models\Transaction;
use Illuminate\Support\Str;
use App\Jobs\SendDelayedSms;
use Illuminate\Http\Request;
use App\Mail\PaymentLinkMail;
use App\Models\BookingPayment;
use App\Jobs\CompleteBookingJob;
use App\Services\ActivityLogger;
use Google\Client as GoogleClient;
use Illuminate\Support\Facades\Log;
use App\Mail\TriggerCompleteBooking;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Notification;
use App\Notifications\NewBookingNotification;

class BookFormController extends Controller
{
    public function store(Request $request)
    {
        try {
            $user = Auth::user();

            $validatedData = $request->validate([
                'gig_id' => 'required|exists:gigs,id',
                'agreed_amount' => 'required|numeric|min:0',
                'gig_price' => 'required|numeric|min:0',
                'start_time' => 'required|date|after_or_equal:today',
                'end_time' => 'required|date|after_or_equal:start_time',
                'message' => 'nullable|string|max:255',
                'app_type' => 'nullable',
            ]);

            if (($validatedData['app_type'] ?? null) === 'web') {
                $formattedStartTime = $validatedData['start_time'];
                $formattedEndTime = $validatedData['end_time'];
            } else {
                $formattedStartTime = Carbon::createFromFormat('m/d/Y H:i:s', $validatedData['start_time'])->format('Y-m-d H:i:s');
                $formattedEndTime = Carbon::createFromFormat('m/d/Y H:i:s', $validatedData['end_time'])->format('Y-m-d H:i:s');
            }

            $gig = Gig::where('id', $validatedData['gig_id'])->first();

            $gig_provider = $gig->user_id;
            // Create the booking
            $booking = BookingForm::create([
                'service_provider_id' => $gig_provider,
                'customer_id' => $user->id,
                'gig_id' => $validatedData['gig_id'],
                'gig_price' => $validatedData['gig_price'],
                'agreed_amount' => $validatedData['agreed_amount'],
                'start_time' => $formattedStartTime,
                'end_time' => $formattedEndTime,
            ]);
            $providerEmail = $gig->user->email;
            $providerName = $gig->user->name;
            $providerPhone = $gig->user->phone;
            $gigName = $gig->title;
            $gigSlug = $gig->slug;
            $message = $validatedData['message'] ?? 'Hello, I am interested in booking your service. Please let me know if this proposal works for you.';

            // Send notification to the provider
            Notification::route('mail', $providerEmail)
                ->notify(new NewBookingNotification($providerEmail, $providerName, $gigName, $gigSlug, $message));
            // create the record on firebase
            $this->recordOnFirestore($validatedData, $user, $booking, $gig);

            // Schedule SMS after 12 hours
            SendDelayedSms::dispatch($providerPhone, $message)->delay(now()->addHours(12));

            //send Firestore notification to user
            // Determine the receiver
            if ($user->id === $gig->provider->id) {
                // Authenticated user is the provider, send notification to the customer
                $receiver = $gig->user ?? '';
            } else {
                // Authenticated user is not the provider, send notification to the provider
                $receiver = $gig->provider ?? '';
            }
            info('receiver info ' . $receiver);
            // Ensure the receiver is set and send the notification
            if ($receiver) {
                $this->sendFcmNotification($receiver, $message);
            }

            return response()->json(['status' => 'success', 'message' => 'Booking engagement sent ', 'data' => $booking], 200);
        } catch (\Throwable $th) {
            Log::error($th->getMessage());
            return response()->json(['status' => 'error', 'message' => 'Booking engagement not sent', 'data' => $th->getMessage()], 401);
        }
    }

    public function bookingAction(Request $request)
    {
        try {
            $user = Auth::user();

            $validatedData = $request->validate([
                'gig_id' => 'required|exists:gigs,id',
                'message' => 'nullable|string|max:255',
                'action' => 'nullable|string|in:Accepted,declined',
                'booking_id' => 'required|exists:booking_forms,id',
            ]);

            // info($validatedData);
            $gig = Gig::where('id', $validatedData['gig_id'])->first();
            $booking = $gig->bookings->where('id', $validatedData['booking_id'])->first();
            $bookingAmount = $booking ? $booking->agreed_amount : null;

            $gigName = $gig->title;
            $gigSlug = $gig->slug;

            $trxRef = strtoupper('FIXGINI-' . Str::random(16));
            $message = $validatedData['message'] ?? 'You got a new notification.';

            // Send Firestore notification to user
            $receiver = $gig->provider ?? '';
            $this->sendFcmNotification($receiver, $message);

            if ($validatedData['action'] === 'Accepted') {
                $message = 'Your booking request has been accepted. Please proceed to payment to confirm the booking.';
                // Call Flutterwave to generate a payment link
                $paymentLink = $this->generatePaymentLink($trxRef, $bookingAmount, $validatedData['booking_id'], $booking->customer, $gig);

                $this->initiateBookingPayment($trxRef, $booking);

                // send to firebase for notification
                $this->updateFirestore($paymentLink, $trxRef, $validatedData, $user, $booking, $gig);

                // Send the payment link via email to the user
                Mail::to($booking->customer->email)->send(new PaymentLinkMail($paymentLink, $booking->customer->name));
            } elseif ($validatedData['action'] === 'declined') {
                info('incoming decline');
                $message = $validatedData['message'] ?? 'Hello, This enagement is rejected.';
                $this->cancelBooking($trxRef, $message, $validatedData['booking_id']);
                $this->updateFirestoreRejected($validatedData, $user, $booking, $gig, $validatedData['booking_id']);
                Mail::to($booking->customer->email)->send(new BookingAction($booking, $gigName, $gigSlug, $message));

                // Log the user activity
                $device = '';
                $activityLogger = app(ActivityLogger::class);
                $activityLogger->log('Provider rejected engagement from customer', $user->id, $user->role, $device);
            }
            return response()->json(['status' => 'success', 'message' => 'Booking engagement sent', 'data' => $trxRef], 200);
        } catch (\Throwable $th) {
            info($th->getMessage());
            return response()->json(['status' => 'error', 'message' => 'Response not successfully', 'data' => $th->getMessage()], 401);
        }
    }

    private function initiateBookingPayment($trxRef, $booking)
    {
        BookingPayment::create([
            'tx_ref' => $trxRef,
            'booking_id' => $booking->id,
            'customer_id' => $booking->customer_id,
            'amount' => $booking->agreed_amount,
            'payment_status' => 'pending',
            'cancel_reason' => 'no',
        ]);
        Transaction::create([
            'tx_ref' => $trxRef,
            'booking_id' => $booking->id,
            'user_id' => $booking->customer_id,
            'type' => 'booking',
            'amount' => $booking->agreed_amount,
            'description' => "Booking payment for {$booking->gig->title} is pending",
            'status' => 'pending',
        ]);
    }

    private function cancelBooking($trxRef, $message, $bookingId)
    {
        // Find the existing booking payment by tx_ref
        $bookingPayment = BookingPayment::where('tx_ref', $trxRef)->first();
        if ($bookingPayment) {
            // Update the existing booking payment
            $bookingPayment->update([
                'payment_status' => 'cancelled',
                'cancel_reason' => $message ?? '',
            ]);
        }
        // Find the existing booking form by id
        $booking = BookingForm::where('id', $bookingId)->first();
        if ($booking) {
            // Update the existing booking payment
            $booking->update([
                'status' => 'cancelled',
            ]);
        }
    }

    private function generatePaymentLink($trxRef, $amount, $bookId, $user, $gig)
    {
        $currency = ($gig->currency == '₦') ? 'NGN' : $gig->currency;

        // Create the HTTP client
        $client = new Client();

        //FLWSECK-4414d62ee9f096de8a542b988d954b7c-198be0428d9vt-X

        //FLWSECK_TEST-6cf1359026621655dea637381728ef05-X

        try {
            // Make the POST request
            $response = $client->post('https://api.flutterwave.com/v3/payments', [
                'headers' => [
                    'Authorization' => 'Bearer FLWSECK-4414d62ee9f096de8a542b988d954b7c-198be0428d9vt-X',
                    'Content-Type' => 'application/json',
                ],
                'json' => [
                    'amount' => $amount,
                    'currency' => $currency,
                    'tx_ref' => strtoupper($trxRef),
                    'order_id' => $bookId,
                    'redirect_url' => 'https://fixgini.com/account/payment/history',
                    'customer' => [
                        'email' => $user->email,
                        'name' => $user->name,
                        'phone_number' => $user->phone,
                    ],
                    'meta' => [
                        'fullname' => "{$user->name} {$user->lastname}",
                        'customer_id' => $user->id,
                        'booking_id' => $bookId,
                        'service_paid_for' => "https://fixgini.com/service/{$gig->slug}",
                        'service_price' => "{$currency}{$gig->price}",
                    ]
                ]
            ]);

            // Get the response body as a string
            $responseBody = $response->getBody()->getContents();

            // Decode the JSON response into an array
            $responseData = json_decode($responseBody, true);

            // Check if the response is successful
            if ($responseData['status'] === 'success') {
                return $responseData['data']['link'];  // Return the payment link
            }

            // If not successful, throw an exception
            throw new \Exception('Error generating payment link: ' . $responseData['message']);
        } catch (\Exception $e) {
            // Log the error message
            info('Error in generating payment link', ['error' => $e->getMessage()]);
            throw $e;  // Rethrow the exception
        }
    }

    private function recordOnFirestore($validatedData, $user, $booking, $gig)
    {
        try {
            // Firebase Firestore URL (without chatId, Firestore will auto-generate it)
            $firestoreUrl = 'https://firestore.googleapis.com/v1/projects/fixgini/databases/(default)/documents/chats';

            $currentTime = Carbon::now()->format('Y-m-d\TH:i:s.u\Z');

            // Prepare the initial chat data for creation
            $chatData = [
                'fields' => [
                    'createdAt' => [
                        'stringValue' => $currentTime,
                    ],
                    'lastMessage' => [
                        'stringValue' => $validatedData['message'] ?? 'Hey there, are you available for this engagement?',
                    ],
                    'lastMessageAt' => [
                        'stringValue' => $currentTime,
                    ],
                    'lastSenderId' => [
                        'stringValue' => (string) $user->id,
                    ],
                    'chatRoomStatus' => [
                        'stringValue' => 'active',
                    ],
                    'participants' => [
                        'arrayValue' => [
                            'values' => [
                                [
                                    'mapValue' => [
                                        'fields' => [
                                            'firstName' => [
                                                'stringValue' => $user->name,
                                            ],
                                            'userPhoto' => [
                                                'stringValue' => $user->profile_photo_url,
                                            ],
                                            'userUID' => [
                                                'stringValue' => (string) $user->id,  // Ensure it's a string
                                            ],
                                        ],
                                    ],
                                ],
                                [
                                    'mapValue' => [
                                        'fields' => [
                                            'firstName' => [
                                                'stringValue' => $gig->user->name,
                                            ],
                                            'userPhoto' => [
                                                'stringValue' => $gig->user->profile_photo_url,
                                            ],
                                            'userUID' => [
                                                'stringValue' => (string) $booking->service_provider_id,
                                            ],
                                        ],
                                    ],
                                ],
                            ],
                        ],
                    ],
                    'participantsUIDs' => [
                        'arrayValue' => [
                            'values' => [
                                [
                                    'stringValue' => (string) $user->id,  // Ensure it's a string
                                ],
                                [
                                    'stringValue' => (string) $gig->user->id,
                                ],
                            ],
                        ],
                    ],
                ],
            ];

            // Send the data to Firestore using POST to create a new document with an auto-generated ID
            $client = new \GuzzleHttp\Client();
            $response = $client->post($firestoreUrl, [
                'json' => $chatData,
            ]);

            // Check if the response was successful
            if ($response->getStatusCode() === 200) {
                // Decode the response to get the document ID (chatId)
                $responseBody = json_decode($response->getBody(), true);
                $chatId = $responseBody['name'];  // This is the document ID
                $chatId = substr($chatId, strrpos($chatId, '/') + 1);
                info("Chat created with ID: {$chatId}");

                // Prepare the update data with chatId added to the fields (Optional, might not need the same data again)
                $updateData = [
                    'fields' => [
                        'chatId' => [
                            'stringValue' => $chatId,  // Adding the chatId to the payload
                        ],
                        'lastMessage' => [
                            'stringValue' => $validatedData['message'] ?? 'Hey there, are you available for this engagement?',
                        ],
                        'lastMessageAt' => [
                            'stringValue' => $currentTime,
                        ],
                        'lastSenderId' => [
                            'stringValue' => (string) $user->id,
                        ],
                        'chatRoomStatus' => [
                            'stringValue' => 'active',
                        ],
                        'participants' => [
                            'arrayValue' => [
                                'values' => [
                                    [
                                        'mapValue' => [
                                            'fields' => [
                                                'firstName' => [
                                                    'stringValue' => $user->name ?? '',
                                                ],
                                                'userPhoto' => [
                                                    'stringValue' => $user->profile_photo_url,
                                                ],
                                                'userUID' => [
                                                    'stringValue' => (string) $user->id,
                                                ],
                                            ],
                                        ],
                                    ],
                                    [
                                        'mapValue' => [
                                            'fields' => [
                                                'firstName' => [
                                                    'stringValue' => $gig->user->name ?? '',
                                                ],
                                                'userPhoto' => [
                                                    'stringValue' => $gig->user->profile_photo_url,
                                                ],
                                                'userUID' => [
                                                    'stringValue' => (string) $gig->user->id,
                                                ],
                                            ],
                                        ],
                                    ],
                                ],
                            ],
                        ],
                        'participantsUIDs' => [
                            'arrayValue' => [
                                'values' => [
                                    [
                                        'stringValue' => (string) $user->id,
                                    ],
                                    [
                                        'stringValue' => (string) $gig->user->id,
                                    ],
                                ],
                            ],
                        ],
                    ],
                ];

                // Send the data to Firestore using PATCH to update the existing document with chatId
                $firestoreUpdateUrl = 'https://firestore.googleapis.com/v1/projects/fixgini/databases/(default)/documents/chats/' . $chatId;
                $updateResponse = $client->patch($firestoreUpdateUrl, [
                    'json' => $updateData,
                ]);

                if ($updateResponse->getStatusCode() === 200) {

                    // Prepare the chat room message data for creation
                    $messageData = [
                        'fields' => [
                            'chatId' => [
                                'stringValue' => $chatId,  // The actual chat ID
                            ],
                            'message' => [
                                'stringValue' => $validatedData['message'] ?? 'Hello, I am interested in booking your service. Please let me know if this proposal works for you.',  // Your message
                            ],

                            'sentBy' => [
                                'stringValue' => (string) $user->id,  // The ID of the user who sent the message
                            ],
                            'time' => [
                                'stringValue' => $currentTime,  // Timestamp when the message was sent
                            ],
                            'chatReceipt' => [
                                'nullValue' => null,  // If not yet received
                            ],
                            'paymentLink' => [
                                'nullValue' => null,  // If not yet received
                            ],
                            'participants' => [
                                'arrayValue' => [
                                    'values' => [
                                        [
                                            'stringValue' => (string) $user->id,  // User's ID
                                        ],
                                        [
                                            'stringValue' => (string) $gig->user->id,  // Provider's ID
                                        ],
                                    ],
                                ],
                            ],
                            'chatHire' => [
                                'mapValue' => [
                                    'fields' => [
                                        'price' => [
                                            'doubleValue' => (string) $booking->agreed_amount,  // Price for the gig
                                        ],
                                        'gigId' => [
                                            'stringValue' => (string) $validatedData['gig_id'],  // Gig ID
                                        ],
                                        'gigName' => [
                                            'stringValue' => (string) $booking->gig->title,  // Gig title
                                        ],
                                        'gigCurrency' => [
                                            'stringValue' => (string) $booking->gig->currency,  // Gig currency
                                        ],
                                        'gigName' => [
                                            'stringValue' => (string) $booking->gig->title,  // Gig title
                                        ],
                                        'gigCurrency' => [
                                            'stringValue' => (string) $booking->gig->currency,  // Gig currency
                                        ],
                                        'time' => [
                                            'stringValue' => $currentTime,  // Current time
                                        ],
                                        'bookingId' => [
                                            'stringValue' => (string) $booking->id,  // Booking ID
                                        ],
                                        'start' => [
                                            'stringValue' => $booking->start_time,  // Start time
                                        ],
                                        'end' => [
                                            'stringValue' => $booking->end_time,  // End time
                                        ],
                                        'sentBy' => [
                                            'stringValue' => (string) $user->id,  // User's ID
                                        ],
                                    ],
                                ],
                            ],
                        ],
                    ];

                    // Firestore URL to create a new message in the chat room
                    $firestoreMessageUrl = "https://firestore.googleapis.com/v1/projects/fixgini/databases/(default)/documents/chats/{$chatId}/chat_room";

                    // Send the message data to Firestore using POST to create a new message
                    $client = new \GuzzleHttp\Client();
                    $messageResponse = $client->post($firestoreMessageUrl, [
                        'json' => $messageData,
                    ]);

                    // Check if the message was successfully added to Firestore
                    if ($messageResponse->getStatusCode() === 200) {
                        info('Chat message created successfully in chat_room.');
                        $responseBody = json_decode($messageResponse->getBody(), true);
                        $chatRoomId = $responseBody['name'];  // This is the document ID
                        $chatRoomId = substr($chatRoomId, strrpos($chatRoomId, '/') + 1);

                        $updatedMessageData = [
                            'fields' => [
                                'chatId' => [
                                    'stringValue' => $chatId,  // Adding the chatId to the payload
                                ],
                                'messageId' => [
                                    'stringValue' => $chatRoomId,
                                ],
                                'message' => [
                                    'stringValue' => $validatedData['message'] ?? 'Hey there, are you available for this engagement?',
                                ],

                                'sentBy' => [
                                    'stringValue' => (string) $user->id,  // The ID of the user who sent the message
                                ],
                                'time' => [
                                    'stringValue' => $currentTime,  // Timestamp when the message was sent
                                ],
                                'chatReceipt' => [
                                    'nullValue' => null,  // If not yet received
                                ],
                                'paymentLink' => [
                                    'nullValue' => null,  // If not yet received
                                ],
                                'participants' => [
                                    'arrayValue' => [
                                        'values' => [
                                            [
                                                'stringValue' => (string) $user->id,  // User's ID
                                            ],
                                            [
                                                'stringValue' => (string) $gig->user->id,  // Provider's ID
                                            ],
                                        ],
                                    ],
                                ],
                                'chatHire' => [
                                    'mapValue' => [
                                        'fields' => [
                                            'accepted' => [
                                                'booleanValue' => false, // Use booleanValue for boolean
                                            ],
                                            'paid' => [
                                                'booleanValue' => false,
                                            ],
                                            'price' => [
                                                'doubleValue' => (string) $booking->agreed_amount,  // Price for the gig
                                            ],
                                            'gigId' => [
                                                'stringValue' => (string) $validatedData['gig_id'],  // Gig ID
                                            ],
                                            'gigName' => [
                                                'stringValue' => (string) $booking->gig->title,  // Gig title
                                            ],
                                            'gigCurrency' => [
                                                'stringValue' => (string) $booking->gig->currency,  // Gig currency
                                            ],
                                            'bookingId' => [
                                                'stringValue' => (string) $booking->id,  // Booking ID
                                            ],
                                            'time' => [
                                                'stringValue' => $currentTime,
                                            ],
                                            'start' => [
                                                'stringValue' => Carbon::parse($booking->start_time)->format('Y-m-d\TH:i:s.u\Z'),
                                            ],
                                            'end' => [
                                                'stringValue' => Carbon::parse($booking->end_time)->format('Y-m-d\TH:i:s.u\Z'),
                                            ],
                                            'sentBy' => [
                                                'stringValue' => (string) $user->id,  // User's ID
                                            ],
                                        ],
                                    ],
                                ],
                            ],
                        ];
                        // Firestore URL to create a new message in the chat room
                        $updateFirestoreMessageUrl = "https://firestore.googleapis.com/v1/projects/fixgini/databases/(default)/documents/chats/{$chatId}/chat_room/{$chatRoomId}";
                        // Send the message data to Firestore using PATCH to update the message
                        $client = new \GuzzleHttp\Client();
                        $messageResponse = $client->patch($updateFirestoreMessageUrl, [
                            'json' => $updatedMessageData,
                        ]);

                        // update the booking form table
                        BookingForm::where('id', $booking->id)->update(['chat_id' => $chatId, 'chat_room_id' => $chatRoomId]);

                        return response()->json([
                            'status' => 'success',
                            'message' => 'Chat room and message recorded successfully.',
                        ], 200);
                    } else {
                        throw new \Exception('Failed to create message in chat_room');
                    }
                }
            } else {
                throw new \Exception('Failed to record chat in Firebase');
            }
        } catch (\Throwable $th) {
            Log::error("Failed to record chat in Firebase: {$th->getMessage()}");
            return response()->json(['status' => 'error', 'message' => 'Failed to record chat in Firebase.'], 500);
        }
    }

    private function updateFirestore($paymentLink, $trxRef, $validatedData, $user, $booking, $gig)
    {
        try {
            // Retrieve the chatRoomId and chatId from the session
            $chatRoomId = $booking->chat_room_id;
            $chatId = $booking->chat_id;
            $currentTime = Carbon::now()->format('Y-m-d\TH:i:s.u\Z');
            
            // Prepare the update data with chatId added to the fields (Optional, might not need the same data again)
            $updateChatData = [
                'fields' => [
                    'chatId' => [
                        'stringValue' => $chatId,  // Adding the chatId to the payload
                    ],
                    'lastMessage' => [
                        'stringValue' => $validatedData['message'] ?? 'Hey there, are you available for this engagement?',
                    ],
                    'lastMessageAt' => [
                        'stringValue' => $currentTime,
                    ],
                    'lastSenderId' => [
                        'stringValue' => (string) $user->id,
                    ],
                    'chatRoomStatus' => [
                        'stringValue' => 'active',
                    ],
                    'participants' => [
                        'arrayValue' => [
                            'values' => [
                                [
                                    'mapValue' => [
                                        'fields' => [
                                            'firstName' => [
                                                'stringValue' => $booking->customer->name ?? '',
                                            ],
                                            'userPhoto' => [
                                                'stringValue' => $booking->customer->profile_photo_url,
                                            ],
                                            'userUID' => [
                                                'stringValue' => (string) $booking->customer_id,
                                            ],
                                        ],
                                    ],
                                ],
                                [
                                    'mapValue' => [
                                        'fields' => [
                                            'firstName' => [
                                                'stringValue' => $gig->provider->name ?? '',
                                            ],
                                            'userPhoto' => [
                                                'stringValue' => $gig->provider->profile_photo_url,
                                            ],
                                            'userUID' => [
                                                'stringValue' => (string) $booking->service_provider_id,
                                            ],
                                        ],
                                    ],
                                ],
                            ],
                        ],
                    ],
                    'participantsUIDs' => [
                        'arrayValue' => [
                            'values' => [
                                [
                                    'stringValue' => (string) $booking->customer_id,
                                ],
                                [
                                    'stringValue' => (string) $booking->service_provider_id,
                                ],
                            ],
                        ],
                    ],
                ],
            ];

            // Send the data to Firestore using PATCH to update the existing document with chatId
            $client = new \GuzzleHttp\Client();
            $updateChatId = 'https://firestore.googleapis.com/v1/projects/fixgini/databases/(default)/documents/chats/' . $chatId;
            $client->patch($updateChatId, [
                'json' => $updateChatData,
            ]);


            $updateChatRoomData = [
                'fields' => [
                    'chatId' => [
                        'stringValue' => $chatId,  // The actual chat ID
                    ],
                    'message' => [
                        'stringValue' => $validatedData['message'],  // Your message
                    ],
                    'messageId' => [
                        'stringValue' => $chatRoomId,
                    ],
                    'sentBy' => [
                        'stringValue' => (string) $user->id,  // The ID of the user who sent the message
                    ],
                    'time' => [
                        'stringValue' => $currentTime,
                    ],
                    'chatReceipt' => [
                        'nullValue' => null,  // If not yet received
                    ],
                    'paymentLink' => [
                        'stringValue' => $paymentLink,
                    ],

                    'participants' => [
                        'arrayValue' => [
                            'values' => [
                                [
                                    'stringValue' => (string) $booking->customer_id,  // User's ID
                                ],
                                [
                                    'stringValue' => (string) $booking->service_provider_id,  // Provider's ID
                                ],
                            ],
                        ],
                    ],


                    'chatHire' => [
                        'mapValue' => [
                            'fields' => [
                                'acceptTime' => [
                                    'stringValue' => $currentTime
                                ],
                                'paid' => [
                                    'booleanValue' => false,
                                ],
                                'paidTime' => [
                                    'nullValue' => null,
                                ],
                                'trxRef' => [
                                    'stringValue' => $trxRef,
                                ],
                                'accepted' => [
                                    'booleanValue' => true, // Use booleanValue for boolean
                                ],
                                'completed' => [
                                    'booleanValue' => false, // Use booleanValue for boolean
                                ],
                                'completedTime' => [
                                    'nullValue' => null, // Use nullValue instead of an empty string
                                ],
                                'confirmCompleted' => [
                                    'booleanValue' => false, // Use booleanValue for boolean
                                ],
                                'reasonForConfirmDecline' => [
                                    'nullValue' => null, // Use nullValue for empty fields
                                ],
                                'reasonForDecline' => [
                                    'nullValue' => null, // Use nullValue for empty fields
                                ],
                                'rejected' => [
                                    'booleanValue' => false, // Use booleanValue for boolean
                                ],
                                'bookingId' => [
                                    'stringValue' => (string) $booking->id, // Keep as stringValue if it's not numeric
                                ],
                                'price' => [
                                    'doubleValue' => (float) $booking->agreed_amount, // Use doubleValue for decimal values
                                ],
                                'gigId' => [
                                    'stringValue' => (string) $validatedData['gig_id'], // Keep as stringValue
                                ],
                                'gigName' => [
                                    'stringValue' => (string) $booking->gig->title,  // Gig title
                                ],
                                'gigCurrency' => [
                                    'stringValue' => (string) $booking->gig->currency,  // Gig currency
                                ],
                                'time' => [
                                    'stringValue' => $currentTime,
                                ],
                                'start' => [
                                    'stringValue' => Carbon::parse($booking->start_time)->format('Y-m-d\TH:i:s.u\Z'), // Use stringValue
                                ],
                                'end' => [
                                    'stringValue' => Carbon::parse($booking->end_time)->format('Y-m-d\TH:i:s.u\Z'), // Use stringValue
                                ],
                                'sentBy' => [
                                    'stringValue' => (string) $user->id, // Keep as stringValue
                                ],
                            ],
                        ],
                    ],

                ],
            ];

            // Firestore URL to create a new message in the chat room
            $updatedChatRoomID = "https://firestore.googleapis.com/v1/projects/fixgini/databases/(default)/documents/chats/{$chatId}/chat_room/{$chatRoomId}";
            // Send the message data to Firestore using PATCH to update the message
            $client = new \GuzzleHttp\Client();
            $client->patch($updatedChatRoomID, [
                'json' => $updateChatRoomData,
            ]);
            // update the booking form table
            info('Chat room message updated successfully with MessageId in chat_room.');

            return response()->json([
                'status' => 'success',
                'message' => 'Chat room message id recorded successfully.',
            ], 200);
        } catch (\Throwable $th) {
            Log::error("Failed to record chat room message in Firestore: {$th->getMessage()}");
            return response()->json(['status' => 'error', 'message' => 'Failed to record chat room in Firebase.'], 500);
        }
    }

    private function updateFirestoreRejected($validatedData, $user, $booking)
    {
        try {
            $chatId = $booking->chat_id;
            $chatRoomId = $booking->chat_room_id;
            $currentTime = Carbon::now()->format('Y-m-d\TH:i:s.u\Z');

            $updateData = [
                'fields' => [
                    'chatId' => [
                        'stringValue' => $chatId,  // Adding the chatId to the payload
                    ],
                    'lastMessage' => [
                        'stringValue' => $validatedData['message'] ?? 'Hey there, are you available for this engagement?',
                    ],
                    'lastMessageAt' => [
                        'stringValue' => $currentTime,
                    ],
                    'lastSenderId' => [
                        'stringValue' => (string) $user->id,
                    ],
                    'chatRoomStatus' => [
                        'stringValue' => 'active',
                    ],
                    'participants' => [
                        'arrayValue' => [
                            'values' => [
                                [
                                    'mapValue' => [
                                        'fields' => [
                                            'firstName' => [
                                                'stringValue' => $booking->customer->name ?? '',
                                            ],
                                            'userPhoto' => [
                                                'stringValue' => $booking->customer->profile_photo_url,
                                            ],
                                            'userUID' => [
                                                'stringValue' => (string) $booking->customer_id,
                                            ],
                                        ],
                                    ],
                                ],
                                [
                                    'mapValue' => [
                                        'fields' => [
                                            'firstName' => [
                                                'stringValue' => $booking->gig->user->name ?? '',
                                            ],
                                            'userPhoto' => [
                                                'stringValue' => $booking->gig->user->profile_photo_url,
                                            ],
                                            'userUID' => [
                                                'stringValue' => (string) $booking->service_provider_id,
                                            ],
                                        ],
                                    ],
                                ],
                            ],
                        ],
                    ],
                    'participantsUIDs' => [
                        'arrayValue' => [
                            'values' => [
                                [
                                    'stringValue' => (string) $booking->customer_id,
                                ],
                                [
                                    'stringValue' => (string) $booking->service_provider_id,
                                ],
                            ],
                        ],
                    ],
                ],
            ];

            // Send the data to Firestore using PATCH to update the existing document with chatId
            $client = new \GuzzleHttp\Client();
            $firestoreUpdateUrl = 'https://firestore.googleapis.com/v1/projects/fixgini/databases/(default)/documents/chats/' . $chatId;
            $client->patch($firestoreUpdateUrl, [
                'json' => $updateData,
            ]);


            $updateChatRoomData = [
                'fields' => [
                    'chatId' => [
                        'stringValue' => $chatId,  // The actual chat ID
                    ],
                    'message' => [
                        'stringValue' => $validatedData['message'],  // Your message
                    ],
                    'messageId' => [
                        'stringValue' => $chatRoomId,
                    ],
                    'sentBy' => [
                        'stringValue' => (string) $user->id,  // The ID of the user who sent the message
                    ],
                    'time' => [
                        'stringValue' => $currentTime,
                    ],
                    'chatReceipt' => [
                        'nullValue' => null, // Use nullValue instead of an empty string
                    ],
                    'paymentLink' => [
                        'nullValue' => null, // Use nullValue instead of an empty string
                    ],

                    'participants' => [
                        'arrayValue' => [
                            'values' => [
                                [
                                    'stringValue' => (string) $booking->customer_id,  // User's ID
                                ],
                                [
                                    'stringValue' => (string) $booking->service_provider_id,  // Provider's ID
                                ],
                            ],
                        ],
                    ],


                    'chatHire' => [
                        'mapValue' => [
                            'fields' => [
                                'acceptTime' => [
                                    'stringValue' => $currentTime
                                ],
                                'accepted' => [
                                    'booleanValue' => false, // Use booleanValue for boolean
                                ],
                                'rejected' => [
                                    'booleanValue' => true, // Use booleanValue for boolean
                                ],
                                'completed' => [
                                    'booleanValue' => false, // Use booleanValue for boolean
                                ],
                                'completedTime' => [
                                    'nullValue' => null, // Use nullValue instead of an empty string
                                ],
                                'confirmCompleted' => [
                                    'booleanValue' => false, // Use booleanValue for boolean
                                ],
                                'reasonForConfirmDecline' => [
                                    'nullValue' => null, // Use nullValue for empty fields
                                ],
                                'reasonForDecline' => [
                                    'nullValue' => null, // Use nullValue for empty fields
                                ],
                                'rejected' => [
                                    'booleanValue' => true, // Use booleanValue for boolean
                                ],
                                'bookingId' => [
                                    'stringValue' => (string) $booking->id, // Keep as stringValue if it's not numeric
                                ],
                                'price' => [
                                    'doubleValue' => (float) $booking->agreed_amount, // Use doubleValue for decimal values
                                ],
                                'gigId' => [
                                    'stringValue' => (string) $validatedData['gig_id'], // Keep as stringValue
                                ],
                                'gigName' => [
                                    'stringValue' => (string) $booking->gig->title,  // Gig title
                                ],
                                'gigCurrency' => [
                                    'stringValue' => (string) $booking->gig->currency,  // Gig currency
                                ],
                                'time' => [
                                    'stringValue' => $currentTime,
                                ],
                                'start' => [
                                    'stringValue' => Carbon::parse($booking->start_time)->format('Y-m-d\TH:i:s.u\Z'), // Use stringValue
                                ],
                                'end' => [
                                    'stringValue' => Carbon::parse($booking->end_time)->format('Y-m-d\TH:i:s.u\Z'), // Use stringValue
                                ],
                                'sentBy' => [
                                    'stringValue' => (string) $user->id, // Keep as stringValue
                                ],
                            ],
                        ],
                    ],

                ],
            ];

            // Firestore URL to create a new message in the chat room
            $updatedChatRoomID = "https://firestore.googleapis.com/v1/projects/fixgini/databases/(default)/documents/chats/{$chatId}/chat_room/{$chatRoomId}";
            // Send the message data to Firestore using PATCH to update the message
            $client = new \GuzzleHttp\Client();
            $client->patch($updatedChatRoomID, [
                'json' => $updateChatRoomData,
            ]);

            // update the booking form table
            // BookingForm::where('id', $booking->id)->update(['chat_id' => $chatId, 'chat_room_id' => $chatRoomId]);
            info('Chat room message updated successfully with MessageId in chat_room.');

            info('Engagement rejected in chat_room.');
            return response()->json([
                'status' => 'success',
                'message' => 'Chat room and message recorded successfully.',
            ], 200);
        } catch (\Throwable $th) {
            Log::error("Failed to record chat in Firebase: {$th->getMessage()}");
            return response()->json(['status' => 'error', 'message' => 'Failed to record chat in Firebase.'], 500);
        }
    }

    private function sendFcmNotification($receiver, $message)
    {
        try {
            // Prepare the FCM notification payload
            $fcm_token = $receiver->fcm_token;
            if (empty($receiver->fcm_token)) {
                return response()->json(['message' => 'No FCM token available for this user'], 400);
            }

            // Path to Firebase service account credentials
            $credentialsFilePath = public_path("fixgini-168886924712.json");
            $projectId = 'fixgini';

            // Retrieve access token for FCM using Google Client
            $client = new GoogleClient();
            $client->setAuthConfig($credentialsFilePath);
            $client->useApplicationDefaultCredentials();
            $client->addScope('https://www.googleapis.com/auth/firebase.messaging');
            $client->fetchAccessTokenWithAssertion();
            $token = $client->getAccessToken();
            $accessToken = $token['access_token'];

            // Set up headers for FCM API
            $headers = [
                "Authorization: Bearer $accessToken",
                'Content-Type: application/json',
            ];

            $data = [
                "title" => "Dear {$receiver->name}",
                "message" => $message,
                "type" => "single_chat",
            ];

            $notification = [
                "title" => "Dear {$receiver->name}",
                "body" => $message,
            ];


            $webpush = [
                "fcm_options" => [
                    "link" => "https://fixgini.com/chat"
                ],
            ];


            // FCM API payload for the single user
            $data = [
                "message" => [
                    "token" => $fcm_token,
                    "data" => $data,
                    "notification" => $notification,
                    "webpush" => $webpush,
                ],

            ];
            $payload = json_encode($data);

            // Send the notification via cURL
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, "https://fcm.googleapis.com/v1/projects/{$projectId}/messages:send");
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
            $response = curl_exec($ch);
            $err = curl_error($ch);
            curl_close($ch);

            // Check for errors
            if ($err) {
                Log::error('Curl Error: ', ['error' => $err]); // Use array structure for logging
                return response()->json([
                    'message' => 'Curl Error: ' . $err,
                ], 500);
            } else {
                // Decode response for logging
                $decodedResponse = json_decode($response, true);
                Log::info('Notification sent successfully with response : ', $decodedResponse); // Log array response properly

                return response()->json([
                    'message' => 'Notification sent successfully',
                    'response' => $decodedResponse, // Return decoded response as JSON
                ], 200);
            }
        } catch (\Throwable $th) {
            Log::error($th->getMessage());
            // Catch and handle errors
            return response()->json([
                'message' => $th->getMessage(),
            ], 500);
        }
    }

    public function chatMessage(Request $request)
    {
        try {
            $user = Auth::user();

            $validatedData = $request->validate([
                'booking_id' => 'required|exists:booking_forms,id',
                'message' => 'required|string',
            ]);
            $booking = BookingForm::where('id', $validatedData['booking_id'])->first();

            // Retrieve the chatRoomId and chatId from the session
            $chatRoomId = $booking->chat_room_id;
            $chatId = $booking->chat_id;
            $currentTime = Carbon::now()->format('Y-m-d\TH:i:s.u\Z');

            // Prepare the update data with chatId added to the fields (Optional, might not need the same data again)
            $updateExistingChatData = [
                'fields' => [
                    'chatId' => [
                        'stringValue' => $chatId,  // Adding the chatId to the payload
                    ],
                    'lastMessage' => [
                        'stringValue' => $validatedData['message'] ?? 'Hey there, are you available for this engagement?',
                    ],
                    'lastMessageAt' => [
                        'stringValue' => $currentTime,
                    ],
                    'lastSenderId' => [
                        'stringValue' => (string) $user->id,
                    ],
                    'chatRoomStatus' => [
                        'stringValue' => 'active',
                    ],
                    'participants' => [
                        'arrayValue' => [
                            'values' => [
                                [
                                    'mapValue' => [
                                        'fields' => [
                                            'firstName' => [
                                                'stringValue' => $booking->customer->name ?? '',
                                            ],
                                            'userPhoto' => [
                                                'stringValue' => $booking->customer->profile_photo_url,
                                            ],
                                            'userUID' => [
                                                'stringValue' => (string) $booking->customer_id,
                                            ],
                                        ],
                                    ],
                                ],
                                [
                                    'mapValue' => [
                                        'fields' => [
                                            'firstName' => [
                                                'stringValue' => $booking->gig->user->name ?? '',
                                            ],
                                            'userPhoto' => [
                                                'stringValue' => $booking->gig->user->profile_photo_url,
                                            ],
                                            'userUID' => [
                                                'stringValue' => (string) $booking->service_provider_id,
                                            ],
                                        ],
                                    ],
                                ],
                            ],
                        ],
                    ],
                    'participantsUIDs' => [
                        'arrayValue' => [
                            'values' => [
                                [
                                    'stringValue' => (string) $booking->customer_id,
                                ],
                                [
                                    'stringValue' => (string) $booking->service_provider_id,
                                ],
                            ],
                        ],
                    ],
                ],
            ];


            // Send the data to Firestore using PATCH to update the existing document with chatId
            $client = new \GuzzleHttp\Client();
            $updateExistingChatId = 'https://firestore.googleapis.com/v1/projects/fixgini/databases/(default)/documents/chats/' . $chatId;
            $client->patch($updateExistingChatId, [
                'json' => $updateExistingChatData,
            ]);


            $createChatRoom = [
                'fields' => [
                    'chatId' => [
                        'stringValue' => $chatId,  // The actual chat ID
                    ],
                    'message' => [
                        'stringValue' => $validatedData['message'],  // Your message
                    ],
                    'messageId' => [
                        'stringValue' => $chatRoomId,
                    ],
                    'sentBy' => [
                        'stringValue' => (string) $user->id,  // The ID of the user who sent the message
                    ],
                    'time' => [
                        'stringValue' => $currentTime,
                    ],
                    'chatReceipt' => [
                        'nullValue' => null,  // If not yet received
                    ],
                    'paymentLink' => [
                        'nullValue' => null,  // If not yet received
                    ],

                    'participants' => [
                        'arrayValue' => [
                            'values' => [
                                [
                                    'stringValue' => (string) $booking->customer_id,  // User's ID
                                ],
                                [
                                    'stringValue' => (string) $booking->service_provider_id,  // Provider's ID
                                ],
                            ],
                        ],
                    ],

                    'chatHire' => [
                        'nullValue' => null,  // If not yet received
                    ],

                    'webHire' => [
                        'mapValue' => [
                            'fields' => [
                                'acceptTime' => [
                                    'stringValue' => $currentTime
                                ],
                                'paid' => [
                                    'booleanValue' => true,
                                ],
                                'paidTime' => [
                                    'stringValue' => $currentTime,
                                ],
                                'trxRef' => [
                                    'nullValue' => null, // Use nullValue instead of an empty string
                                ],
                                'accepted' => [
                                    'booleanValue' => true, // Use booleanValue for boolean
                                ],
                                'completed' => [
                                    'booleanValue' => false, // Use booleanValue for boolean
                                ],
                                'completedTime' => [
                                    'nullValue' => null, // Use nullValue instead of an empty string
                                ],
                                'confirmCompleted' => [
                                    'booleanValue' => false, // Use booleanValue for boolean
                                ],
                                'reasonForConfirmDecline' => [
                                    'nullValue' => null, // Use nullValue for empty fields
                                ],
                                'reasonForDecline' => [
                                    'nullValue' => null, // Use nullValue for empty fields
                                ],
                                'rejected' => [
                                    'booleanValue' => false, // Use booleanValue for boolean
                                ],
                                'bookingId' => [
                                    'stringValue' => (string) $booking->id, // Keep as stringValue if it's not numeric
                                ],
                                'price' => [
                                    'doubleValue' => (float) $booking->agreed_amount, // Use doubleValue for decimal values
                                ],
                                'gigId' => [
                                    'stringValue' => (string) $booking->gig_id, // Keep as stringValue
                                ],
                                'gigName' => [
                                    'stringValue' => (string) $booking->gig->title,  // Gig title
                                ],
                                'gigCurrency' => [
                                    'stringValue' => (string) $booking->gig->currency,  // Gig currency
                                ],
                                'time' => [
                                    'stringValue' => $currentTime,
                                ],
                                'start' => [
                                    'stringValue' => Carbon::parse($booking->start_time)->format('Y-m-d\TH:i:s.u\Z'), // Use stringValue
                                ],
                                'end' => [
                                    'stringValue' => Carbon::parse($booking->end_time)->format('Y-m-d\TH:i:s.u\Z'), // Use stringValue
                                ],
                                'sentBy' => [
                                    'stringValue' => (string) $user->id, // Keep as stringValue
                                ],
                            ],
                        ],
                    ],

                ],
            ];

            // Firestore URL to create a new message in the chat room
            $createChatRoomID = "https://firestore.googleapis.com/v1/projects/fixgini/databases/(default)/documents/chats/{$chatId}/chat_room/";
            // Send the message data to Firestore using PATCH to update the message
            $client = new \GuzzleHttp\Client();
            $client->post($createChatRoomID, [
                'json' => $createChatRoom,
            ]);
            // update the booking form table
            info('new chat created in chat_room.');
            $receiver = $booking->provider ?? '';
            $this->sendFcmNotification($receiver, $validatedData['message']);
            return response()->json([
                'status' => 'success',
                'message' => 'Chat room message recorded successfully.',
            ], 200);
        } catch (\Throwable $th) {
            Log::error("Failed to record chat room message in Firestore: {$th->getMessage()}");
            return response()->json(['status' => 'error', 'message' => 'Failed to record chat room in Firebase.'], 500);
        }
    }

    // Get all bookings for the logged-in customer
    public function customerBookings(Request $request)
    {
        try {
            $user = Auth::user();

            $customer_id = $user->id;
            $allBookings = BookingForm::with('gig')->where('customer_id', $customer_id)->latest()->limit(10)->get();
            if ($allBookings->isEmpty()) {
                return response()->json(['status' => 'error', 'message' => 'Engagement not found'], 404);
            } else {
                $pendingBookings = $allBookings->where('status', 'pending')->values();
                $ongoingBookings = $allBookings->where('status', 'ongoing')->values();
                $completedBookings = $allBookings->where('status', 'completed')->values();
                return response()->json([
                    'status' => 'success',
                    'message' => 'Engagement found',
                    'data' => [
                        'all' => $allBookings,
                        'pending' => $pendingBookings,
                        'ongoing' => $ongoingBookings,
                        'completed' => $completedBookings,
                    ],
                ], 200);
            }
        } catch (\Throwable $th) {
            return response()->json(['status' => 'error', 'message' => 'Engagement Booking not found', 'data' => $th->getMessage()], 401);
        }
    }

    // Get all gigs in booking that below to the service provider user id
    public function serviceProviderBookings(Request $request)
    {
        try {
            $user = Auth::user();
            $gig_ids = Gig::where('user_id', $user->id)->pluck('id');

            // Retrieve bookings based on statuses
            $allBookings = BookingForm::with('gig', 'customer')->whereIn('gig_id', $gig_ids)->latest()->limit(10)->get();
            if ($allBookings->isEmpty()) {
                return response()->json(['status' => 'error', 'message' => 'Engagement not found'], 404);
            } else {
                $pendingBookings = $allBookings->where('status', 'pending')->values();
                $ongoingBookings = $allBookings->where('status', 'ongoing')->values();
                $completedBookings = $allBookings->where('status', 'completed')->values();

                // Return grouped data
                return response()->json([
                    'status' => 'success',
                    'message' => 'Engagement found',
                    'data' => [
                        'all' => $allBookings,
                        'pending' => $pendingBookings,
                        'ongoing' => $ongoingBookings,
                        'completed' => $completedBookings,
                    ],
                ], 200);
            }
        } catch (\Throwable $th) {
            return response()->json(['status' => 'error', 'message' => 'Engagement Booking not found', 'data' => $th->getMessage()], 401);
        }
    }

    // Show a specific booking by ID
    public function show(Request $request)
    {
        try {
            $validatedData = $request->validate([
                'booking_id' => 'required|exists:booking_forms,id',
            ]);
            $id = $validatedData['booking_id'];
            $booking = BookingForm::findOrFail($id);

            return response()->json(['status' => 'success', 'data' => $booking], 200);
        } catch (\Throwable $th) {
            return response()->json(['status' => 'error', 'message' => 'Booking not found', 'data' => $th->getMessage()], 401);
        }
    }

    // Cancel a booking
    public function cancel(Request $request)
    {
        try {
            $validatedData = $request->validate([
                'booking_id' => 'required|exists:booking_forms,id',
            ]);
            $id = $validatedData['booking_id'];
            $booking = BookingForm::findOrFail($id);
            $booking->update(['status' => 'cancelled']);
            return response()->json(['status' => 'success', 'message' => 'Booking cancelled successfully'], 200);
        } catch (\Throwable $th) {
            return response()->json(['status' => 'error', 'message' => 'Booking not found', 'data' => $th->getMessage()], 401);
        }
    }


    // public function completeBooking(Request $request)
    // {
    //     try {
    //         $validatedData = $request->validate([
    //             'booking_id' => 'required|exists:booking_forms,id',
    //         ]);

    //         info('incoming confirm completion from customer');

    //         $id = $validatedData['booking_id'];
    //         $booking = BookingForm::findOrFail($id);

    //         // Update booking status
    //         $booking->update(['status' => 'completed']);

    //         // Get the amount paid
    //         $payment = BookingPayment::where('booking_id', $id)->firstOrFail();

    //         // Calculate amounts
    //         $toCredit = $payment->payment_status === 'completed' ? $payment->agreed_amount : 0;
    //         $toPending = $booking->status === 'pending' ? $booking->agreed_amount : 0;

    //         // Credit the service provider's wallet
    //         $provider_id = $booking->gig->user_id;

    //         $provider_wallet = Wallet::where('user_id', $provider_id)->first();
    //         info('before - provider_wallet ' . $provider_wallet);
    //         if ($provider_wallet) {
    //             // Update the wallet's balances
    //             $provider_wallet->update([
    //                 'available' => $provider_wallet->available + $toCredit,
    //                 'pending' => $provider_wallet->pending + $toPending,
    //             ]);
    //         }
    //         info('after - provider_wallet ' . $provider_wallet);

    //         // Update Firestore or any other related systems
    //         $this->updateCompleteFirestore($booking, $payment->tx_ref);

    //         return response()->json([
    //             'status' => 'success',
    //             'message' => 'Engagement completed',
    //         ], 200);
    //     } catch (\Throwable $th) {
    //         return response()->json([
    //             'status' => 'error',
    //             'message' => 'Engagement Booking not found',
    //             'data' => $th->getMessage(),
    //         ], 401);
    //     }
    // }

    public function completeBooking(Request $request)
    {
        try {
            $validatedData = $request->validate([
                'booking_id' => 'required|exists:booking_forms,id',
            ]);

            info('Incoming confirm completion from customer.');

            $bookingId = $validatedData['booking_id'];
            $booking = BookingForm::findOrFail($bookingId);

            // Update booking status
            $booking->update(['status' => 'completed']);

            // Get the completed booking
            $booking_id = BookingForm::where('id', $bookingId)->where('status', 'completed')->first();
            // Get the amount paid of the completed booking
            $payment = BookingPayment::where('booking_id', $booking_id->id)->where('payment_status', 'completed')->first();
            // Calculate amount to credit based on payment status
            $toCredit = $payment->amount;

            // Credit the service provider's wallet
            $provider_id = $booking->gig->user_id;
            $provider_wallet = Wallet::where('user_id', $provider_id)->first();

            if ($provider_wallet) {
                // Update only the `available` balance if payment is completed
                $provider_wallet->update([
                    'pending_withdraw' => $provider_wallet->pending_withdraw + $toCredit,
                ]);
            } else {
                // Log an error if the wallet is not found
                info("Wallet not found for provider with ID: $provider_id.");
                return response()->json([
                    'status' => 'error',
                    'message' => 'Service provider wallet not found.',
                ], 404);
            }

            info('Updated provider wallet: ' . json_encode($provider_wallet));

            // Update Firestore or any other external system
            $this->updateCompleteFirestore($booking, $payment->tx_ref);

            return response()->json([
                'status' => 'success',
                'message' => 'Engagement completed successfully.',
            ], 200);
        } catch (\Throwable $th) {
            // Catch and log exceptions
            info('Error completing booking: ' . $th->getMessage());
            return response()->json([
                'status' => 'error',
                'message' => 'An error occurred while completing the booking.',
                'data' => $th->getMessage(),
            ], 500);
        }
    }


    public function triggerCompleteBooking(Request $request)
    {
        try {
            $validatedData = $request->validate([
                'booking_id' => 'required|exists:booking_forms,id',
            ]);

            $id = $validatedData['booking_id'];
            $booking = BookingForm::findOrFail($id);
            if ($booking) {
                $booking->status = 'awaiting';
                $booking->save();
            }
            // mail the customer that the service provider is done with the project
            $email = $booking->customer->email;
            Mail::to($email)->send(new TriggerCompleteBooking($booking));
            // Dispatch job to complete booking after 12 hours if booking status is still ongoing
            if (($booking->status) === 'awaiting') {
                CompleteBookingJob::dispatch($id)->delay(now()->addHours(12));
            }

            $this->triggerCompleteFirestore($booking);

            return response()->json([
                'status' => 'success',
                'message' => 'Customer notified successfully',
            ], 200);
        } catch (\Throwable $th) {
            return response()->json([
                'status' => 'error',
                'message' => 'Booking not found',
                'data' => $th->getMessage(),
            ], 401);
        }
    }

    private function updateCompleteFirestore($booking, $tx_ref)
    {
        try {
            // Retrieve the chatRoomId and chatId from the session
            $chatRoomId = $booking->chat_room_id;
            $chatId = $booking->chat_id;
            $currentTime = Carbon::now()->format('Y-m-d\TH:i:s.u\Z');

            // Prepare the update data with chatId added to the fields (Optional, might not need the same data again)
            $updateChatData = [
                'fields' => [
                    'chatId' => [
                        'stringValue' => $chatId,  // Adding the chatId to the payload
                    ],
                    'lastMessage' => [
                        'stringValue' => 'Engagement completed successfully',
                    ],
                    'lastMessageAt' => [
                        'stringValue' => $currentTime,
                    ],
                    'lastSenderId' => [
                        'stringValue' => (string) $booking->customer_id,
                    ],
                    'chatRoomStatus' => [
                        'stringValue' => 'active',
                    ],
                    'participants' => [
                        'arrayValue' => [
                            'values' => [
                                [
                                    'mapValue' => [
                                        'fields' => [
                                            'firstName' => [
                                                'stringValue' => $booking->customer->name ?? '',
                                            ],
                                            'userPhoto' => [
                                                'stringValue' => $booking->customer->profile_photo_url,
                                            ],
                                            'userUID' => [
                                                'stringValue' => (string) $booking->customer_id,
                                            ],
                                        ],
                                    ],
                                ],
                                [
                                    'mapValue' => [
                                        'fields' => [
                                            'firstName' => [
                                                'stringValue' => $booking->gig->user->name ?? '',
                                            ],
                                            'userPhoto' => [
                                                'stringValue' => $booking->gig->user->profile_photo_url,
                                            ],
                                            'userUID' => [
                                                'stringValue' => (string) $booking->service_provider_id,
                                            ],
                                        ],
                                    ],
                                ],
                            ],
                        ],
                    ],
                    'participantsUIDs' => [
                        'arrayValue' => [
                            'values' => [
                                [
                                    'stringValue' => (string) $booking->customer_id,
                                ],
                                [
                                    'stringValue' => (string) $booking->service_provider_id,
                                ],
                            ],
                        ],
                    ],
                ],
            ];

            // Send the data to Firestore using PATCH to update the existing document with chatId
            $client = new \GuzzleHttp\Client();
            $updateChatId = 'https://firestore.googleapis.com/v1/projects/fixgini/databases/(default)/documents/chats/' . $chatId;
            $client->patch($updateChatId, [
                'json' => $updateChatData,
            ]);

            $updateChatRoomData = [
                'fields' => [
                    'chatId' => [
                        'stringValue' => $chatId,  // The actual chat ID
                    ],
                    'message' => [
                        'stringValue' => 'Engagement completed successfully',
                    ],
                    'messageId' => [
                        'stringValue' => $chatRoomId,
                    ],
                    'sentBy' => [
                        'stringValue' => (string) $booking->customer_id,  // The ID of the user who sent the message
                    ],
                    'time' => [
                        'stringValue' => $currentTime,
                    ],

                    'participants' => [
                        'arrayValue' => [
                            'values' => [
                                [
                                    'stringValue' => (string) $booking->customer_id,  // User's ID
                                ],
                                [
                                    'stringValue' => (string) $booking->service_provider_id,  // Provider's ID
                                ],
                            ],
                        ],
                    ],


                    'chatHire' => [
                        'mapValue' => [
                            'fields' => [
                                'acceptTime' => [
                                    'stringValue' => $currentTime
                                ],
                                'paid' => [
                                    'booleanValue' => true,
                                ],
                                'paidTime' => [
                                    'stringValue' => $currentTime,
                                ],
                                'trxRef' => [
                                    'stringValue' => $tx_ref,
                                ],
                                'accepted' => [
                                    'booleanValue' => true, // Use booleanValue for boolean
                                ],
                                'completed' => [
                                    'booleanValue' => true, // Use booleanValue for boolean
                                ],
                                'completedTime' => [
                                    'stringValue' => $currentTime
                                ],
                                'confirmCompleted' => [
                                    'booleanValue' => true, // Use booleanValue for boolean
                                ],
                                'reasonForConfirmDecline' => [
                                    'nullValue' => null, // Use nullValue for empty fields
                                ],
                                'reasonForDecline' => [
                                    'nullValue' => null, // Use nullValue for empty fields
                                ],
                                'rejected' => [
                                    'booleanValue' => false, // Use booleanValue for boolean
                                ],
                                'bookingId' => [
                                    'stringValue' => (string) $booking->id, // Keep as stringValue if it's not numeric
                                ],
                                'price' => [
                                    'doubleValue' => (float) $booking->agreed_amount, // Use doubleValue for decimal values
                                ],
                                'gigId' => [
                                    'stringValue' => (string) $booking->gig_id, // Keep as stringValue
                                ],
                                'gigName' => [
                                    'stringValue' => (string) $booking->gig->title,  // Gig title
                                ],
                                'gigCurrency' => [
                                    'stringValue' => (string) $booking->gig->currency,  // Gig currency
                                ],
                                'time' => [
                                    'stringValue' => $currentTime,
                                ],
                                'start' => [
                                    'stringValue' => Carbon::parse($booking->start_time)->format('Y-m-d\TH:i:s.u\Z'), // Use stringValue
                                ],
                                'end' => [
                                    'stringValue' => Carbon::parse($booking->end_time)->format('Y-m-d\TH:i:s.u\Z'), // Use stringValue
                                ],
                                'sentBy' => [
                                    'stringValue' => (string) $booking->customer_id, // Keep as stringValue
                                ],
                            ],
                        ],
                    ],

                ],
            ];

            // Firestore URL to create a new message in the chat room
            $updatedChatRoomID = "https://firestore.googleapis.com/v1/projects/fixgini/databases/(default)/documents/chats/{$chatId}/chat_room/{$chatRoomId}";
            // Send the message data to Firestore using PATCH to update the message
            $client = new \GuzzleHttp\Client();
            $client->patch($updatedChatRoomID, [
                'json' => $updateChatRoomData,
            ]);

            // update the booking form table
            // BookingForm::where('id', $booking->id)->update(['chat_id' => $chatId, 'chat_room_id' => $chatRoomId]);
            info('Task completed successfully with MessageId in chat_room.');

            return response()->json([
                'status' => 'success',
                'message' => 'Chat room message id recorded successfully.',
            ], 200);
        } catch (\Throwable $th) {
            Log::error("Failed to record chat room message in Firestore: {$th->getMessage()}");
            return response()->json(['status' => 'error', 'message' => 'Failed to record chat room in Firebase.'], 500);
        }
    }
    private function triggerCompleteFirestore($booking)
    {
        try {
            // Retrieve the chatRoomId and chatId from the session
            $chatRoomId = $booking->chat_room_id;
            $chatId = $booking->chat_id;
            $currentTime = Carbon::now()->format('Y-m-d\TH:i:s.u\Z');

            // Prepare the update data with chatId added to the fields (Optional, might not need the same data again)
            $updateChatData = [
                'fields' => [
                    'chatId' => [
                        'stringValue' => $chatId,  // Adding the chatId to the payload
                    ],
                    'lastMessage' => [
                        'stringValue' => 'Engagement completion awaiting customer approval',
                    ],
                    'lastMessageAt' => [
                        'stringValue' => $currentTime,
                    ],
                    'lastSenderId' => [
                        'stringValue' => (string) $booking->customer_id,
                    ],
                    'chatRoomStatus' => [
                        'stringValue' => 'active',
                    ],
                    'participants' => [
                        'arrayValue' => [
                            'values' => [
                                [
                                    'mapValue' => [
                                        'fields' => [
                                            'firstName' => [
                                                'stringValue' => $booking->customer->name ?? '',
                                            ],
                                            'userPhoto' => [
                                                'stringValue' => $booking->customer->profile_photo_url,
                                            ],
                                            'userUID' => [
                                                'stringValue' => (string) $booking->customer_id,
                                            ],
                                        ],
                                    ],
                                ],
                                [
                                    'mapValue' => [
                                        'fields' => [
                                            'firstName' => [
                                                'stringValue' => $booking->gig->user->name ?? '',
                                            ],
                                            'userPhoto' => [
                                                'stringValue' => $booking->gig->user->profile_photo_url,
                                            ],
                                            'userUID' => [
                                                'stringValue' => (string) $booking->service_provider_id,
                                            ],
                                        ],
                                    ],
                                ],
                            ],
                        ],
                    ],
                    'participantsUIDs' => [
                        'arrayValue' => [
                            'values' => [
                                [
                                    'stringValue' => (string) $booking->customer_id,
                                ],
                                [
                                    'stringValue' => (string) $booking->service_provider_id,
                                ],
                            ],
                        ],
                    ],
                ],
            ];

            // Send the data to Firestore using PATCH to update the existing document with chatId
            $client = new \GuzzleHttp\Client();
            $updateChatId = 'https://firestore.googleapis.com/v1/projects/fixgini/databases/(default)/documents/chats/' . $chatId;
            $client->patch($updateChatId, [
                'json' => $updateChatData,
            ]);

            $updateChatRoomData = [
                'fields' => [
                    'chatId' => [
                        'stringValue' => $chatId,  // The actual chat ID
                    ],
                    'message' => [
                        'stringValue' => 'Engagement completion awaiting customer approval',
                    ],
                    'messageId' => [
                        'stringValue' => $chatRoomId,
                    ],
                    'sentBy' => [
                        'stringValue' => (string) $booking->customer_id,  // The ID of the user who sent the message
                    ],
                    'time' => [
                        'stringValue' => $currentTime,
                    ],

                    'participants' => [
                        'arrayValue' => [
                            'values' => [
                                [
                                    'stringValue' => (string) $booking->customer_id,  // User's ID
                                ],
                                [
                                    'stringValue' => (string) $booking->service_provider_id,  // Provider's ID
                                ],
                            ],
                        ],
                    ],


                    'chatHire' => [
                        'mapValue' => [
                            'fields' => [
                                'acceptTime' => [
                                    'stringValue' => $currentTime
                                ],
                                'paid' => [
                                    'booleanValue' => true,
                                ],
                                'paidTime' => [
                                    'stringValue' => $currentTime,
                                ],
                                'trxRef' => [
                                    'nullValue' => null, // Use nullValue for empty fields
                                ],
                                'accepted' => [
                                    'booleanValue' => true, // Use booleanValue for boolean
                                ],
                                'completed' => [
                                    'booleanValue' => true, // Use booleanValue for boolean
                                ],
                                'completedTime' => [
                                    'stringValue' => $currentTime
                                ],
                                'confirmCompleted' => [
                                    'booleanValue' => false, // Use booleanValue for boolean
                                ],
                                'reasonForConfirmDecline' => [
                                    'nullValue' => null, // Use nullValue for empty fields
                                ],
                                'reasonForDecline' => [
                                    'nullValue' => null, // Use nullValue for empty fields
                                ],
                                'rejected' => [
                                    'booleanValue' => false, // Use booleanValue for boolean
                                ],
                                'bookingId' => [
                                    'stringValue' => (string) $booking->id, // Keep as stringValue if it's not numeric
                                ],
                                'price' => [
                                    'doubleValue' => (float) $booking->agreed_amount, // Use doubleValue for decimal values
                                ],
                                'gigId' => [
                                    'stringValue' => (string) $booking->gig_id, // Keep as stringValue
                                ],
                                'gigName' => [
                                    'stringValue' => (string) $booking->gig->title,  // Gig title
                                ],
                                'gigCurrency' => [
                                    'stringValue' => (string) $booking->gig->currency,  // Gig currency
                                ],
                                'time' => [
                                    'stringValue' => $currentTime,
                                ],
                                'start' => [
                                    'stringValue' => Carbon::parse($booking->start_time)->format('Y-m-d\TH:i:s.u\Z'), // Use stringValue
                                ],
                                'end' => [
                                    'stringValue' => Carbon::parse($booking->end_time)->format('Y-m-d\TH:i:s.u\Z'), // Use stringValue
                                ],
                                'sentBy' => [
                                    'stringValue' => (string) $booking->customer_id, // Keep as stringValue
                                ],
                            ],
                        ],
                    ],

                ],
            ];

            // Firestore URL to create a new message in the chat room
            $updatedChatRoomID = "https://firestore.googleapis.com/v1/projects/fixgini/databases/(default)/documents/chats/{$chatId}/chat_room/{$chatRoomId}";
            // Send the message data to Firestore using PATCH to update the message
            $client = new \GuzzleHttp\Client();
            $client->patch($updatedChatRoomID, [
                'json' => $updateChatRoomData,
            ]);

            info('Task triggered for completion.');

            return response()->json([
                'status' => 'success',
                'message' => 'Task triggered for completion in chat room recorded successfully.',
            ], 200);
        } catch (\Throwable $th) {
            Log::error("Failed to Task triggered for completion in chat room in Firestore: {$th->getMessage()}");
            return response()->json(['status' => 'error', 'message' => 'Failed to triggered for completion in chat room in Firebase.'], 500);
        }
    }


    public function userWallet()
    {
        $user = Auth::user();
        $userWallet = Wallet::where('user_id', $user->id)->first();

        $available = BookingForm::where('service_provider_id', $user->id)->where('status', 'completed')->sum('agreed_amount');
        // $pending = BookingForm::where('service_provider_id', $user->id)->where('status', 'ongoing')->orWhere('status', 'awaiting')->sum('agreed_amount');
        $pending = BookingForm::where('service_provider_id', $user->id)
            ->where(function ($query) {
                $query->where('status', 'ongoing')
                    ->orWhere('status', 'awaiting');
            })
            ->sum('agreed_amount');

        $userWallet->update([
            // 'available' => $available,
            'pending' => $pending,
        ]);

        if ($userWallet) {
            return response()->json([
                'data' => $userWallet,
                'status' => 'success',
                'message' => 'Transactions Found',
            ], 200);
        }
    }
}