<?php
// app/Payment/Paystack.php - Paystack Payment Gateway Integration

class Paystack implements PaymentInterface {
    private $secret_key;
    private $public_key;
    private $base_url = 'https://api.paystack.co';
    
    public function __construct() {
        $this->secret_key = PAYSTACK_SECRET_KEY;
        $this->public_key = PAYSTACK_PUBLIC_KEY;
    }
    
    /**
     * Initialize payment
     */
    public function initialize($data) {
        $url = $this->base_url . '/transaction/initialize';
        
        $fields = [
            'email' => $data['email'],
            'amount' => $data['amount'] * 100, // Convert to kobo
            'reference' => $data['reference'],
            'callback_url' => $data['callback_url'] ?? PAYSTACK_CALLBACK_URL,
            'metadata' => [
                'order_id' => $data['order_id'] ?? null,
                'customer_name' => $data['customer_name'] ?? null,
                'custom_fields' => [
                    [
                        'display_name' => 'Order Number',
                        'variable_name' => 'order_number',
                        'value' => $data['order_number'] ?? ''
                    ]
                ]
            ]
        ];
        
        $response = $this->makeRequest($url, 'POST', $fields);
        
        if ($response['success'] && isset($response['data']['authorization_url'])) {
            return [
                'success' => true,
                'authorization_url' => $response['data']['authorization_url'],
                'access_code' => $response['data']['access_code'],
                'reference' => $response['data']['reference']
            ];
        }
        
        return [
            'success' => false,
            'message' => $response['message'] ?? 'Payment initialization failed'
        ];
    }
    
    /**
     * Verify payment
     */
    public function verify($reference) {
        $url = $this->base_url . '/transaction/verify/' . $reference;
        
        $response = $this->makeRequest($url, 'GET');
        
        // Paystack returns {status: true, data: {...}}
        // NOT {success: true, ...}
        if (isset($response['status']) && $response['status'] === true 
            && isset($response['data']['status']) && $response['data']['status'] === 'success') {
            return [
                'success' => true,
                'status' => 'success',
                'amount' => $response['data']['amount'] / 100, // Convert from kobo
                'reference' => $response['data']['reference'],
                'transaction_date' => $response['data']['paid_at'] ?? $response['data']['transaction_date'],
                'channel' => $response['data']['channel'] ?? 'card',
                'currency' => $response['data']['currency'] ?? 'NGN',
                'gateway_response' => $response['data']['gateway_response'] ?? 'Successful',
                'customer' => [
                    'email' => $response['data']['customer']['email'] ?? null,
                    'customer_code' => $response['data']['customer']['customer_code'] ?? null
                ],
                'metadata' => $response['data']['metadata'] ?? [],
                'raw_response' => $response // Include full response
            ];
        }
        
        return [
            'success' => false,
            'status' => $response['data']['status'] ?? 'failed',
            'message' => $response['message'] ?? 'Payment verification failed',
            'raw_response' => $response
        ];
    }
    
    /**
     * Process refund
     */
    public function refund($reference, $amount = null) {
        $url = $this->base_url . '/refund';
        
        // Get transaction details first
        $transaction = $this->getTransaction($reference);
        
        if (!$transaction['success']) {
            return [
                'success' => false,
                'message' => 'Transaction not found'
            ];
        }
        
        $fields = [
            'transaction' => $reference
        ];
        
        // If partial refund, specify amount in kobo
        if ($amount !== null) {
            $fields['amount'] = $amount * 100;
        }
        
        $response = $this->makeRequest($url, 'POST', $fields);
        
        if ($response['success']) {
            return [
                'success' => true,
                'message' => 'Refund processed successfully',
                'refund_id' => $response['data']['id'] ?? null,
                'status' => $response['data']['status'] ?? 'pending'
            ];
        }
        
        return [
            'success' => false,
            'message' => $response['message'] ?? 'Refund processing failed'
        ];
    }
    
    /**
     * Get transaction details
     */
    public function getTransaction($reference) {
        $url = $this->base_url . '/transaction/verify/' . $reference;
        
        $response = $this->makeRequest($url, 'GET');
        
        if ($response['success']) {
            return [
                'success' => true,
                'data' => $response['data']
            ];
        }
        
        return [
            'success' => false,
            'message' => $response['message'] ?? 'Transaction not found'
        ];
    }
    
    /**
     * Get public key
     */
    public function getPublicKey() {
        return $this->public_key;
    }
    
    /**
     * Make API request
     */
    private function makeRequest($url, $method = 'GET', $data = null) {
        $ch = curl_init();
        
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Authorization: Bearer ' . $this->secret_key,
            'Content-Type: application/json',
            'Cache-Control: no-cache'
        ]);
        
        if ($method === 'POST') {
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        }
        
        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        
        if (curl_errno($ch)) {
            $error = curl_error($ch);
            curl_close($ch);
            
            log_message("Paystack API Error: {$error}", 'error');
            
            return [
                'success' => false,
                'message' => 'Connection error: ' . $error
            ];
        }
        
        curl_close($ch);
        
        $result = json_decode($response, true);
        
        if ($http_code >= 200 && $http_code < 300) {
            return $result;
        }
        
        log_message("Paystack API Error: HTTP {$http_code} - " . ($result['message'] ?? 'Unknown error'), 'error');
        
        return [
            'success' => false,
            'message' => $result['message'] ?? 'API request failed',
            'http_code' => $http_code
        ];
    }
    
    /**
     * Validate webhook signature
     */
    public function validateWebhook($input, $signature) {
        $hash = hash_hmac('sha512', $input, $this->secret_key);
        return hash_equals($hash, $signature);
    }
}