<?php

namespace App\Services\Payments\Gateways;

use App\Services\Payments\PaymentGatewayInterface;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;
use Exception;

class PayPalGateway implements PaymentGatewayInterface
{
    protected $config;
    protected $mode;
    protected $baseUrl;
    protected $clientId;
    protected $clientSecret;

    public function __construct($config, $mode)
    {
        $this->config = $config;
        $this->mode = $mode;
        
        $credentials = ($mode === 'live') ? $config['live_credentials'] : $config['test_credentials'];
        
        $this->clientId = $credentials['client_id'] ?? '';
        $this->clientSecret = $credentials['client_secret'] ?? '';
        
        $this->baseUrl = ($mode === 'live') 
            ? 'https://api-m.paypal.com' 
            : 'https://api-m.sandbox.paypal.com';
    }

    protected function getAccessToken()
    {
        if (empty($this->clientId) || empty($this->clientSecret)) {
            throw new Exception("PayPal credentials are missing in the Admin Panel.");
        }

        $response = Http::asForm()->withBasicAuth($this->clientId, $this->clientSecret)
            ->post("{$this->baseUrl}/v1/oauth2/token", [
                'grant_type' => 'client_credentials'
            ]);

        if ($response->failed()) {
            Log::error('PayPal Auth Failed: ' . $response->body());
            throw new Exception('PayPal Authentication Failed. Check Client ID and Secret.');
        }

        return $response->json('access_token');
    }

    public function pay(float $amount, string $currency, array $metadata)
    {
        $token = $this->getAccessToken();
        $orderNumber = $metadata['order_number']; 

        $response = Http::withToken($token)
            ->withHeaders(['Content-Type' => 'application/json'])
            ->post("{$this->baseUrl}/v2/checkout/orders", [
                'intent' => 'CAPTURE',
                'purchase_units' => [
                    [
                        'reference_id' => $orderNumber, 
                        'amount' => [
                            'currency_code' => strtoupper($currency),
                            'value' => number_format($amount, 2, '.', '')
                        ]
                    ]
                ],
                'application_context' => [
                    'return_url' => route('payment.callback', ['gateway' => 'paypal', 'order' => $orderNumber]),
                    'cancel_url' => route('home') 
                ]
            ]);

        if ($response->failed()) {
            Log::error('PayPal Order Creation Failed: ' . $response->body());
            throw new Exception('PayPal Order Creation Failed.');
        }

        $links = collect($response->json('links'));
        $approveUrl = $links->firstWhere('rel', 'approve')['href'];

        return ['url' => $approveUrl];
    }

    public function verify(array $requestData): array
    {
        $orderNumber = $requestData['order'] ?? null; 
        $paypalToken = $requestData['token'] ?? null;

        if (!$paypalToken) {
            Log::error("PayPal Verify: Missing token in URL", $requestData);
            return ['success' => false, 'order_number' => $orderNumber];
        }

        try {
            $token = $this->getAccessToken();

            // --- FIXED: Pass new \stdClass() to force an empty JSON object {} instead of an empty array []
            $response = Http::withToken($token)
                ->withHeaders([
                    'Content-Type' => 'application/json',
                    'Prefer' => 'return=representation'
                ])
                ->post("{$this->baseUrl}/v2/checkout/orders/{$paypalToken}/capture", new \stdClass());

            if ($response->successful()) {
                $status = $response->json('status');
                
                if ($status === 'COMPLETED') {
                    return [
                        'success' => true,
                        'order_number' => $orderNumber
                    ];
                } else {
                    Log::warning("PayPal Capture not completed. Status: " . $status, $response->json());
                }
            } else {
                Log::error("PayPal Capture API Failed", [
                    'body' => $response->body(), 
                    'status' => $response->status()
                ]);
            }
        } catch (\Exception $e) {
            Log::error("PayPal Verify Exception: " . $e->getMessage());
        }

        return ['success' => false, 'order_number' => $orderNumber];
    }
}