<?php
/**
 * Violet MediaPay Payment Gateway Class
 * Documentation: https://violetmediapay.com
 */

class Violet {
    private $apiKey;
    private $secretKey;
    private $baseUrl;
    private $mode;
    private $notifyUrl;
    private $returnUrl;
    
    public function __construct() {
        $db = db();
        $config = [];
        $stmt = $db->query("SELECT setting_key, setting_value FROM payment_config WHERE setting_key LIKE 'violet_%'");
        while ($row = $stmt->fetch()) {
            $config[$row['setting_key']] = $row['setting_value'];
        }
        
        $this->apiKey    = $config['violet_api_key'] ?? '';
        $this->secretKey = $config['violet_secret_key'] ?? '';
        $this->mode      = $config['violet_mode'] ?? 'sandbox';
        $this->notifyUrl = $config['violet_notify_url'] ?? '';
        $this->returnUrl = $config['violet_return_url'] ?? '';
        
        // Note: Violet menggunakan typo "sanbox" di endpoint sandbox (bukan "sandbox")
        if ($this->mode === 'production') {
            $this->baseUrl = 'https://violetmediapay.com/api/live/';
        } else {
            $this->baseUrl = 'https://violetmediapay.com/api/sanbox/';
        }
    }
    
    /**
     * Cek apakah Violet sudah dikonfigurasi
     */
    public function isConfigured() {
        return !empty($this->apiKey) && !empty($this->secretKey);
    }
    
    /**
     * Get mode
     */
    public function getMode() {
        return $this->mode;
    }
    
    /**
     * Internal CURL request
     */
    private function request($endpoint, $data) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->baseUrl . $endpoint);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Accept: application/json']);
        
        $response = curl_exec($ch);
        $error    = curl_error($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        
        if ($error) {
            return ['success' => false, 'error' => 'CURL Error: ' . $error, 'http_code' => $httpCode];
        }
        
        $result = json_decode($response, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            return ['success' => false, 'error' => 'Invalid JSON response', 'raw' => $response, 'http_code' => $httpCode];
        }
        
        return $result;
    }
    
    /**
     * Buat signature untuk create transaction
     * Formula: hash_hmac('sha256', ref_kode + apikey + amount, secret_key)
     */
    private function createSignature($ref_kode, $amount) {
        return hash_hmac('sha256', $ref_kode . $this->apiKey . $amount, $this->secretKey);
    }
    
    /**
     * Buat transaksi baru
     */
    public function createPayment($params) {
        if (!$this->isConfigured()) {
            return ['success' => false, 'error' => 'Violet belum dikonfigurasi'];
        }
        
        $ref_kode = $params['referenceId'];
        $amount   = (int) $params['amount'];
        $method   = $params['channel'] ?? 'QRIS';
        
        $signature = $this->createSignature($ref_kode, $amount);
        
        $postData = [
            'api_key'          => $this->apiKey,
            'secret_key'       => $this->secretKey,
            'channel_payment'  => $method,
            'ref_kode'         => $ref_kode,
            'nominal'          => $amount,
            'cus_nama'         => $params['customerName'] ?? '',
            'cus_email'        => $params['customerEmail'] ?? '',
            'cus_phone'        => $params['customerPhone'] ?? '',
            'produk'           => $params['productName'] ?? 'Tagihan Internet',
            'url_redirect'     => $params['returnUrl'] ?? $this->returnUrl,
            'url_callback'     => $params['notifyUrl'] ?? $this->notifyUrl,
            'expired_time'     => time() + (24 * 60 * 60), // 24 jam
            'signature'        => $signature
        ];
        
        $result = $this->request('create', $postData);
        
        // Violet return status "success" atau boolean true
        $isSuccess = false;
        if (isset($result['status'])) {
            $isSuccess = (strtolower((string)$result['status']) === 'success' || $result['status'] === true);
        }
        
        if ($isSuccess) {
            $data = $result['data'] ?? $result;
            
            $paymentUrl = $data['checkout_url'] 
                       ?? $data['payment_url'] 
                       ?? $data['url'] 
                       ?? '';
            
            return [
                'success'        => true,
                'session_id'     => $data['id_reference'] ?? $ref_kode,
                'payment_url'    => $paymentUrl,
                'ref_kode'       => $ref_kode,
                'payment_method' => $method,
                'data'           => $data
            ];
        }
        
        return [
            'success' => false,
            'error'   => $result['message'] ?? $result['msg'] ?? 'Gagal membuat transaksi Violet',
            'data'    => $result
        ];
    }
    
    /**
     * Ambil daftar channel pembayaran
     */
    public function getChannels() {
        if (!$this->isConfigured()) {
            return ['success' => false, 'error' => 'Violet belum dikonfigurasi'];
        }
        
        $postData = [
            'api_key'         => $this->apiKey,
            'secret_key'      => $this->secretKey,
            'channel_payment' => 'list'
        ];
        
        $result = $this->request('channel-payment', $postData);
        
        $isSuccess = isset($result['status']) && 
                     (strtolower((string)$result['status']) === 'success' || $result['status'] === true);
        
        if ($isSuccess) {
            return [
                'success'  => true,
                'channels' => $result['data'] ?? []
            ];
        }
        
        return [
            'success' => false,
            'error'   => $result['message'] ?? 'Gagal mengambil channel',
            'data'    => $result
        ];
    }
    
    /**
     * Cek status transaksi
     */
    public function checkTransaction($ref, $ref_id) {
        if (!$this->isConfigured()) {
            return ['success' => false, 'error' => 'Violet belum dikonfigurasi'];
        }
        
        $postData = [
            'api_key'    => $this->apiKey,
            'secret_key' => $this->secretKey,
            'ref'        => $ref,
            'ref_id'     => $ref_id
        ];
        
        return $this->request('transactions', $postData);
    }
    
    /**
     * Validasi signature callback
     * Formula callback: hash_hmac('sha256', ref, apikey)
     */
    public function verifyCallbackSignature($ref, $signature) {
        $expected = hash_hmac('sha256', $ref, $this->apiKey);
        return hash_equals($expected, $signature);
    }
}