<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Controllers\Site\SiteController;
use App\Http\Controllers\Site\WebsiteBookingControllerr;
use Illuminate\Http\Request;
use App\Models\Booking\SchServiceBooking;
use App\Models\Customer\CmnCustomer;
use App\Models\Settings\CmnBranch;
use App\Models\Settings\SiteRespondIoKeywords;
use App\Models\Services\SchServices;
use App\Models\Employee\SchEmployee;
use App\Models\Website\SiteRespondIoEventLog;
use App\Models\Website\SiteRespondIoEventLogMessage;
use App\Models\Website\SiteRespondIoEventLogChannel;
use App\Models\Website\SiteRespondIoEventLogContact;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Notification;
use Illuminate\Support\Facades\Log;
use App\Enums\ServiceStatus;
use Carbon\Carbon;
use ErrorException;

class RespondIoController extends Controller
{
    public function sendReminder(SchServiceBooking $appointment)
    {
        $serviceDate = new Carbon($appointment->date);
        $appointmentStatus = ServiceStatus::wordFromValue($appointment->status);
        if ($appointment->customer->respondio_ctc_id) {
            $identifier = 'id:' . $appointment->customer->respondio_ctc_id;
        } else {
            $identifier = 'phone:' . $appointment->customer->phone_no;
        }

        $appointment->start_time = Carbon::createFromFormat('H:i:s', $appointment->start_time)->format('H:i');
        // $whatsapp_message = "*Reminder For Your Appointment*\nBooking No: $appointment->id\nName: $appointment->customer_name\nService: $appointment->service\nDate: {$serviceDate->format('D, M d, Y')}\nTime: $appointment->start_time - $appointment->end_time\nLocation: $appointment->branch\nStatus: $appointmentStatus";
        // //$telegram_message = "Dear $user->name,\n\nThis is a confirmation notice of your appointment\n\nBooking No: $updateData->id\nName: $user->name\nService: $serviceName\nDate: {$serviceDate->format('D, M d, Y')}\nTime: $updateData->start_time - $updateData->end_time\nLocation: $branchName";
        // //$identifier = 'phone:+'.$customer->phone_no;

        // // Send message via Respond.io API
        // $response = Http::withHeaders([
        //     'Accept' => 'application/json',
        //     'Authorization' => 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NjYyMiwic3BhY2VJZCI6MTU2NTE0LCJvcmdJZCI6MTU4MDM2LCJ0eXBlIjoiYXBpIiwiaWF0IjoxNzExOTYwMjg4fQ.wLWuSYTPI-NhULIg5jtuzKFuCmhG91MvI77goMYOn_I',
        //     'Content-Type' => 'application/json',
        // ])->post('https://api.respond.io/v2/contact/' . $identifier . '/message', [
        //     'message' => [
        //         // 'text' => $whatsapp_message,
        //         'text' => $whatsapp_message,
        //         'type' => 'text'
        //     ],
        //     'channelId' => 0,
        // ]);

        // if ($response->successful()) {
        //     // Message sent successfully
        //     $upcomingAppointments[] = ['booking_no' => $appointment->id, 'response_msg' => $response->json()];
        // } else {
        //     // Failed to send message
        //     return false;
        // }

        // Sending message using whatsapp template
        //$whatsapp_message = "*Appointment Pending Acceptance* \n\nBooking No: {{1}}\n\nYour appointment is pending acceptance from branch supervior";
        //$identifier = 'phone:'.$customer->phone_no;
        // Send message via Respond.io API
        $response = Http::withHeaders([
            'Accept' => 'application/json',
            'Authorization' => 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NjYyMiwic3BhY2VJZCI6MTU2NTE0LCJvcmdJZCI6MTU4MDM2LCJ0eXBlIjoiYXBpIiwiaWF0IjoxNzExOTYwMjg4fQ.wLWuSYTPI-NhULIg5jtuzKFuCmhG91MvI77goMYOn_I',
            'Content-Type' => 'application/json',
        ])->post('https://api.respond.io/v2/contact/'.$identifier.'/message', [
            "message" => [
                "type" => "whatsapp_template",
                "template" => [
                    "name" => "reminder_notification",
                    "components" => [
                        [
                            "type" => "body",
                            "text" => "This is a reminder of your appointment, with Booking No. {{1}} on {{2}}, {{3}} located at {{4}}. See you soon!",
                            "parameters" => [
                                [
                                    "type" => "text",
                                    "text" => $appointment->id,
                                ],
                                [
                                    "type" => "text",
                                    "text" => $serviceDate->format('D, M d, Y'),
                                ],
                                [
                                    "type" => "text",
                                    "text" => $appointment->start_time,
                                ],
                                [
                                    "type" => "text",
                                    "text" => $appointment->branch,
                                ],
                            ],
                        ]
                    ],
                    "languageCode" => "en",
                ],
            ],
            
            'channelId' => (int)config('app.respond_io_whatsapp_channel_id'),
        ]);

        if ($response->successful()) {
            // Message sent successfully
            \Log::info($response);
        } else {
            // Failed to send message
            \Log::info($response);
            throw new ErrorException(translate("Failed to send whatsapp message"));
        }
    }

