<?php
header('Content-Type: application/json');
$response = ['success' => false, 'message' => 'Gagal memproses permintaan deposit.', 'payment_data' => null, 'paydisini_unique_code' => null];

require_once __DIR__ . '/../../config/config.php';
require_once __DIR__ . '/../../includes/session.php';
require_once __DIR__ . '/../../lib/Auth.php';
require_once __DIR__ . '/../../includes/functions.php';

if (!Auth::isLoggedIn()) {
    http_response_code(401);
    $response['message'] = 'Sesi berakhir.';
    echo json_encode($response);
    exit;
}
if (!isset($pdo) || !$pdo instanceof PDO) {
    http_response_code(500);
    error_log("PDO object not available in request_deposit.php");
    $response['message'] = 'Koneksi database gagal.';
    echo json_encode($response);
    exit;
}
if (!defined('PAYDISINI_API_KEY') || empty(PAYDISINI_API_KEY)) {
    http_response_code(500);
    error_log("PayDisini API Key not defined in config.");
    $response['message'] = 'Konfigurasi payment gateway (API Key) tidak lengkap.';
    echo json_encode($response);
    exit;
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    http_response_code(405);
    $response['message'] = 'Metode request tidak valid.';
    echo json_encode($response);
    exit;
}

try {
    $userId = $_SESSION['user_id'];
    $methodCode = sanitize_input($_POST['method_code'] ?? '');
    $amount = filter_input(INPUT_POST, 'amount', FILTER_VALIDATE_FLOAT);

    if (empty($methodCode)) {
        throw new InvalidArgumentException("Metode pembayaran wajib dipilih.");
    }
    if ($amount === false || $amount <= 0) {
        throw new InvalidArgumentException("Jumlah deposit tidak valid.");
    }

    $pdo->beginTransaction();

    $stmtMethod = $pdo->prepare("SELECT id, name, code, min_deposit, max_deposit, bonus_percentage, rate, type FROM deposit_methods WHERE code = :code AND status = 'active' LIMIT 1");
    $stmtMethod->bindParam(':code', $methodCode);
    $stmtMethod->execute();
    $method = $stmtMethod->fetch(PDO::FETCH_ASSOC);

    if (!$method) {
        throw new InvalidArgumentException("Metode pembayaran tidak valid atau tidak aktif.");
    }
    if ($amount < $method['min_deposit']) {
        throw new InvalidArgumentException("Jumlah deposit minimal adalah Rp " . number_format($method['min_deposit'], 0, ',', '.'));
    }
    if ($method['max_deposit'] !== null && $amount > $method['max_deposit']) {
        throw new InvalidArgumentException("Jumlah deposit maksimal adalah Rp " . number_format($method['max_deposit'], 0, ',', '.'));
    }

    $bonusAmount = round($amount * ($method['bonus_percentage'] / 100), 2);
    $receivedAmount = round(($amount + $bonusAmount) * ($method['rate'] ?? 1), 2);

    $localDepositId = 'INV' . time() . rand(100, 999);
    $paydisiniUniqueCode = substr($localDepositId, 0, 32);

    $paydisiniApiKey = trim(PAYDISINI_API_KEY);
    $paydisiniServiceId = trim($method['code']);
    $paydisiniAmount = (int)$amount;
    $paydisiniMerchantId = 940;
    $paydisiniNote = "Deposit Saldo User ID " . $userId . " Ref: " . $paydisiniUniqueCode;
    $paydisiniValidTime = 3600;
    $paydisiniTypeFee = 2;
    $signatureString = $paydisiniApiKey . $paydisiniUniqueCode . $paydisiniServiceId . $paydisiniAmount . $paydisiniValidTime .'NewTransaction';
    $paydisiniSignature = md5($signatureString);

    $postData = [
        'key' => $paydisiniApiKey,
        'request' => 'new',
        'unique_code' => $paydisiniUniqueCode,
        'service' => $paydisiniServiceId,
        'amount' => $paydisiniAmount,
        'merchant_id' => $paydisiniMerchantId,
        'note' => $paydisiniNote,
        'valid_time' => $paydisiniValidTime,
        'type_fee' => $paydisiniTypeFee,
        'signature' => $paydisiniSignature,
        'payment_guide' => 'TRUE',
        'return_url' => base_url('deposit/invoice/' . $paydisiniUniqueCode)
    ];

    $paydisiniApiUrl = 'https://api.paydisini.co.id/v1/';
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $paydisiniApiUrl);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postData));
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    $apiResultJson = curl_exec($ch);
    $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curlError = curl_error($ch);
    curl_close($ch);

    $apiResponseLog = $apiResultJson ?: $curlError ?: "HTTP: " . $httpCode;

    if ($curlError || $httpCode !== 200) {
        throw new RuntimeException("Gagal menghubungi payment gateway: " . $apiResponseLog);
    }

    $apiResult = json_decode($apiResultJson, true);
    if (json_last_error() !== JSON_ERROR_NONE || !isset($apiResult['success'])) {
        throw new RuntimeException("Respons payment gateway tidak valid: " . $apiResponseLog);
    }
    if ($apiResult['success'] === false) {
        throw new RuntimeException("Payment Gateway: " . ($apiResult['msg'] ?? 'Terjadi kesalahan.'));
    }

    $paydisiniData = $apiResult['data'] ?? null;
    if (!$paydisiniData || !isset($paydisiniData['pay_id'])) {
        throw new RuntimeException("Data transaksi dari payment gateway tidak lengkap.");
    }

    $paydisiniPayId = $paydisiniData['pay_id'];
    $paydisiniUniqueCodeResp = $paydisiniData['unique_code'];
    $status = strtolower($paydisiniData['status'] ?? 'pending');
    $paymentNumber = $paydisiniData['virtual_account'] ?? $paydisiniData['payment_code'] ?? null;
    $qrCodeUrl = $paydisiniData['qrcode_url'] ?? null;
    $checkoutUrl = $paydisiniData['checkout_url_v3'] ?? $paydisiniData['checkout_url'] ?? null;
    $expiredAt = $paydisiniData['expired'] ?? date('Y-m-d H:i:s', strtotime('+' . $paydisiniValidTime . ' seconds'));

    $paymentDetailsForDb = json_encode([
        'paydisini_pay_id' => $paydisiniPayId,
        'unique_code' => $paydisiniUniqueCodeResp,
        'service_name' => $paydisiniData['service_name'] ?? $method['name'],
        'amount_paydisini' => (float)($paydisiniData['amount'] ?? $amount),
        'fee' => (float)($paydisiniData['fee'] ?? 0),
        'balance_received_paydisini' => (float)($paydisiniData['balance'] ?? 0),
        'payment_number' => $paymentNumber,
        'qr_code_url' => $qrCodeUrl,
        'checkout_url' => $checkoutUrl,
        'payment_guide' => $apiResult['payment_guide'] ?? null
    ]);

    $sqlInsert = "INSERT INTO deposits (
                      user_id, deposit_method_id, deposit_id, paydisini_pay_id, paydisini_unique_code,
                      amount, bonus, received_amount, status, payment_details,
                      checkout_url, payment_number, qr_code_url, created_at, updated_at, expired_at
                  ) VALUES (
                      :user_id, :method_id, :deposit_id, :paydisini_pay_id, :paydisini_unique_code,
                      :amount, :bonus, :received, :status, :payment_details,
                      :checkout_url, :payment_number, :qr_code_url, NOW(), NOW(), :expired_at
                  )";
    $stmtInsert = $pdo->prepare($sqlInsert);
    $stmtInsert->bindParam(':user_id', $userId, PDO::PARAM_INT);
    $stmtInsert->bindParam(':method_id', $method['id'], PDO::PARAM_INT);
    $stmtInsert->bindParam(':deposit_id', $localDepositId);
    $stmtInsert->bindParam(':paydisini_pay_id', $paydisiniPayId);
    $stmtInsert->bindParam(':paydisini_unique_code', $paydisiniUniqueCodeResp);
    $stmtInsert->bindParam(':amount', $amount);
    $stmtInsert->bindParam(':bonus', $bonusAmount);
    $stmtInsert->bindParam(':received', $receivedAmount);
    $stmtInsert->bindParam(':status', $status);
    $stmtInsert->bindParam(':payment_details', $paymentDetailsForDb);
    $stmtInsert->bindParam(':checkout_url', $checkoutUrl);
    $stmtInsert->bindParam(':payment_number', $paymentNumber);
    $stmtInsert->bindParam(':qr_code_url', $qrCodeUrl);
    $stmtInsert->bindParam(':expired_at', $expiredAt);

    if (!$stmtInsert->execute()) {
        throw new RuntimeException("Gagal menyimpan data deposit ke database.");
    }

    $pdo->commit();

    $response['success'] = true;
    $response['message'] = $apiResult['msg'] ?? "Permintaan deposit berhasil dibuat.";
    $response['paydisini_unique_code'] = $paydisiniUniqueCodeResp;
    $response['payment_data'] = [
        'type' => $method['type'],
        'service_name' => $paydisiniData['service_name'] ?? $method['name'],
        'amount_to_pay' => (float)($paydisiniData['amount'] ?? $amount),
        'fee' => (float)($paydisiniData['fee'] ?? 0),
        'payment_number' => $paymentNumber,
        'qr_code_url' => $qrCodeUrl,
        'checkout_url' => $checkoutUrl,
        'expired_at' => $expiredAt,
        'payment_guide' => $apiResult['payment_guide'] ?? null
    ];

} catch (InvalidArgumentException $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    http_response_code(400);
    $response['message'] = $e->getMessage();
} catch (RuntimeException $e) {
     if ($pdo->inTransaction()) {
         $pdo->rollBack();
     }
     error_log("AJAX Request Deposit Runtime Error: " . $e->getMessage());
     $response['message'] = $e->getMessage();
     http_response_code(500);
} catch (\PDOException $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    error_log("AJAX Request Deposit DB Error: " . $e->getMessage());
    $response['message'] = "Terjadi kesalahan database saat memproses deposit.";
    http_response_code(500);
} catch (\Throwable $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    error_log("AJAX Request Deposit General Error: " . $e->getMessage());
    $response['message'] = "Terjadi kesalahan internal server.";
    if (defined('DEBUG_MODE') && DEBUG_MODE === true) {
        $response['debug_php'] = $e->getMessage();
    }
    http_response_code(500);
}

echo json_encode($response);
exit;
?>
