<?php
/**
 * Withdrawal AJAX Handler — Paystack Transfers
 * Actions: verify_account, get_banks, withdraw
 */
if (session_status() === PHP_SESSION_NONE) session_start();
require_once dirname(__DIR__, 2) . '/include/config.php';

header('Content-Type: application/json; charset=utf-8');

if (!isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== true || empty($_SESSION['user_id'])) {
    echo json_encode(['status' => '0', 'msg' => 'Not authenticated.']); exit();
}

$user_id = (int)$_SESSION['user_id'];
$action  = trim($_POST['action'] ?? '');

$paystack_secret = trim($site_data['paystack_secret_key'] ?? '');
$min_withdraw    = floatval($site_data['withdraw_minimum'] ?? 500);
$withdraw_fee    = floatval($site_data['withdraw_fee'] ?? 50);

if (empty($paystack_secret)) {
    echo json_encode(['status' => '0', 'msg' => 'Withdrawal not available at this time.']); exit();
}

// ── Verify Bank Account ─────────────────────────────────────────
if ($action === 'verify_account') {
    $account_number = trim($_POST['account_number'] ?? '');
    $bank_code      = trim($_POST['bank_code'] ?? '');

    if (empty($account_number) || empty($bank_code)) {
        echo json_encode(['status' => '0', 'msg' => 'Please enter account number and select a bank.']); exit();
    }

    $url = 'https://api.paystack.co/bank/resolve?account_number=' . urlencode($account_number) . '&bank_code=' . urlencode($bank_code);

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $paystack_secret],
        CURLOPT_TIMEOUT        => 20,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => 0,
    ]);
    $response = curl_exec($ch);
    $err = curl_error($ch);
    curl_close($ch);

    if ($err) {
        echo json_encode(['status' => '0', 'msg' => 'Could not verify account. Please try again.']); exit();
    }

    $result = json_decode($response, true);
    if (!$result || !isset($result['status']) || $result['status'] !== true) {
        echo json_encode(['status' => '0', 'msg' => $result['message'] ?? 'Account verification failed.']); exit();
    }

    $account_name = $result['data']['account_name'] ?? '';
    echo json_encode(['status' => '1', 'account_name' => $account_name]);
    exit();
}

// ── Get Banks List ──────────────────────────────────────────────
if ($action === 'get_banks') {
    $banks = null;

    $ch = curl_init('https://api.paystack.co/bank?country=nigeria&perPage=100');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $paystack_secret],
        CURLOPT_TIMEOUT        => 10,
        CURLOPT_CONNECTTIMEOUT => 5,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => 0,
    ]);
    $response = curl_exec($ch);
    $err = curl_error($ch);
    curl_close($ch);

    if (!$err) {
        $result = json_decode($response, true);
        if ($result && $result['status'] === true && !empty($result['data'])) {
            $banks = array_map(function($b) {
                return ['name' => $b['name'], 'code' => $b['code']];
            }, $result['data']);
        }
    }

    if (!$banks) {
        $banks = [
            ['name' => 'Access Bank', 'code' => '044'],
            ['name' => 'Citibank Nigeria', 'code' => '023'],
            ['name' => 'Ecobank Nigeria', 'code' => '050'],
            ['name' => 'Fidelity Bank', 'code' => '070'],
            ['name' => 'First Bank of Nigeria', 'code' => '011'],
            ['name' => 'First City Monument Bank', 'code' => '214'],
            ['name' => 'Globus Bank', 'code' => '00103'],
            ['name' => 'Guaranty Trust Bank', 'code' => '058'],
            ['name' => 'Heritage Bank', 'code' => '030'],
            ['name' => 'Keystone Bank', 'code' => '082'],
            ['name' => 'Kuda Bank', 'code' => '50211'],
            ['name' => 'Moniepoint MFB', 'code' => '50515'],
            ['name' => 'OPay', 'code' => '999992'],
            ['name' => 'PalmPay', 'code' => '999991'],
            ['name' => 'Polaris Bank', 'code' => '076'],
            ['name' => 'Providus Bank', 'code' => '101'],
            ['name' => 'Stanbic IBTC Bank', 'code' => '221'],
            ['name' => 'Standard Chartered Bank', 'code' => '068'],
            ['name' => 'Sterling Bank', 'code' => '232'],
            ['name' => 'Titan Trust Bank', 'code' => '102'],
            ['name' => 'Union Bank of Nigeria', 'code' => '032'],
            ['name' => 'United Bank for Africa', 'code' => '033'],
            ['name' => 'Unity Bank', 'code' => '215'],
            ['name' => 'Wema Bank', 'code' => '035'],
            ['name' => 'Zenith Bank', 'code' => '057'],
        ];
    }

    echo json_encode(['status' => '1', 'banks' => $banks]);
    exit();
}

