<?php

// Prevent direct script access
if (basename(__FILE__) == basename($_SERVER['SCRIPT_FILENAME'])) {
    die('No direct script access allowed');
}

// --- Zibal Payment Gateway Service ---

/**
 * Requests a payment transaction from Zibal.
 *
 * @param int $amount_rial Amount in Rials.
 * @param string $description Description for the transaction.
 * @param string $callback_url The URL Zibal redirects to after payment attempt.
 * @param string|null $mobile User's mobile number.
 * @param array|null $allowedCards Optional list of allowed card numbers (PANs).
 * @param string|null $nationalCode Optional national code for identity verification.
 * @param string|null $orderId Optional order ID for tracking.
 * @return array Result array with 'success' (bool), 'trackId' (string|null), 'payment_url' (string|null), 'message' (string).
 */
function requestZibalPayment(int $amount_rial, string $description, string $callback_url, ?string $mobile = null, ?array $allowedCards = null, ?string $nationalCode = null, ?string $orderId = null): array {
    if (!defined('ZIBAL_MERCHANT') || !defined('ZIBAL_API_REQUEST_URL') || !defined('ZIBAL_STARTPAY_URL')) {
        return ['success' => false, 'trackId' => null, 'payment_url' => null, 'message' => 'پیکربندی زیبال ناقص است.'];
    }

    $data = [
        "merchant" => ZIBAL_MERCHANT,
        "amount" => $amount_rial,
        "callbackUrl" => $callback_url,
        "description" => $description,
    ];

    if (!empty($mobile)) {
        $data['mobile'] = $mobile;
    }

    if (!empty($orderId)) {
        $data['orderId'] = (string)$orderId;
    }

    // ویژگی محدودسازی کارت (لیست کارت‌های مجاز)
    if (!empty($allowedCards) && is_array($allowedCards)) {
        $data['allowedCards'] = $allowedCards;
    }

    // ویژگی تطبیق کد ملی (امنیت بیشتر)
    if (!empty($nationalCode)) {
        $data['nationalCode'] = $nationalCode;
    }

    $jsonData = json_encode($data);

    $ch = curl_init(ZIBAL_API_REQUEST_URL);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Zibal Rest Api v1');
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', 'Content-Length: ' . strlen($jsonData)]);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

    $result = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curl_error = curl_error($ch);
    curl_close($ch);

    // Log response for debugging
    if (defined('ERROR_LOG_PATH')) {
        $log_msg = "--- Zibal Request ---\nData: {$jsonData}\nHTTP: {$http_code}\nError: {$curl_error}\nResponse: {$result}\n---\n";
        file_put_contents(ERROR_LOG_PATH, $log_msg, FILE_APPEND);
    }

    if ($curl_error) {
        return ['success' => false, 'trackId' => null, 'payment_url' => null, 'message' => 'خطا در اتصال به زیبال: ' . $curl_error];
    }

    $resultData = json_decode($result, true);

    // Check result code (100 means success)
    if ($http_code == 200 && isset($resultData['result']) && $resultData['result'] == 100 && !empty($resultData['trackId'])) {
        $trackId = $resultData['trackId'];
        $payment_url = ZIBAL_STARTPAY_URL . $trackId;
        return ['success' => true, 'trackId' => $trackId, 'payment_url' => $payment_url, 'message' => 'درخواست پرداخت ایجاد شد.'];
    } else {
        $error_code = $resultData['result'] ?? $http_code;
        $error_message = zibalErrorCodeToMessage($error_code);
        // اگر پیام خطای خاصی از سمت زیبال آمد، آن را هم نمایش بده
        if (!empty($resultData['message'])) {
            $error_message .= " (" . $resultData['message'] . ")";
        }
        return ['success' => false, 'trackId' => null, 'payment_url' => null, 'message' => "خطا از زیبال ({$error_code}): " . $error_message];
    }
}

/**
 * Verifies a Zibal payment transaction.
 *
 * @param int $trackId The trackId received from Zibal callback.
 * @return array Result array with 'success', 'ref_id', 'card_pan', 'message', 'code'.
 */