    public function searchAppointments(Request $request)
    {
        //dd($request->email);

        $appointments = SchServiceBooking::join('cmn_customers', 'sch_service_bookings.cmn_customer_id', '=', 'cmn_customers.id')
            ->join('sch_services', 'sch_service_bookings.sch_service_id', '=', 'sch_services.id')
            ->join('cmn_branches', 'sch_service_bookings.cmn_branch_id', '=', 'cmn_branches.id')
            ->join('sch_employees', 'sch_service_bookings.sch_employee_id', '=', 'sch_employees.id')
            ->where('cmn_customers.phone_no', '+' . $request->phone)
            ->where('sch_service_bookings.status', '<', 3)
            ->whereDate('sch_service_bookings.date', '>=', now()->toDateString())
            ->select([
                'sch_service_bookings.id',
                'cmn_branches.name as branch',
                'sch_service_bookings.cmn_branch_id',
                'sch_employees.full_name as employee',
                'sch_service_bookings.sch_employee_id',
                'cmn_customers.full_name as customer',
                'cmn_customers.fullName_S as someoneelse',
                'sch_service_bookings.cmn_customer_id',
                'cmn_customers.phone_no',
                'cmn_customers.email',
                'sch_service_bookings.date',
                'sch_service_bookings.sch_service_id',
                'sch_services.title as service',
                'sch_services.sch_service_category_id',
                'sch_service_bookings.start_time',
                'sch_service_bookings.end_time',
                'sch_service_bookings.is_checked',
                'sch_service_bookings.SomeBody_Name',
                'sch_service_bookings.status',
                'sch_service_bookings.remarks'
            ])
            ->orderBy('sch_service_bookings.id', 'desc')
            ->get();

        if ($request->send_msg) {
            if ($appointments->count() > 0) {
                return $this->apiResponse(['status' => '1'], 200);
            } else {
                return $this->apiResponse(['status' => '0'], 200);
            }
        }

        $upcomingAppointments = array();

        if ($request->user_input) {
            if ($appointments->count() > 0) {
                //dd($request->user_input, $appointments);
                $validateRecord = $appointments->where('id', $request->user_input);

                if ($validateRecord->count() > 0) {
                    return $this->apiResponse(['status' => '1'], 200);
                } else {
                    return $this->apiResponse(['status' => '0'], 200);
                }
            }
        }

        foreach ($appointments as $appointment) {
            $serviceDate = new Carbon($appointment->date);
            $appointmentStatus = ServiceStatus::wordFromValue($appointment->status);
            $whatsapp_message = "*Booking No: $appointment->id*\nName: $appointment->customer\nService: $appointment->service\nDate: {$serviceDate->format('D, M d, Y')}\nTime: $appointment->start_time - $appointment->end_time\nLocation: $appointment->branch\nStatus: $appointmentStatus";
            //$telegram_message = "Dear $user->name,\n\nThis is a confirmation notice of your appointment\n\nBooking No: $updateData->id\nName: $user->name\nService: $serviceName\nDate: {$serviceDate->format('D, M d, Y')}\nTime: $updateData->start_time - $updateData->end_time\nLocation: $branchName";
            //$identifier = 'phone:+'.$customer->phone_no;

            $identifier = 'id:' . $request->contact_id;
            // Send message via Respond.io API
            $response = Http::withHeaders([
                'Accept' => 'application/json',
                'Authorization' => 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NjYyMiwic3BhY2VJZCI6MTU2NTE0LCJvcmdJZCI6MTU4MDM2LCJ0eXBlIjoiYXBpIiwiaWF0IjoxNzExOTYwMjg4fQ.wLWuSYTPI-NhULIg5jtuzKFuCmhG91MvI77goMYOn_I',
                'Content-Type' => 'application/json',
            ])->post('https://api.respond.io/v2/contact/' . $identifier . '/message', [
                'message' => [
                    // 'text' => $whatsapp_message,
                    'text' => $whatsapp_message,
                    'type' => 'text'
                ],
                'channelId' => 0,
            ]);

            if ($response->successful()) {
                // Message sent successfully
                $upcomingAppointments[] = ['booking_no' => $appointment->id, 'response_msg' => $response->json()];
            } else {
                // Failed to send message
                return false;
            }

            // $response = Http::withHeaders([
            //     'Accept' => 'application/json',
            //     'Authorization' => 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NjYyMiwic3BhY2VJZCI6MTU2NTE0LCJvcmdJZCI6MTU4MDM2LCJ0eXBlIjoiYXBpIiwiaWF0IjoxNzExOTYwMjg4fQ.wLWuSYTPI-NhULIg5jtuzKFuCmhG91MvI77goMYOn_I',
            //     'Content-Type' => 'application/json',
            // ])->put('https://api.respond.io/v2/contact/'.$identifier, [
            //     'custom_fields' => [
            //        'name' =>
            //     ]
            // ]);

            // if ($response->successful()) {
            //     // Message sent successfully
            //     $upcomingAppointments[] = ['booking_no' => $appointment->id, 'response_msg' => $response->json()];    
            // } else {
            //     // Failed to send message
            //     return false;
            // }
        }
        // dd($upcomingAppointments);

        return $this->apiResponse(['status' => '1', 'data' => $upcomingAppointments], 200);
    }