// ── Process Withdrawal ──────────────────────────────────────────
if ($action === 'withdraw') {
    $amount         = floatval($_POST['amount'] ?? 0);
    $account_number = trim($_POST['account_number'] ?? '');
    $bank_code      = trim($_POST['bank_code'] ?? '');
    $account_name   = trim($_POST['account_name'] ?? '');

    if ($amount < $min_withdraw) {
        echo json_encode(['status' => '0', 'msg' => 'Minimum withdrawal is &#8358;' . number_format($min_withdraw, 2)]); exit();
    }
    if (empty($account_number) || empty($bank_code) || empty($account_name)) {
        echo json_encode(['status' => '0', 'msg' => 'Please verify your bank account first.']); exit();
    }

    $total_deduct = $amount + $withdraw_fee;

    // Check balance
    $stmt = $pdo->prepare("SELECT main_balance FROM users WHERE id = :uid");
    $stmt->execute(['uid' => $user_id]);
    $balance = (float)$stmt->fetchColumn();

    if ($balance < $total_deduct) {
        echo json_encode(['status' => '0', 'msg' => 'Insufficient balance. You need &#8358;' . number_format($total_deduct, 2) . ' (including &#8358;' . number_format($withdraw_fee, 2) . ' fee).']); exit();
    }

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

    $ch = curl_init('https://api.paystack.co/transferrecipient');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $recipient_payload,
        CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $paystack_secret, 'Content-Type: application/json'],
        CURLOPT_TIMEOUT        => 20,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => 0,
    ]);
    $response = curl_exec($ch);
    $err = curl_error($ch);
    curl_close($ch);

    if ($err) {
        echo json_encode(['status' => '0', 'msg' => 'Connection error. Please try again.']); exit();
    }

    $result = json_decode($response, true);
    if (!$result || $result['status'] !== true) {
        echo json_encode(['status' => '0', 'msg' => 'Could not create transfer. Please check your account details.']); exit();
    }

    $recipient_code = $result['data']['recipient_code'] ?? '';
    if (empty($recipient_code)) {
        echo json_encode(['status' => '0', 'msg' => 'Transfer setup failed. Please try again.']); exit();
    }

    // Step 2: Initiate transfer
    $transfer_ref = 'WDR_' . strtoupper(uniqid()) . '_' . time();
    $transfer_payload = json_encode([
        'source'    => 'balance',
        'amount'    => (int)($amount * 100),
        'recipient' => $recipient_code,
        'reason'    => 'Wallet withdrawal',
        'reference' => $transfer_ref,
    ]);

    $ch = curl_init('https://api.paystack.co/transfer');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $transfer_payload,
        CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $paystack_secret, 'Content-Type: application/json'],
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => 0,
    ]);
    $response = curl_exec($ch);
    $err = curl_error($ch);
    curl_close($ch);

    if ($err) {
        echo json_encode(['status' => '0', 'msg' => 'Transfer failed. Please try again.']); exit();
    }

    $result = json_decode($response, true);
    error_log('[Withdraw] Transfer response for user ' . $user_id . ': ' . $response);

    if (!$result || $result['status'] !== true) {
        $msg = $result['message'] ?? 'Transfer failed.';
        error_log('[Withdraw] Transfer failed for user ' . $user_id . ': ' . $msg);
        if (stripos($msg, 'balance') !== false) {
            $msg = 'Withdrawal temporarily unavailable. Please try again later.';
        } else {
            $msg = 'Withdrawal failed: ' . $msg;
        }
        echo json_encode(['status' => '0', 'msg' => $msg]); exit();
    }

    $transfer_status = $result['data']['status'] ?? 'pending';
    $transfer_code   = $result['data']['transfer_code'] ?? '';

    // Ensure columns exist (outside transaction - DDL auto-commits)
    try { $pdo->exec("ALTER TABLE transactions ADD COLUMN IF NOT EXISTS transaction_type VARCHAR(30) DEFAULT NULL"); } catch (PDOException $e) {}
    try { $pdo->exec("ALTER TABLE transactions ADD COLUMN IF NOT EXISTS metadata TEXT DEFAULT NULL"); } catch (PDOException $e) {}

    // Step 3: Deduct balance and record transaction
    try {
        $pdo->beginTransaction();

        $upd = $pdo->prepare("UPDATE users SET main_balance = main_balance - :amt WHERE id = :uid AND main_balance >= :amt2");
        $upd->execute(['amt' => $total_deduct, 'uid' => $user_id, 'amt2' => $total_deduct]);

        if ($upd->rowCount() === 0) {
            $pdo->rollBack();
            echo json_encode(['status' => '0', 'msg' => 'Insufficient balance.']); exit();
        }

        $pdo->prepare(
            "INSERT INTO transactions (user_id, transaction_ref, payment_gateway, transaction_type, amount, currency, status, payment_method, gateway_reference, metadata, created_at)
             VALUES (:uid, :ref, 'paystack_transfer', 'withdrawal', :amt, 'NGN', :status, 'bank_transfer', :gref, :meta, NOW())"
        )->execute([
            'uid'    => $user_id,
            'ref'    => $transfer_ref,
            'amt'    => $amount,
            'status' => ($transfer_status === 'success') ? 'successful' : 'pending',
            'gref'   => $transfer_code,
            'meta'   => json_encode(['bank' => $bank_code, 'account' => $account_number, 'name' => $account_name, 'fee' => $withdraw_fee]),
        ]);

        $pdo->commit();

        $new_balance = $balance - $total_deduct;
        echo json_encode([
            'status'      => '1',
            'msg'         => 'Withdrawal of &#8358;' . number_format($amount, 2) . ' initiated successfully! It will arrive shortly.',
            'new_balance' => number_format($new_balance, 2),
        ]);

    } catch (Exception $e) {
        if ($pdo->inTransaction()) $pdo->rollBack();
        error_log('[Withdraw] DB error for user ' . $user_id . ': ' . $e->getMessage());
        echo json_encode(['status' => '0', 'msg' => 'Something went wrong. Please contact support.']);
    }
    exit();
}