function verifyZibalPayment(int $trackId): array {
    if (!defined('ZIBAL_MERCHANT') || !defined('ZIBAL_API_VERIFY_URL')) {
        return ['success' => false, 'ref_id' => null, 'card_pan' => null, 'message' => 'پیکربندی تایید زیبال ناقص است.', 'code' => -999];
    }

    $data = [
        "merchant" => ZIBAL_MERCHANT,
        "trackId" => $trackId,
    ];
    $jsonData = json_encode($data);

    $ch = curl_init(ZIBAL_API_VERIFY_URL);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Zibal Rest Api v1');
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
    curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', 'Content-Length: ' . strlen($jsonData)]);
    curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
    curl_setopt($ch, CURLOPT_TIMEOUT, 40);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

    $result = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curl_error = curl_error($ch);
    curl_close($ch);

    if (defined('ERROR_LOG_PATH')) {
        $log_msg = "--- Zibal Verify ---\nData: {$jsonData}\nHTTP: {$http_code}\nError: {$curl_error}\nResponse: {$result}\n---\n";
        file_put_contents(ERROR_LOG_PATH, $log_msg, FILE_APPEND);
    }

    if ($curl_error) {
        return ['success' => false, 'ref_id' => null, 'card_pan' => null, 'message' => 'خطا در اتصال به زیبال برای تایید: ' . $curl_error, 'code' => -998];
    }

    $resultData = json_decode($result, true);
    $zibal_code = $resultData['result'] ?? $http_code;

    // 100: موفق، 201: قبلا تایید شده
    if ($http_code == 200 && isset($resultData['result']) && ($resultData['result'] == 100 || $resultData['result'] == 201)) {
        return [
            'success' => true,
            'ref_id' => $resultData['refNumber'] ?? null,
            'card_pan' => $resultData['cardNumber'] ?? null, // Masked card
            'amount' => $resultData['amount'] ?? 0, // مبلغ تایید شده
            'message' => ($resultData['result'] == 201) ? 'پرداخت قبلا تایید شده است.' : 'پرداخت با موفقیت تایید شد.',
            'code' => (int)$resultData['result']
        ];
    } else {
        $error_message = zibalErrorCodeToMessage($zibal_code);
        return [
            'success' => false,
            'ref_id' => null,
            'card_pan' => null,
            'message' => "خطا در تایید پرداخت ({$zibal_code}): " . $error_message,
            'code' => (int)$zibal_code
        ];
    }
}

/**
 * Translates Zibal error codes to Persian messages.
 */
function zibalErrorCodeToMessage($code): string {
    $code = (int)$code;
    $messages = [
        100 => 'با موفقیت تایید شد.',
        102 => 'merchant یافت نشد.',
        103 => 'merchant غیرفعال',
        104 => 'merchant نامعتبر',
        105 => 'amount بایستی بزرگتر از 1,000 ریال باشد.',
        106 => 'callbackUrl نامعتبر می‌باشد. (شروع با http و یا https)',
        113 => 'مبلغ تراکنش از سقف میزان تراکنش بیشتر است.',
        114 => 'کدملی ارسالی نامعتبر است.',
        201 => 'قبلا تایید شده',
        202 => 'سفارش پرداخت نشده یا ناموفق بوده است.',
        203 => 'trackId نامعتبر می‌باشد.',
        -1 => 'در انتظار پرداخت',
        -2 => 'خطای داخلی',
        1 => 'پرداخت شده - تاییدشده',
        2 => 'پرداخت شده - تاییدنشده',
        3 => 'لغوشده توسط کاربر',
        4 => 'شماره کارت نامعتبر می‌باشد.',
        5 => 'موجودی حساب کافی نمی‌باشد.',
        6 => 'رمز واردشده اشتباه می‌باشد.',
        7 => 'تعداد درخواست‌ها بیش از حد مجاز می‌باشد.',
        8 => 'تعداد پرداخت اینترنتی روزانه بیش از حد مجاز می‌باشد.',
        9 => 'مبلغ پرداخت اینترنتی روزانه بیش از حد مجاز می‌باشد.',
        10 => 'صادرکننده‌ی کارت نامعتبر می‌باشد.',
        11 => 'خطای سوییچ',
        12 => 'کارت قابل دسترسی نمی‌باشد.',
        15 => 'تراکنش استرداد شده',
        21 => 'پذیرنده نامعتبر است'
    ];
    return $messages[$code] ?? "خطای تعریف نشده (کد: {$code})";
}

?>