<?php

namespace App\Services;

use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Illuminate\Http\Client\ConnectionException;
use Illuminate\Support\Facades\Cache;

class JasaOtpService
{
    private string $apiKey;
    private string $baseUrl;
    private float $profit;

    public function __construct(int $server = 1)
    {
        $this->profit = (float) config('services.jasaotp.profit', 0);

        if ($server === 2) {
            $this->apiKey = config('services.jasaotp.api_key_2')
                ?: config('services.jasaotp.api_key_1');

            $this->baseUrl = rtrim(
                config('services.jasaotp.api_v2')
                    ?: config('services.jasaotp.api_v1'),
                '/'
            ) . '/';
        } else {
            $this->apiKey  = config('services.jasaotp.api_key_1');
            $this->baseUrl = rtrim(
                config('services.jasaotp.api_v1'),
                '/'
            ) . '/';
        }

        if (empty($this->apiKey)) {
            throw new \RuntimeException('JASAOTP API KEY belum dikonfigurasi');
        }

        if (empty($this->baseUrl)) {
            throw new \RuntimeException('JASAOTP BASE URL belum dikonfigurasi');
        }
    }

    public function getBalance(): int
    {
        try {
            $res = Http::timeout(5)
                ->retry(1, 500)
                ->get($this->baseUrl . 'balance.php', [
                    'api_key' => $this->apiKey
                ])->json();

            return (int)($res['data']['saldo'] ?? $res['saldo'] ?? 0);
        } catch (\Throwable $e) {
            Log::warning('⚠️ getBalance gagal: ' . $e->getMessage());
            return 0;
        }
    }

    public function getCountries(): array
    {
        return Cache::remember('jasaotp_countries_'.$this->baseUrl, 3600, function () {
            try {
                return Http::timeout(5)
                    ->retry(1, 500)
                    ->get($this->baseUrl . 'negara.php', [
                        'api_key' => $this->apiKey
                    ])
                    ->json() ?? [];

            } catch (ConnectionException $e) {
                Log::error('❌ JasaOTP getCountries CONNECTION REFUSED', [
                    'msg' => $e->getMessage()
                ]);
                return [];
            } catch (\Throwable $e) {
                Log::error('❌ JasaOTP getCountries ERROR', [
                    'msg' => $e->getMessage()
                ]);
                return [];
            }
        });
    }

    public function getOperators(string $negara): array
    {
        return Cache::remember("jasaotp_operators_{$negara}_{$this->baseUrl}", 3600, function () use ($negara) {
            try {
                return Http::timeout(5)
                    ->retry(1, 500)
                    ->get($this->baseUrl . 'operator.php', [
                        'api_key' => $this->apiKey,
                        'negara'  => $negara
                    ])
                    ->json() ?? [];

            } catch (\Throwable $e) {
                Log::error('❌ JasaOTP getOperators ERROR', [
                    'negara' => $negara,
                    'msg' => $e->getMessage()
                ]);
                return [];
            }
        });
    }

    public function getServices(string $negara): array
{
    $cacheKey = "jasaotp_services_{$negara}_{$this->baseUrl}";

    // 🔥 kalau sudah ada cache → langsung pakai
    if ($cached = Cache::get($cacheKey)) {
        return $cached;
    }

    $lock = Cache::lock("lock_services_{$negara}", 10);

    if ($lock->get()) {
        try {
            $res = Http::timeout(5)
                ->retry(1, 500)
                ->get($this->baseUrl . 'layanan.php', [
                    'api_key' => $this->apiKey,
                    'negara'  => $negara
                ])
                ->json();

            if (!is_array($res)) $res = [];

            // 🔥 PROCESS DATA
            $list = [];
            if (isset($res['data'][$negara])) {
                $list = &$res['data'][$negara];
            } elseif (isset($res[$negara])) {
                $list = &$res[$negara];
            } elseif (isset($res['data'])) {
                $list = &$res['data'];
            }

            if (is_array($list)) {
                foreach ($list as &$item) {
                    if (!isset($item['harga'])) continue;

                    $modal = (float) $item['harga'];
                    $item['harga_modal'] = $modal;
                    $item['harga'] = round($modal + ($modal * ($this->profit / 100)));
                }
            }

            $res['markup'] = $this->profit;

            Cache::put($cacheKey, $res, 3600);

            return $res;

        } finally {
            $lock->release();
        }
    }

    // 🔥 fallback kalau lagi di-lock
    return Cache::get($cacheKey, []);
}

