<?php
/**
 * withdraw.php — Initiates a Paystack bank transfer from the user's wallet.
 * Called by withdrawal.php via AJAX POST.
 */
ob_start();
session_start();
include("config/db.php");
include("config/paystack.php");
ob_clean();

header('Content-Type: application/json');

// Auth check
if (!isset($_SESSION['user_id'])) {
    echo json_encode(['success' => false, 'message' => 'Not logged in. Please refresh.']);
    exit;
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    echo json_encode(['success' => false, 'message' => 'Invalid request method.']);
    exit;
}

$user_id        = (int)$_SESSION['user_id'];
$account_number = trim($_POST['account_number'] ?? '');
$bank_code      = trim($_POST['bank_code']      ?? '');
$amount         = (float)($_POST['amount']       ?? 0);

// Validate inputs
if (!$account_number || !$bank_code) {
    echo json_encode(['success' => false, 'message' => 'Bank and account number are required.']);
    exit;
}
if ($amount < 100) {
    echo json_encode(['success' => false, 'message' => 'Minimum withdrawal is ₦100.']);
    exit;
}
if (!defined('PAYSTACK_SECRET') || empty(PAYSTACK_SECRET)) {
    echo json_encode(['success' => false, 'message' => 'Payment config error. Contact support.']);
    exit;
}

// ── 1. Check wallet balance ─────────────────────────────────────────────────
$ws = $conn->prepare("SELECT balance FROM wallets WHERE user_id=?");
$ws->bind_param("i", $user_id);
$ws->execute();
$wallet = $ws->get_result()->fetch_assoc();

if (!$wallet) {
    echo json_encode(['success' => false, 'message' => 'Wallet not found.']);
    exit;
}
if ((float)$wallet['balance'] < $amount) {
    echo json_encode(['success' => false, 'message' => 'Insufficient wallet balance.']);
    exit;
}

// ── 2. Resolve account name first (verify it's valid) ──────────────────────
$verify_url = 'https://api.paystack.co/bank/resolve'
            . '?account_number=' . urlencode($account_number)
            . '&bank_code='      . urlencode($bank_code);

$verify_res = wd_curl_get($verify_url);
$verify     = json_decode($verify_res, true);

if (empty($verify['status']) || empty($verify['data']['account_name'])) {
    $msg = $verify['message'] ?? 'Could not verify account. Check account number and bank.';
    echo json_encode(['success' => false, 'message' => $msg]);
    exit;
}

$account_name = $verify['data']['account_name'];

// ── 3. Create transfer recipient ────────────────────────────────────────────
$recipient_payload = json_encode([
    'type'           => 'nuban',
    'name'           => $account_name,
    'account_number' => $account_number,
    'bank_code'      => $bank_code,
    'currency'       => 'NGN',
]);

$rec_res = wd_curl_post('https://api.paystack.co/transferrecipient', $recipient_payload);
$rec     = json_decode($rec_res, true);

if (empty($rec['status']) || empty($rec['data']['recipient_code'])) {
    $msg = $rec['message'] ?? 'Could not create transfer recipient.';
    echo json_encode(['success' => false, 'message' => $msg]);
    exit;
}

$recipient_code = $rec['data']['recipient_code'];

// ── 4. Generate unique reference ────────────────────────────────────────────
$reference = 'WD_' . $user_id . '_' . time() . '_' . mt_rand(1000, 9999);

// ── 5. Initiate transfer ────────────────────────────────────────────────────
$transfer_payload = json_encode([
    'source'    => 'balance',
    'amount'    => (int)round($amount * 100),   // Paystack uses kobo
    'recipient' => $recipient_code,
    'reason'    => 'Dabil Wallet Withdrawal',
    'reference' => $reference,
]);

$tr_res = wd_curl_post('https://api.paystack.co/transfer', $transfer_payload);
$tr     = json_decode($tr_res, true);

// Log for debugging
@file_put_contents(
    __DIR__ . '/paystack_log.txt',
    date('Y-m-d H:i:s') . " | withdraw | user={$user_id} | amount={$amount} | ref={$reference} | " . $tr_res . "\n",
    FILE_APPEND
);