    public function handleIncomingMessage(Request $request)
    {
        $data = $request->all();
        //dd($data, $request);

        $eventLog = SiteRespondIoEventLog::create([
            'event_type' => 'incoming_message',
            'event_id' => $data['event_id'],
            'created_at' => now(),
            'updated_at' => now()
        ]);

        SiteRespondIoEventLogMessage::create([
            'event_log_id' => $eventLog->id,
            'message_id' => $data['message']['messageId'] ?? null,
            'message' => $data['message'] ?? null,
            'status' => $data['message']['status'] ?? null,
            'channel_message_id' => $data['message']['channelMessageId'] ?? null,
            'contact_id' => $data['message']['contactId'] ?? null,
            'channel_id' => $data['message']['channelId'] ?? null,
            'traffic' => $data['message']['traffic'] ?? null,
            'timestamp' => $data['message']['timestamp'] ?? null,
            'created_at' => now(),
            'updated_at' => now()
        ]);

        // Debug: Contact & Channel not updated
        SiteRespondIoEventLogContact::create([
            'event_log_id' => $eventLog->id,
            'first_name' => $data['contact']['firstName'] ?? null,
            'last_name' => $data['contact']['lastName'] ?? null,
            'language' => $data['contact']['language'] ?? null,
            'phone' => $data['contact']['phone'] ?? null,
            'email' => $data['contact']['email'] ?? null,
            'language' => $data['contact']['language'] ?? null,
            'profile_pic' => $data['contact']['profilePic'] ?? null,
            'country_code' => $data['contact']['countryCode'] ?? null,
            'status' => $data['contact']['status'] ?? null,
            'assignee' => $data['contact']['assignee'] ?? null,
            'created_at_timestamp' => $data['contact']['created_at'] ?? null,
            'created_at' => now(),
            'updated_at' => now()
        ]);

        SiteRespondIoEventLogChannel::create([
            'event_log_id' => $eventLog->id,
            'name' => $data['channel']['name'] ?? null,
            'source' => $data['channel']['source'] ?? null,
            'meta' => $data['channel']['meta'] ?? null,
            'created_at_timestamp' => $data['channel']['created_at'] ?? null,
            'created_at' => now(),
            'updated_at' => now()
        ]);

        // Update timestamp in 'last_incoming_whatsapp_msg' column in cmn_customers table
        CmnCustomer::where('phone_no', $data['contact']['phone'])
        ->update([
            'last_incoming_whatsapp_msg' => $data['message']['timestamp'],
            'updated_at' => now()
        ]);

        Log::info('Incoming message received:', $data);

        $incomingText = $data['message']['message']['type'] == 'text' ? htmlentities($data['message']['message']['text'], ENT_QUOTES, 'UTF-8') : '';

        $keyword = SiteRespondIoKeywords::whereRaw(
            "JSON_SEARCH(LOWER(keyword), 'one', LOWER(?)) IS NOT NULL",
            ['%' . strtolower($incomingText) . '%']
        )->first();

        if ($keyword) {
            Log::info('Keyword received:' . json_encode($keyword));
            
            $identifier = 'phone:'. $data['contact']['phone'];
            switch ($keyword->type) {
                case 1:
                    # code...
                    break;
                case 2:
                    // End conversation via Respond.io API
                    $response = Http::withHeaders([
                        'Accept' => 'application/json',
                        'Authorization' => 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NjYyMiwic3BhY2VJZCI6MTU2NTE0LCJvcmdJZCI6MTU4MDM2LCJ0eXBlIjoiYXBpIiwiaWF0IjoxNzExOTYwMjg4fQ.wLWuSYTPI-NhULIg5jtuzKFuCmhG91MvI77goMYOn_I',
                        'Content-Type' => 'application/json',
                    ])->post('https://api.respond.io/v2/contact/'.$identifier.'/conversation/status', [
                        'status' => 'close',
                        'summary' => 'Ending workflow due to detected keyword',
                        'category' => 'Workflow Endpoint'
                    ]);

                    // \Log::info('Close conversation: ' . $response);

                    if (!$response->successful()) {
                        return false;
                    }
                    break;
                case 3:
                    # code...
                    break;
                case 4:
                    # code...
                    break;
                default:
                    # code...
                    break;
            }
            // Return a response with the found keyword status
            return $this->apiResponse(['status' => '1', 'message' => 'Keyword found'], 200);
        }

        return response()->json(['status' => 'success', 'message' => 'Incoming message processed'], 200);
    }