    public function order(string $negara, string $layanan, string $operator): array
{
    $url = $this->baseUrl . 'order.php';

    $params = [
        'api_key'  => $this->apiKey,
        'negara'   => $negara,
        'layanan'  => $layanan,
        'operator' => $operator,
    ];

    // 🔥 coba max 2x
    for ($i = 0; $i < 2; $i++) {

        try {

            $response = Http::timeout(10)
                ->connectTimeout(5)
                ->retry(1, 500, function ($exception) {
                    return $exception instanceof ConnectionException;
                })
                ->get($url, $params);

            // 🔥 cek status HTTP
            if (!$response->successful()) {

                Log::warning('⚠️ ORDER HTTP ERROR', [
                    'attempt' => $i + 1,
                    'status'  => $response->status(),
                ]);

                continue;
            }

            $json = $response->json();

            // 🔥 pastikan JSON valid
            if (!is_array($json)) {

                Log::warning('⚠️ ORDER INVALID JSON', [
                    'attempt' => $i + 1,
                    'body'    => $response->body(),
                ]);

                continue;
            }

            Log::info('📤 JasaOTP ORDER', [
                'attempt' => $i + 1,
                'url'     => $url,
                'params'  => [
                    'negara'   => $negara,
                    'layanan'  => $layanan,
                    'operator' => $operator,
                ],
                'resp' => $json,
            ]);

            // ✅ sukses
            if (($json['success'] ?? false) && isset($json['data']['order_id'])) {

                return [
                    'success' => true,
                    'message' => $json['message'] ?? 'Order berhasil.',
                    'data'    => [
                        'order_id' => $json['data']['order_id'],
                        'number'   => $json['data']['number'] ?? null,
                    ],
                ];
            }

        } catch (\Throwable $e) {

            Log::warning('⚠️ JasaOTP ORDER Exception', [
                'attempt' => $i + 1,
                'error'   => $e->getMessage(),
            ]);
        }
    }

    // 🔥 fallback
    return [
        'success' => false,
        'message' => 'Order tidak mendapat respon dari provider',
    ];
}
    public function checkOtp(string $id): array
{
    $url = $this->baseUrl . 'sms.php';

    $params = [
        'api_key' => $this->apiKey,
        'id'      => $id,
    ];

    for ($i = 0; $i < 2; $i++) {

        try {

            $response = Http::timeout(10)->connectTimeout(5)
                ->retry(1, 500, function ($exception) {
                    return $exception instanceof ConnectionException;
                })
                ->get($url, $params);

            // 🔥 cek HTTP status
            if (!$response->successful()) {

                Log::warning('⚠️ CHECK OTP HTTP ERROR', [
                    'attempt' => $i + 1,
                    'status'  => $response->status(),
                    'body'    => $response->body(),
                ]);

                continue;
            }

            $json = $response->json();

            // 🔥 pastikan array
            if (!is_array($json)) {

                Log::warning('⚠️ CHECK OTP INVALID JSON', [
                    'attempt' => $i + 1,
                    'body'    => $response->body(),
                ]);

                continue;
            }

            return $json;

        } catch (\Throwable $e) {

            Log::warning('JasaOTP CHECK OTP Exception', [
                'attempt' => $i + 1,
                'error'   => $e->getMessage(),
            ]);
        }
    }

    return [
        'success' => false,
        'status'  => 'pending',
        'message' => 'Provider tidak merespon',
    ];
}

    public function cancelOrder(string $id): array
{
    try {

        $response = Http::timeout(10)
            ->connectTimeout(5)
            ->retry(1, 500, function ($exception) {
                return $exception instanceof ConnectionException;
            })
            ->get($this->baseUrl . 'cancel.php', [
                'api_key' => $this->apiKey,
                'id'      => $id,
            ]);

        // 🔥 cek status HTTP
        if (!$response->successful()) {

            Log::warning('⚠️ CANCEL ORDER HTTP ERROR', [
                'id'     => $id,
                'status' => $response->status(),
                'body'   => $response->body(),
            ]);

            return [
                'success' => false,
                'message' => 'Provider tidak merespon',
            ];
        }

        $json = $response->json();

        // 🔥 pastikan array
        if (!is_array($json)) {

            Log::warning('⚠️ CANCEL ORDER INVALID JSON', [
                'id'   => $id,
                'body' => $response->body(),
            ]);

            return [
                'success' => false,
                'message' => 'Response provider tidak valid',
            ];
        }

        return $json;

    } catch (\Throwable $e) {

        Log::warning('⚠️ JasaOTP cancelOrder ERROR', [
            'id'  => $id,
            'msg' => $e->getMessage()
        ]);

        return [
            'success' => false,
            'message' => 'Gagal membatalkan order (provider error)'
        ];
    }
}
}