<?php

namespace App\Services;

use App\Models\Order;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class PhonePeService
{
    protected string $env;
    protected string $merchantId;
    protected string $saltKey;
    protected string $saltIndex;
    protected string $baseUrl;

    public function __construct()
    {
        $this->env = env('PHONEPE_ENV') ?: config('services.phonepe.env', 'production');
        $this->merchantId = env('PHONEPE_MERCHANT_ID') 
            ?: config('services.phonepe.merchant_id') 
            ?: env('PHONEPE_CLIENT_ID') 
            ?: config('services.phonepe.client_id', '');
        $this->saltKey = env('PHONEPE_SALT_KEY') 
            ?: config('services.phonepe.salt_key') 
            ?: env('PHONEPE_CLIENT_SECRET') 
            ?: config('services.phonepe.client_secret', '');
        $this->saltIndex = (string) (env('PHONEPE_SALT_INDEX') ?: env('PHONEPE_CLIENT_VERSION', '1'));

        if (strtolower($this->env) === 'production') {
            $this->baseUrl = 'https://api.phonepe.com/apis/hermes';
        } else {
            $this->baseUrl = 'https://api-preprod.phonepe.com/apis/pg-sandbox';
        }
    }

    /**
     * Initiate standard PhonePe PG payment request.
     */
    public function initiatePayment(Order $order, string $redirectUrl, string $callbackUrl): array
    {
        if (empty($this->merchantId) || empty($this->saltKey)) {
            Log::warning("PhonePe Production credentials not configured in backend .env");
            return [
                'success' => false,
                'message' => 'PhonePe payment gateway credentials are not configured in backend environment.'
            ];
        }

        // Unique Merchant Transaction ID: TXN_{order_number}_{timestamp}
        $merchantTransactionId = 'TXN_' . preg_replace('/[^A-Za-z0-9]/', '', $order->order_number) . '_' . time();
        $merchantUserId = 'CUST_' . preg_replace('/[^0-9]/', '', $order->customer_phone ?: '0000000000');
        
        // Amount in paise (1 INR = 100 paise)
        $amountInPaise = (int) round(((float) $order->total_amount) * 100);

        $payload = [
            'merchantId' => $this->merchantId,
            'merchantTransactionId' => $merchantTransactionId,
            'merchantUserId' => $merchantUserId,
            'amount' => $amountInPaise,
            'redirectUrl' => $redirectUrl,
            'redirectMode' => 'POST',
            'callbackUrl' => $callbackUrl,
            'mobileNumber' => substr(preg_replace('/[^0-9]/', '', $order->customer_phone), -10),
            'paymentInstrument' => [
                'type' => 'PAY_PAGE'
            ]
        ];

        $encodePayload = base64_encode(json_encode($payload));
        $apiPath = '/pg/v1/pay';

        // Checksum calculation: SHA256(base64Payload + "/pg/v1/pay" + saltKey) + "###" + saltIndex
        $checksum = hash('sha256', $encodePayload . $apiPath . $this->saltKey) . '###' . $this->saltIndex;

        try {
            $endpoint = $this->baseUrl . $apiPath;
            $response = Http::withHeaders([
                'Content-Type' => 'application/json',
                'X-VERIFY' => $checksum,
                'accept' => 'application/json',
            ])->post($endpoint, [
                'request' => $encodePayload
            ]);

            $statusCode = $response->status();
            $resData = $response->json();
            Log::info("PhonePe Initiate Response (HTTP {$statusCode}):", $resData ?? ['raw' => $response->body()]);

            if ($response->successful() && isset($resData['success']) && $resData['success'] === true) {
                $payUrl = $resData['data']['instrumentResponse']['redirectInfo']['url'] ?? null;
                
                if ($payUrl) {
                    // Update order with merchant transaction ID
                    $order->update([
                        'transaction_id' => $merchantTransactionId,
                        'payment_details' => json_encode($resData)
                    ]);

                    return [
                        'success' => true,
                        'merchant_transaction_id' => $merchantTransactionId,
                        'redirect_url' => $payUrl,
                        'message' => 'Payment initiated successfully.'
                    ];
                }
            }

            // Extract exact error code and safe diagnostic message from PhonePe API response
            $errCode = $resData['code'] ?? (string) $statusCode;
            $errMessage = $resData['message'] ?? 'PhonePe gateway initiation rejected.';

            if ($statusCode === 404 || $errCode === '404') {
                $safeMsg = "PhonePe Gateway Error (HTTP 404): Merchant Account / API Route mapping not found. Please verify your Merchant ID & Production onboarding status.";
            } else if ($errCode === 'KEY_NOT_CONFIGURED') {
                $safeMsg = "PhonePe Gateway Error: Key not found for merchant. Please verify your Salt Key / Client Secret.";
            } else {
                $safeMsg = "PhonePe Gateway Error (HTTP {$statusCode} - {$errCode}): {$errMessage}";
            }

            return [
                'success' => false,
                'status_code' => $statusCode,
                'code' => $errCode,
                'message' => $safeMsg
            ];

        } catch (\Exception $e) {
            Log::error("PhonePe Payment Initiation Exception: " . $e->getMessage());
            return [
                'success' => false,
                'message' => 'Error connecting to PhonePe Payment Gateway: ' . $e->getMessage()
            ];
        }
    }

    /**
     * Securely verify payment status directly with PhonePe Server API.
     */
    public function verifyStatus(string $merchantTransactionId): array
    {
        if (empty($this->merchantId) || empty($this->saltKey)) {
            return [
                'success' => false,
                'payment_status' => 'failed',
                'message' => 'PhonePe credentials not configured.'
            ];
        }

        $apiPath = "/pg/v1/status/{$this->merchantId}/{$merchantTransactionId}";
        $checksum = hash('sha256', $apiPath . $this->saltKey) . '###' . $this->saltIndex;

        try {
            $endpoint = $this->baseUrl . $apiPath;
            $response = Http::withHeaders([
                'Content-Type' => 'application/json',
                'X-VERIFY' => $checksum,
                'X-MERCHANT-ID' => $this->merchantId,
                'accept' => 'application/json',
            ])->get($endpoint);

            $resData = $response->json();
            Log::info("PhonePe Status Check Response for {$merchantTransactionId}:", $resData ?? []);

            if ($response->successful() && isset($resData['success']) && $resData['success'] === true) {
                $code = $resData['code'] ?? '';
                $state = $resData['data']['state'] ?? '';

                if ($code === 'PAYMENT_SUCCESS' || $state === 'COMPLETED') {
                    return [
                        'success' => true,
                        'payment_status' => 'paid',
                        'code' => $code,
                        'phonepe_reference_id' => $resData['data']['transactionId'] ?? null,
                        'data' => $resData['data'] ?? []
                    ];
                }

                if ($code === 'PAYMENT_PENDING' || $state === 'PENDING') {
                    return [
                        'success' => true,
                        'payment_status' => 'pending',
                        'code' => $code,
                        'data' => $resData['data'] ?? []
                    ];
                }
            }

            return [
                'success' => false,
                'payment_status' => 'failed',
                'code' => $resData['code'] ?? 'PAYMENT_FAILED',
                'message' => $resData['message'] ?? 'Payment verification failed.'
            ];

        } catch (\Exception $e) {
            Log::error("PhonePe Status Check Exception for {$merchantTransactionId}: " . $e->getMessage());
            return [
                'success' => false,
                'payment_status' => 'failed',
                'message' => 'Status verification error: ' . $e->getMessage()
            ];
        }
    }

    /**
     * Verify Callback Checksum from PhonePe Webhook POST.
     */
    public function verifyCallbackChecksum(string $responseBody, string $headerXVerify): bool
    {
        if (empty($headerXVerify) || empty($this->saltKey)) {
            return false;
        }

        $expectedChecksum = hash('sha256', $responseBody . $this->saltKey) . '###' . $this->saltIndex;
        return hash_equals($expectedChecksum, $headerXVerify);
    }
}
