<?php

namespace Modules\Sms\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Notification;
use Illuminate\Notifications\Messages\VonageMessage;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Http;
use Modules\Sms\Entities\SmsGlobalSetting;
use Modules\Sms\Entities\SmsUsageLog;
use Modules\Sms\Entities\SmsTemplate;
use Modules\Sms\Channels\AndroidSmsGatewayChannel;
use Modules\Sms\Services\AndroidSmsGatewayClient;

class SendVerifyOtp extends Notification
{
    use Queueable;

    protected $otp;
    protected $message;

    /**
     * Create a new notification instance.
     */
    public function __construct(string $otp)
    {
        $this->otp = $otp;
        $this->message = $this->otp . ' ' . __('sms::modules.email.isTheOtpToVerifyYourPhoneNumber') . ' ' . __('sms::modules.email.doNotShareItWithAnyone');

    }

    /**
     * Get the notification's delivery channels.
     */
    public function via(object $notifiable): array
    {
        $via = [];

        if (! is_null($notifiable->phone_number) && ! is_null($notifiable->phone_code)) {
            if (sms_setting()->vonage_status) {
                array_push($via, 'vonage');
            }

            if (sms_setting()->msg91_status) {
                $via[] = \Modules\Sms\Channels\Msg91Channel::class;
            }

            if (sms_setting()->android_sms_gateway_status && AndroidSmsGatewayClient::canSendForRestaurant(null)) {
                $via[] = AndroidSmsGatewayChannel::class;
            }
        }

        return $via;
    }

    /**
     * Get the Vonage / SMS representation of the notification.
     */
    public function toVonage($notifiable)
    {
        if (sms_setting()->vonage_status) {
            $message = (new VonageMessage)
                        ->content($this->message)->unicode();

        try {
            global_setting()->increment('total_vonage_count');
        } catch (\Exception $e) {
            Log::error('Vonage SMS send failed: ' . $e->getMessage());
            throw $e;
        }

        return $message;

        }
    }

    /**
     * Get the MSG91 representation of the notification.
     */
    public function toMsg91($notifiable)
    {
        if (sms_setting()->msg91_status) {        
            try {
                // Get the flow ID for send OTP
                $smsTemplate = SmsTemplate::where('type', 'send_verify_otp')->first();
                $flowId = $smsTemplate ? $smsTemplate->flow_id : null;
                
                // Format phone number
                $phoneNumber = $notifiable->routeNotificationForMsg91($this);
                
                // Send SMS using the same logic as in SmsSetting
                $success =$this->sendSmsViaMsg91($phoneNumber, $notifiable, $flowId);
                if ($success) {
                    global_setting()->increment('total_msg91_count');
                }
                
            } catch (\Exception $e) {
                Log::error('MSG91 SMS send failed: ' . $e->getMessage());
                throw $e; // Re-throw to be caught by the calling code
            }
        }
    }

    public function toAndroidSmsGateway($notifiable): void
    {
        if (! sms_setting()->android_sms_gateway_status) {
            return;
        }

        try {
            $phone = $notifiable->routeNotificationForAndroidSmsGateway($this);
            if (! $phone) {
                return;
            }

            AndroidSmsGatewayClient::send($phone, $this->message, null, null);

            global_setting()->increment('total_android_sms_gateway_count');
        } catch (\Exception $e) {
            Log::error('Android SMS Gateway send failed: ' . $e->getMessage());
            throw $e;
        }
    }

    /**
     * Send SMS via MSG91 using Transactional API
     */
    private function sendSmsViaMsg91($mobile, $notifiable, $flowId = null)
    {
        $setting = SmsGlobalSetting::first();
      
        $msg91Key = $setting->msg91_auth_key;
        $senderId = $setting->msg91_from;

        // Extract country code and number
        $country = '91'; // default
        $number = $mobile;
        if (preg_match('/^\+(\d{1,3})(\d{6,15})$/', $mobile, $matches)) {
            $country = $matches[1];
            $number = $matches[2];
        }

        // If flow ID is provided, use Flow API, otherwise use transactional API
        if ($flowId && $number && $msg91Key && $senderId) {  
            $response = Http::withHeaders([
                'authkey' => $msg91Key,
                'Content-Type' => 'application/json'
            ])->post('https://api.msg91.com/api/v5/flow/', [
                'flow_id' => $flowId,
                'recipients' => [
                    [
                        'mobiles' => $number,
                        'var' => $this->otp
                    ]
                ]
            ]);       
        } 
        else {
            
            $payload = [
                'sender' => $senderId,
                'route' => '4', // transactional
                'country' => $country,
                'sms' => [
                    [
                        'message' => $this->message,
                        'to' => [$number]
                    ]
                ]
            ];
            $response = Http::withHeaders([
                'authkey' => $msg91Key,
                'Content-Type' => 'application/json'
            ])->post('https://api.msg91.com/api/v2/sendsms', $payload);
        }
        $rawResponse = $response->body();
        
        if (!$response->successful()) {
            Log::error('MSG91 API Error: ' . $rawResponse);
            throw new \Exception('MSG91 API Error: ' . $rawResponse);
        }

        return $response->successful();
    }

    /**
     * Get the array representation of the notification.
     */
    public function toArray($notifiable): array
    {
        return [
            'otp' => $this->otp,
            'message' => $this->message,
        ];
    }
}
