<?php

namespace App\Services\Payments\Providers;

use App\Contracts\BanglaQrProviderInterface;
use App\Models\PaymentTransaction;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Schema;

class HttpBanglaQrProvider implements BanglaQrProviderInterface
{
    public function initiatePayment(PaymentTransaction $transaction, array $payload): array
    {
        if (! $this->setting('initiate_url')) {
            return [
                'configured' => false,
                'successful' => false,
                'body' => [
                    'message' => 'Bangla QR dynamic API initiate_url is not configured.',
                ],
            ];
        }

        $response = Http::timeout((int) $this->setting('timeout', 15))
            ->withHeaders($this->providerHeaders())
            ->post($this->setting('initiate_url'), $payload);

        return [
            'configured' => true,
            'successful' => $response->successful(),
            'body' => $response->json() ?: ['raw' => $response->body()],
        ];
    }

    public function checkStatus(PaymentTransaction $transaction): array
    {
        if (! $this->setting('status_url')) {
            return [
                'configured' => false,
                'successful' => false,
                'body' => [
                    'status' => $transaction->status,
                    'message' => 'Bangla QR status API is not configured.',
                ],
            ];
        }

        $response = Http::timeout((int) $this->setting('timeout', 15))
            ->withHeaders($this->providerHeaders())
            ->get($this->setting('status_url'), [
                'reference' => $transaction->transaction_id,
                'qr_reference' => $transaction->qr_reference,
            ]);

        return [
            'configured' => true,
            'successful' => $response->successful(),
            'body' => $response->json() ?: ['raw' => $response->body()],
        ];
    }

    public function verifyCallback(Request $request): string
    {
        $secret = $this->setting('callback_secret');
        $header = $this->setting('signature_header', 'X-BanglaQR-Signature');
        if (! $secret) {
            return 'unchecked';
        }

        $signature = (string) $request->header($header, '');
        if ($signature === '') {
            return 'missing';
        }

        $expected = hash_hmac('sha256', $request->getContent(), $secret);
        return hash_equals($expected, $signature) ? 'valid' : 'invalid';
    }

    public function refund(PaymentTransaction $transaction, float $amount, array $context = []): array
    {
        return [
            'supported' => false,
            'message' => 'Bangla QR refund API is not configured for this provider adapter.',
        ];
    }

    public function getSettlement(array $filters = []): array
    {
        return [
            'supported' => false,
            'message' => 'Bangla QR settlement API is not configured for this provider adapter.',
        ];
    }

    private function providerHeaders(): array
    {
        $headers = [
            'Accept' => 'application/json',
        ];

        if ($this->setting('api_key')) {
            $headers['Authorization'] = 'Bearer ' . $this->setting('api_key');
        }

        return $headers;
    }

    private function setting(string $key, mixed $default = null): mixed
    {
        $configValue = config("services.bangla_qr.$key");
        if (filled($configValue)) {
            return $configValue;
        }

        if (! Schema::hasTable('addon_settings')) {
            return $default;
        }

        $settings = DB::table('addon_settings')
            ->where('key_name', 'bangla_qr')
            ->where('settings_type', 'payment_config')
            ->first();

        if (! $settings) {
            return $default;
        }

        $mode = $settings->mode ?: (env('APP_ENV') === 'live' ? 'live' : 'test');
        $column = $mode === 'live' ? 'live_values' : 'test_values';
        $values = json_decode($settings->{$column} ?? '{}', true);

        return data_get($values, $key, $default);
    }
}