    public function handleOutgoingMessage(Request $request)
    {
        $data = $request->all();

        $eventLog = SiteRespondIoEventLog::create([
            'event_type' => 'outgoing_message',
            'event_id' => $data['event_id'],
            'created_at' => now(),
            'updated_at' => now()
        ]);

        SiteRespondIoEventLogMessage::create([
            'event_log_id' => $eventLog->id,
            'message_id' => $data['message']['messageId'] ?? null,
            'message' => $data['message'] ?? null,
            'status' => $data['message']['status'] ?? null,
            'channel_message_id' => $data['message']['channelMessageId'] ?? null,
            'contact_id' => $data['message']['contactId'] ?? null,
            'channel_id' => $data['message']['channelId'] ?? null,
            'traffic' => $data['message']['traffic'] ?? null,
            'timestamp' => $data['message']['timestamp'] ?? null,
            'created_at' => now(),
            'updated_at' => now()
        ]);

        Log::info('Outgoing message sent:', $data);

        return response()->json(['status' => 'success', 'message' => 'Outgoing message processed'], 200);
    }

    public function handleContactUpdated(Request $request)
    {
        $data = $request->all();

        $eventLog = SiteRespondIoEventLog::create([
            'event_type' => 'contact_updated',
            'event_data' => json_encode($data),
            'created_at' => now(),
            'updated_at' => now()
        ]);

        SiteRespondIoEventLogContact::create([
            'event_log_id' => $eventLog->id,
            'contact_id' => $data['contact']['id'] ?? null,
            'name' => $data['contact']['name'] ?? null,
            'phone' => $data['contact']['phone'] ?? null,
            'email' => $data['contact']['email'] ?? null,
            'created_at' => now(),
            'updated_at' => now()
        ]);

        Log::info('Contact updated:', $data);

        return response()->json(['status' => 'success', 'message' => 'Contact update processed'], 200);
    }

