<?php

namespace App\Services;

use App\Enums\TransactionStatus;
use App\Models\Transaction;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class TelrService
{
    private $storeId;
    private $authKey;
    private $testMode;
    const API_BASE_URL = 'https://secure.telr.com/gateway/order.json';

    public function __construct()
    {
        $this->storeId = config('services.telr.store_id');
        $this->authKey = config('services.telr.auth_key');
        $this->testMode = config('services.telr.test_mode', true);
    }

    public function createPaymentLink(float $amount, int $transactionId, string $description): ?string
    {
        $data = [
            'method' => 'create',
            'store' => $this->storeId,
            'authkey' => $this->authKey,
            'framed' => 0,
            'order' => [
                'cartid' => $transactionId,
                'test' => $this->testMode ? '1' : '0',
                'amount' => $amount,
                'currency' => 'SAR',
                'description' => "Transaction No.{$transactionId} - {$description}"
            ],
            'return' => [
                'authorised' => route('telr.webhook'),
                'declined' => route('telr.webhook'),
                'cancelled' => route('telr.webhook'),
            ]
        ];

        Log::debug('Creating Telr payment link with data: ', $data);
        $headers = [
            'Content-Type' => 'application/json',
            'accept' => 'application/json',
        ];
        $response = Http::withHeaders(headers: $headers)->post(self::API_BASE_URL, $data);
        Log::debug('Telr API Response: ', $response->json());
        if ($response->successful() && isset($response->json()['order']['url'])) {
            $transaction = Transaction::find($transactionId);
            $transaction?->update(['payment_ref' => $response->json()['order']['ref']]);
            return $response->json()['order']['url'];
        }

        Log::error('Telr API Error on createPaymentLink: ', $response->json());
        return null;
    }

    public function checkPaymentStatus($orderRef)
    {
        $response = Http::withHeaders([
            'Content-Type' => 'application/json',
            'accept' => 'application/json',
        ])->post(self::API_BASE_URL, [
            'method' => 'check',
            'store' => $this->storeId,
            'authkey' => $this->authKey,
            'order' => [
                'ref' => $orderRef
            ]
        ]);

        if ($response->successful()) {
            return $response->json();
        }

        Log::error('Telr API Error on checkPaymentStatus: ', $response->json());
        return null;
    }

    public function handleWebhook($data)
    {
        Log::debug('Telr Webhook Data: ', $data);
        if (!isset($data['OrderRef'])) {
            Log::error('Telr Webhook Error: OrderRef not found in webhook data.');
            return;
        }
        $orderRef = $data['OrderRef'];
        $transaction = Transaction::where('payment_ref', $orderRef)->first();

        if (!$transaction) {
            Log::error('Transaction not found for order ref: ' . $orderRef);
            return;
        }
        Log::debug('Found Transaction: ', ['id' => $transaction->id, 'status' => $transaction->status, 'payment_ref' => $transaction->payment_ref]);
        if ($transaction->status !== TransactionStatus::PENDING_PAYMENT) {
            Log::info('Transaction already processed or not pending: ' . $orderRef);
            return;
        }

        $paymentStatus = $this->checkPaymentStatus($orderRef);
        Log::debug('Telr checkPaymentStatus Data: ', $paymentStatus);
        if ($paymentStatus && isset($paymentStatus['order']['status']['code'])) {
            // Update transaction status based on Telr status code
            // You need to map Telr status codes to your application's transaction statuses
            $telrStatusCode = $paymentStatus['order']['status']['code'];
            $transaction = Transaction::find($paymentStatus['order']['cartid']);
            if (!$transaction) {
                Log::error('Transaction not found for order ref: ' . $orderRef);
                return;
            }
            // Example: 3 = Paid, 2 = Authorised
            // https://docs.telr.com/reference/authorisation-response-codes
            if ($telrStatusCode == 3 || $telrStatusCode == 2) {
                $transaction->update(
                    [
                        'status' => TransactionStatus::PAYMENT_CONFIRMED,
                        'paid_at' => now(),
                        'payment_success_data' => json_encode($paymentStatus)
                    ]
                );
                return true;
            } else {
                // $transaction->update(['status' => 'failed']);
            }
        }
    }
}
