<?php

namespace App\Jobs;

use App\Models\EskizToken;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\Log;

class SendSmsJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected string $phoneNumber;
    protected int $code;

    public function __construct(string $phoneNumber, int $code)
    {
        $this->phoneNumber = $phoneNumber;
        $this->code = $code;
    }

    public function handle(): void
    {
        $phoneNumber = $this->normalizePhoneNumber($this->phoneNumber);

        // Bazadagi tokenni olish
        $token = $this->getTokenFromDb();

        // Token yo'q yoki expired bo'lsa yangilash
        if (!$token) {
            $token = $this->refreshToken();
            if (!$token) {
                Log::error('Eskiz token olish imkonsiz', ['phone' => $phoneNumber]);
                return;
            }
        }

        $postData = [
            'mobile_phone' => $phoneNumber,
            'message' => "pedagog.uz sayti va mobil ilovasi uchun tasdiqlash kodi: {$this->code}",
            'from' => "4546"
        ];

        $response = $this->sendSmsRequest($token, $postData, $phoneNumber);

        // Token eskirgan bo‘lsa qayta olish
        if ($response['http_code'] === 401) {
            Log::warning("Eskiz token muddati tugagan, yangidan olinmoqda...");

            $token = $this->refreshToken();
            if ($token) {
                $this->sendSmsRequest($token, $postData, $phoneNumber);
            }
        }
    }

    private function sendSmsRequest(string $token, array $postData, string $phoneNumber): array
    {
        $curl = curl_init();
        curl_setopt_array($curl, [
            CURLOPT_URL => "https://notify.eskiz.uz/api/message/sms/send",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => http_build_query($postData),
            CURLOPT_HTTPHEADER => [
                "Authorization: Bearer $token",
                "Content-Type: application/x-www-form-urlencoded"
            ],
        ]);

        $response = curl_exec($curl);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        $err = curl_error($curl);
        curl_close($curl);

        if ($err) {
            Log::error("Eskiz SMS cURL Error: " . $err, [
                'phone' => $phoneNumber,
                'http_code' => $httpCode
            ]);
            return ['http_code' => $httpCode];
        }

        Log::debug("Eskiz SMS Response", [
            'phone' => $phoneNumber,
            'http_code' => $httpCode,
            'response' => $response
        ]);

        return ['http_code' => $httpCode, 'body' => $response];
    }

    private function normalizePhoneNumber(string $phoneNumber): string
    {
        $phoneNumber = preg_replace('/[^0-9]/', '', $phoneNumber);

        if (strlen($phoneNumber) === 9 && in_array(substr($phoneNumber, 0, 2), [
                '33', '77', '88', '90', '91', '93', '94', '95', '97', '98', '99'
            ])) {
            $phoneNumber = '998' . $phoneNumber;
        } elseif (str_starts_with($phoneNumber, '+998')) {
            $phoneNumber = substr($phoneNumber, 1);
        }

        return $phoneNumber;
    }

    private function getTokenFromDb(): ?string
    {
        $record = EskizToken::latest()->first();

        if (!$record) return null;

        // Token muddati tugagan bo'lsa
        if ($record->expires_at && now()->greaterThan($record->expires_at)) {
            return null;
        }

        return $record->token;
    }

    private function refreshToken(): ?string
    {
        $email = config('services.eskiz.email');
        $password = config('services.eskiz.password');

        $postData = ['email' => $email, 'password' => $password];

        $curl = curl_init();
        curl_setopt_array($curl, [
            CURLOPT_URL => "https://notify.eskiz.uz/api/auth/login",
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POST => true,
            CURLOPT_POSTFIELDS => http_build_query($postData),
            CURLOPT_HTTPHEADER => ["Content-Type: application/x-www-form-urlencoded"],
        ]);

        $response = curl_exec($curl);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        $err = curl_error($curl);
        curl_close($curl);

        if ($err) {
            Log::error("Eskiz Auth Error: " . $err, ['http_code' => $httpCode]);
            return null;
        }

        $data = json_decode($response, true);

        if (isset($data['message'], $data['data']['token']) && $data['message'] === 'token_generated') {
            $token = $data['data']['token'];
            $expiresAt = now()->addHour(); // Token 1 soatga amal qiladi

            // Tokenni bazaga saqlash (update yoki create)
            EskizToken::updateOrCreate(
                ['id' => 1], // har doim 1-row ishlatiladi
                [
                    'token' => $token,
                    'expires_at' => $expiresAt
                ]
            );

            return $token;
        }

        Log::error("Eskiz Auth Response Invalid", ['response' => $response]);
        return null;
    }
}