    public function listContactChannel($phone_no)
    {
        $response = Http::withHeaders([
            'Accept' => 'application/json',
            'Authorization' => 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NjYyMiwic3BhY2VJZCI6MTU2NTE0LCJvcmdJZCI6MTU4MDM2LCJ0eXBlIjoiYXBpIiwiaWF0IjoxNzExOTYwMjg4fQ.wLWuSYTPI-NhULIg5jtuzKFuCmhG91MvI77goMYOn_I',
            'Content-Type' => 'application/json',
        ])->get('https://api.respond.io/v2/contact/phone:' . $phone_no . '/channels');

        if ($response->successful()) {
            // Message sent successfully
            $respondIoController = new RespondIoController;
            $lastIncomingMessage = $respondIoController->getLastIncomingMessage($response->json()['items']);
            return $lastIncomingMessage;
        } else {
            // Failed to send message
            return false;
        }
    }

    public function getLastIncomingMessage($items)
    {
        $lastMessageTime = '';
        foreach ($items as $item) {
            if($item['id'] = (int)config('app.respond_io_whatsapp_channel_id')){ // Id of the whatsapp channel
                $lastMessageTime = $item['lastIncomingMessageTime'];
                break;
            }
        }

        return $lastMessageTime;
    }

    public function keywordSearch(Request $request)
    {
        // Sanitize user input
        $userInput = htmlentities($request->user_input, ENT_QUOTES, 'UTF-8');
        
        // Check if branch exists
        $branchExist = CmnBranch::where('short_name', $userInput)->exists();
        
        if ($branchExist) {
            // Merge the new attribute into the request
            $request->merge(['branchName' => $request->user_input]);
            $WebsiteBookingController = new WebsiteBookingControllerr();
            $WebsiteBookingController->branchSupport($request);
        }else{
            // Search in the keywords table if the branch doesn't exist
            $keyword = SiteRespondIoKeywords::whereRaw(
                "JSON_SEARCH(LOWER(keyword), 'one', LOWER(?)) IS NOT NULL",
                ['%' . strtolower($userInput) . '%']
            )->first();
            
            if ($keyword) {
                $identifier = 'phone:'. $request->phoneNumber;
                switch ($keyword->type) {
                    case 1:
                        # code...
                        break;
                    case 2:
                        // End conversation via Respond.io API
                        $response = Http::withHeaders([
                            'Accept' => 'application/json',
                            'Authorization' => 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6NjYyMiwic3BhY2VJZCI6MTU2NTE0LCJvcmdJZCI6MTU4MDM2LCJ0eXBlIjoiYXBpIiwiaWF0IjoxNzExOTYwMjg4fQ.wLWuSYTPI-NhULIg5jtuzKFuCmhG91MvI77goMYOn_I',
                            'Content-Type' => 'application/json',
                        ])->post('https://api.respond.io/v2/contact/'.$identifier.'/conversation/status', [
                            'status' => 'close',
                            'summary' => 'Ending branch support workflow',
                            'category' => 'Workflow Endpoint'
                        ]);

                        \Log::info($response);

                        if (!$response->successful()) {
                            return false;
                        }
                        break;
                    case 3:
                        # code...
                        break;
                    case 4:
                        # code...
                        break;
                    default:
                        # code...
                        break;
                }
                // Return a response with the found keyword status
                return $this->apiResponse(['status' => '1', 'message' => 'Keyword found'], 200);
            } else {
                // Return a response if neither branch nor keyword is found
                return $this->apiResponse(['status' => '0', 'message' => 'No branch or keyword found'], 200);
            }
        }
    }

    public function uriEncode(Request $request)
    {
        \Log::alert($this->apiResponse(['status' => '1', 'encodedString' => urlencode($request->stringToEncode)], 200));
        return $this->apiResponse(['status' => '1', 'encodedString' => urlencode($request->stringToEncode)], 200);
    }
}