if (empty($tr['status'])) {
    $msg = $tr['message'] ?? 'Transfer initiation failed.';
    // Common Paystack errors → friendly messages
    if (stripos($msg, 'OTP') !== false || stripos($msg, 'otp') !== false) {
        $msg = 'Transfers require OTP verification on your Paystack dashboard. Please enable transfers in Paystack settings.';
    } elseif (stripos($msg, 'balance') !== false) {
        $msg = 'Insufficient Paystack balance to process transfers. Contact the platform administrator.';
    } elseif (stripos($msg, 'Transfer not enabled') !== false || stripos($msg, 'disabled') !== false) {
        $msg = 'Transfers are not enabled on this Paystack account. Please enable it in your Paystack dashboard under Settings → Transfers.';
    }
    echo json_encode(['success' => false, 'message' => $msg]);
    exit;
}

$transfer_code = $tr['data']['transfer_code'] ?? '';
$tr_status     = $tr['data']['status']        ?? 'pending';

// ── 6. Save withdrawal record ───────────────────────────────────────────────
$conn->begin_transaction();
try {
    // Insert withdrawal (pending — wallet deducted on webhook success)
    $ins = $conn->prepare("
        INSERT INTO withdrawals (user_id, amount, reference, recipient_code, transfer_code, status)
        VALUES (?, ?, ?, ?, ?, 'pending')
    ");
    $ins->bind_param("idsss", $user_id, $amount, $reference, $recipient_code, $transfer_code);
    $ins->execute();

    // Pre-deduct wallet balance (it's reserved; webhook will confirm or reverse)
    $deduct = $conn->prepare("UPDATE wallets SET balance = balance - ? WHERE user_id = ? AND balance >= ?");
    $deduct->bind_param("did", $amount, $user_id, $amount);
    $deduct->execute();

    if ($deduct->affected_rows === 0) {
        throw new Exception('Wallet balance changed. Please try again.');
    }

    // Record wallet transaction
    $wt = $conn->prepare("
        INSERT INTO wallet_transactions (user_id, amount, type, reference, description, status)
        VALUES (?, ?, 'debit', ?, 'Withdrawal to bank account', 'pending')
    ");
    $wt->bind_param("ids", $user_id, $amount, $reference);
    $wt->execute();

    $conn->commit();
} catch (Exception $e) {
    $conn->rollback();
    echo json_encode(['success' => false, 'message' => 'Database error: ' . $e->getMessage()]);
    exit;
}

echo json_encode([
    'success' => true,
    'message' => 'Withdrawal initiated successfully! Your funds will arrive within 0–30 minutes.',
    'reference' => $reference,
]);

// ── cURL helpers ─────────────────────────────────────────────────────────────
function wd_curl_get(string $url): string|false {
    $res = _wd_curl($url, 'GET', null, true);
    if ($res === false) $res = _wd_curl($url, 'GET', null, false);
    return $res;
}

function wd_curl_post(string $url, string $payload): string|false {
    $res = _wd_curl($url, 'POST', $payload, true);
    if ($res === false) $res = _wd_curl($url, 'POST', $payload, false);
    return $res;
}

function _wd_curl(string $url, string $method, ?string $payload, bool $ssl): string|false {
    $ch = curl_init();
    $opts = [
        CURLOPT_URL            => $url,
        CURLOPT_HTTPHEADER     => [
            'Authorization: Bearer ' . PAYSTACK_SECRET,
            'Content-Type: application/json',
            'Accept: application/json',
        ],
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 60,
        CURLOPT_CONNECTTIMEOUT => 15,
        CURLOPT_SSL_VERIFYPEER => $ssl,
        CURLOPT_SSL_VERIFYHOST => $ssl ? 2 : 0,
    ];
    if ($method === 'POST') {
        $opts[CURLOPT_POST]       = true;
        $opts[CURLOPT_POSTFIELDS] = $payload;
    }
    curl_setopt_array($ch, $opts);
    $res = curl_exec($ch);
    $err = curl_errno($ch);
    curl_close($ch);
    return ($err === 0 && $res !== false) ? $res : false;
}