// ── Sync withdrawal status from Paystack ────────────────────────
if ($action === 'sync_status') {
    $txn_ref = trim($_POST['reference'] ?? '');
    if (empty($txn_ref)) {
        echo json_encode(['status' => '0', 'msg' => 'Missing reference.']); exit();
    }

    // Verify this belongs to the user
    $stmt = $pdo->prepare("SELECT * FROM transactions WHERE transaction_ref = :ref AND user_id = :uid AND payment_gateway = 'paystack_transfer' LIMIT 1");
    $stmt->execute(['ref' => $txn_ref, 'uid' => $user_id]);
    $txn = $stmt->fetch(PDO::FETCH_ASSOC);

    if (!$txn) {
        echo json_encode(['status' => '0', 'msg' => 'Transaction not found.']); exit();
    }

    // Check with Paystack
    $ch = curl_init('https://api.paystack.co/transfer/verify/' . urlencode($txn_ref));
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . $paystack_secret],
        CURLOPT_TIMEOUT        => 15,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => 0,
    ]);
    $response = curl_exec($ch);
    curl_close($ch);

    $result = json_decode($response, true);
    if ($result && $result['status'] === true && !empty($result['data']['status'])) {
        $ps_status = strtolower($result['data']['status']);
        $new_status = 'pending';
        if ($ps_status === 'success') $new_status = 'successful';
        elseif ($ps_status === 'failed' || $ps_status === 'reversed') $new_status = 'failed';

        if ($new_status !== $txn['status']) {
            $pdo->prepare("UPDATE transactions SET status = :s WHERE id = :id")->execute(['s' => $new_status, 'id' => $txn['id']]);

            // Refund if failed
            if ($new_status === 'failed' && $txn['status'] !== 'failed') {
                $meta = json_decode($txn['metadata'] ?? '{}', true);
                $fee = floatval($meta['fee'] ?? 0);
                $refund = (float)$txn['amount'] + $fee;
                $pdo->prepare("UPDATE users SET main_balance = main_balance + :amt WHERE id = :uid")->execute(['amt' => $refund, 'uid' => $user_id]);
            }
        }

        echo json_encode(['status' => '1', 'new_status' => $new_status, 'msg' => 'Status updated to: ' . $new_status]);
    } else {
        echo json_encode(['status' => '0', 'msg' => 'Could not verify with payment provider.']);
    }
    exit();
}

echo json_encode(['status' => '0', 'msg' => 'Unknown action.']);
