<?php

namespace App\Services\Bale;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;
use Livewire\Volt\Exceptions\ReturnNewClassExecutionEndingException;

class BaleSafirOTPService
{
    /*
    |
    | Documentation: https://docs.bale.ai/gateway
    |
    | This class provide easy way to send otp code to your user
    | through Bale messenger first you need to register in https://safir.bale.ai/gateway/login
    | then you get username and password add that to your env file and use this class
    |
    | how is work
    | (new BaleSafirOTPService)->sendOTP($phoneNumber, $otp)
    | $phonNumber should be like country code + phone number in case for Iran be like 989228422123
    | $otp should be between 3 and 8 character
    |
    */
    private string $username;
    private string $password;

    private const TOKEN_URL = 'https://safir.bale.ai/api/v2/auth/token';
    private const SENT_OTP_URL = 'https://safir.bale.ai/api/v2/send_otp';


    public function __construct()
    {
        $this->username = env('BALE_MESSENGER_SAFIR_USERNAME');
        $this->password = env('BALE_MESSENGER_SAFIR_PASSWORD');
    }

    public function runTest()
    {
        dd(
            $this,
            $this->getToken(),
            $this->sendOTP('989228422123', 3123),
        );
    }

    public function getToken(bool $fresh = false): array
    {
        if ($fresh === true) {
            return $this->sendGetTokenRequest();
        }
        return Cache::remember('bale_safir_api_token', now()->addHours(12), function () {
            return $this->sendGetTokenRequest();
        });
    }

    public function sendOTP(string $phoneNumber, int $otp): bool
    {
        $response = Http::withToken($this->getToken()['access_token'])
            ->post(self::SENT_OTP_URL, [
                'phone' => $phoneNumber,
                'otp'   => $otp,
            ])->json();


        if (isset($response['balance'])) {
            return true;
        }


        Log::info('bale otp request failed', $response);

        return false;
    }

    private function sendGetTokenRequest()
    {
        $response = Http::asForm()->post(
            self::TOKEN_URL,
            [
                'grant_type'    => 'client_credentials',
                'client_secret' => $this->password,
                'scope'         => 'read',
                'client_id'     => $this->username,
            ]
        );

        return $response->json();
    }
}
