<?php

namespace App\Services;

use Illuminate\Support\Facades\Log;

class OzowService
{
    private string $siteCode;
    private string $privateKey;
    private string $apiKey;
    private bool $isTest;
    private string $baseUrl;

    public function __construct()
    {
        $this->siteCode = config('services.ozow.site_code', '');
        $this->privateKey = config('services.ozow.private_key', '');
        $this->apiKey = config('services.ozow.api_key', '');
        $this->isTest = config('services.ozow.is_test', true);
        $this->baseUrl = $this->isTest 
            ? 'https://api.ozow.com' 
            : 'https://api.ozow.com';
    }

    /**
     * Generate payment request for Ozow
     */
    public function initiatePayment(array $data): array
    {
        $transactionReference = $data['transaction_reference'];
        $amount = number_format($data['amount'], 2, '.', '');
        $bankReference = $data['bank_reference'] ?? $transactionReference;
        $cancelUrl = $data['cancel_url'];
        $errorUrl = $data['error_url'];
        $successUrl = $data['success_url'];
        $notifyUrl = $data['notify_url'];
        $isTest = $this->isTest ? 'true' : 'false';
        $currencyCode = 'ZAR';
        
        // Generate hash according to Ozow specification
        // HashCheck = SHA512(SiteCode + CountryCode + CurrencyCode + Amount + TransactionReference + BankReference + Optional + CancelUrl + ErrorUrl + SuccessUrl + NotifyUrl + IsTest + PrivateKey)
        $hashString = $this->siteCode 
            . 'ZA' 
            . $currencyCode 
            . $amount 
            . $transactionReference 
            . $bankReference 
            . '' // Optional field
            . $cancelUrl 
            . $errorUrl 
            . $successUrl 
            . $notifyUrl 
            . $isTest 
            . $this->privateKey;
        
        $hashCheck = strtolower(hash('sha512', $hashString));

        // Build the payment URL
        $paymentData = [
            'SiteCode' => $this->siteCode,
            'CountryCode' => 'ZA',
            'CurrencyCode' => $currencyCode,
            'Amount' => $amount,
            'TransactionReference' => $transactionReference,
            'BankReference' => $bankReference,
            'CancelUrl' => $cancelUrl,
            'ErrorUrl' => $errorUrl,
            'SuccessUrl' => $successUrl,
            'NotifyUrl' => $notifyUrl,
            'IsTest' => $isTest,
            'HashCheck' => $hashCheck,
        ];

        // Ozow payment page URL
        $paymentUrl = 'https://pay.ozow.com/?' . http_build_query($paymentData);

        return [
            'success' => true,
            'payment_url' => $paymentUrl,
            'transaction_reference' => $transactionReference,
            'hash' => $hashCheck,
        ];
    }

    /**
     * Verify the hash from Ozow callback/notification
     */
    public function verifyNotificationHash(array $data): bool
    {
        $receivedHash = strtolower($data['Hash'] ?? '');
        
        // Build hash string according to Ozow notification specification
        // Hash = SHA512(SiteCode + TransactionId + TransactionReference + Amount + Status + Optional + CurrencyCode + IsTest + StatusMessage + PrivateKey)
        $hashString = ($data['SiteCode'] ?? '')
            . ($data['TransactionId'] ?? '')
            . ($data['TransactionReference'] ?? '')
            . ($data['Amount'] ?? '')
            . ($data['Status'] ?? '')
            . ($data['Optional'] ?? '')
            . ($data['CurrencyCode'] ?? '')
            . ($data['IsTest'] ?? '')
            . ($data['StatusMessage'] ?? '')
            . $this->privateKey;
        
        $calculatedHash = strtolower(hash('sha512', $hashString));
        
        Log::info('Ozow hash verification', [
            'received' => $receivedHash,
            'calculated' => $calculatedHash,
            'match' => $receivedHash === $calculatedHash,
        ]);
        
        return $receivedHash === $calculatedHash;
    }

    /**
     * Check if payment was successful based on status
     */
    public function isPaymentSuccessful(string $status): bool
    {
        return strtolower($status) === 'complete';
    }

    /**
     * Get payment status from Ozow API
     */
    public function getPaymentStatus(string $transactionId): ?array
    {
        try {
            $url = "{$this->baseUrl}/GetTransactionByReference";
            
            $response = file_get_contents($url . '?' . http_build_query([
                'SiteCode' => $this->siteCode,
                'TransactionReference' => $transactionId,
            ]), false, stream_context_create([
                'http' => [
                    'header' => "ApiKey: {$this->apiKey}\r\n",
                ],
            ]));
            
            if ($response) {
                return json_decode($response, true);
            }
        } catch (\Exception $e) {
            Log::error('Ozow API error: ' . $e->getMessage());
        }
        
        return null;
    }

    /**
     * Generate a unique transaction reference
     */
    public function generateTransactionReference(int $orderId): string
    {
        return 'PH-' . $orderId . '-' . time() . '-' . strtoupper(substr(md5(uniqid()), 0, 6));
    }
}
