<?php
/**
 * Payment Callback Handler - FIXED
 * File: payment-callback.php
 * 
 * When customer pays online via Paystack:
 * - Money comes FROM Paystack (not from customer wallet)
 * - We CREDIT the wallets (add money)
 * - NOT debit (we're not taking money from customer wallet)
 */

require_once 'app/Core/init.php';

if (!Auth::check() || Auth::userType() !== 'customer') {
    redirect('auth/login.php');
}

$reference = $_GET['reference'] ?? '';
$gatewayName = $_GET['gateway'] ?? '';

if (!$reference || !$gatewayName || !isset($_SESSION['pending_booking'])) {
    redirect('items.php');
}

$booking = $_SESSION['pending_booking'];

try {
    $db = Database::getInstance();
    $customerModel = new Customer();
    $customer = $customerModel->findByUserId(Auth::user()['id']);
    
    if (!$customer) redirect('items.php');
    
    $paymentModel = new OnlinePayment();
    $existingPayment = $paymentModel->findByReference($reference);
    
    // Check if payment already processed
    if ($existingPayment && $existingPayment['status'] === 'successful') {
        $orderSql = "SELECT order_number FROM orders WHERE id = ?";
        $order = $db->fetch($orderSql, [$existingPayment['order_id']]);
        
        if ($order) {
            unset($_SESSION['pending_booking']);
            redirect("booking-confirmation.php?order={$order['order_number']}");
        }
        
        redirect('customer/bookings.php?success=already_processed');
    }
    
    // Create payment record if doesn't exist
    if (!$existingPayment) {
        $paymentModel->create([
            'customer_id' => $customer['id'],
            'transaction_reference' => $reference,
            'payment_gateway' => $gatewayName,
            'amount' => $booking['total_amount'],
            'status' => 'pending',
            'customer_email' => Auth::user()['email'],
            'metadata' => ['item_id' => $booking['item_id']]
        ]);
    }
    
    // Verify payment with gateway
    $gatewayFactory = PaymentGatewayFactory::getInstance();
    $gateway = $gatewayFactory->getGateway($gatewayName);
    $verification = $gateway->verify($reference);
    
    if (!$verification['success']) {
        $paymentModel->updateStatus($reference, 'failed', [
            'error_message' => $verification['message'] ?? 'Failed'
        ]);
        redirect('items.php?error=payment_failed');
    }
    
    // Verify amount
    if (abs($verification['amount'] - $booking['total_amount']) > 0.01) {
        $paymentModel->updateStatus($reference, 'failed', [
            'error_message' => 'Amount mismatch'
        ]);
        redirect('items.php?error=amount_mismatch');
    }
    
    // BEGIN TRANSACTION
    $db->beginTransaction();
    
    try {
        $orderNumber = 'RNT' . date('YmdHis') . '' . strtoupper(substr(uniqid(), -6));
        
        // Create order
        $db->execute("INSERT INTO orders (
            order_number, customer_id, vendor_id, item_id, 
            start_date, end_date, rental_days, quantity,
            subtotal, security_deposit, platform_fee, total_amount, 
            status, payment_status, rental_completed, security_deposit_status,
            created_at, updated_at
        ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'confirmed', 'paid', 0, 'held', NOW(), NOW())", [
            $orderNumber, $booking['customer_id'], $booking['vendor_id'],
            $booking['item_id'], $booking['start_date'], $booking['end_date'],
            $booking['number_of_days'], $booking['quantity'], $booking['subtotal'],
            $booking['security_deposit'], 0, $booking['total_amount']
        ]);
        
        $orderId = $db->lastInsertId();
        
        if (!$orderId) {
            throw new Exception("Order creation failed");
        }
        
        // Create payment record (for reconciliation)
        $db->execute("INSERT INTO payments (
            order_id, transaction_reference, payment_gateway, 
            amount, payment_type, status, gateway_response, 
            gateway_reference, paid_at, created_at, updated_at
        ) VALUES (?, ?, ?, ?, 'order_payment', 'completed', ?, ?, NOW(), NOW(), NOW())", [
            $orderId, $reference, $gatewayName, $booking['total_amount'],
            json_encode($verification), $verification['reference'] ?? $reference
        ]);
        
        // ========================================
        // NEW WALLET SYSTEM - CREDIT WALLETS
        // ========================================
        
        $walletService = new WalletService();
        $customer_user_id = Auth::getUserId();
        
        // Get vendor user_id
        $vendor_sql = "SELECT user_id FROM vendors WHERE id = ?";
        $vendor = $db->fetch($vendor_sql, [$booking['vendor_id']]);
        
        if (!$vendor) {
            throw new Exception("Vendor not found");
        }
        
        $vendor_user_id = $vendor['user_id'];
        
        // Split payment
        $rental_amount = $booking['subtotal'];
        $security_deposit = $booking['security_deposit'];
        
        // Get customer wallets
        $customer_security_wallet = $walletService->getWallet($customer_user_id, 'security_held');
        $vendor_pending_wallet = $walletService->getWallet($vendor_user_id, 'pending_earnings');
        
        if (!$customer_security_wallet || !$vendor_pending_wallet) {
            throw new Exception("Wallet not found. Please ensure wallet system is initialized.");
        }
        
        // 1. CREDIT customer's security_held wallet with deposit
        $db->execute(
            "UPDATE user_wallets SET balance = balance + ?, updated_at = NOW() WHERE id = ?",
            [$security_deposit, $customer_security_wallet['id']]
        );
        
        // Record transaction for security deposit
        $db->execute(
            "INSERT INTO transactions (
                user_id, from_wallet_id, to_wallet_id, order_id, 
                transaction_type, amount, description, 
                reference, status, created_at
            ) VALUES (?, NULL, ?, ?, 'security_deposit', ?, ?, ?, 'completed', NOW())",
            [
                $customer_user_id, 
                $customer_security_wallet['id'],
                $orderId,
                $security_deposit,
                "Security deposit for order {$orderNumber}",
                $reference
            ]
        );
        
        // 2. CREDIT vendor's pending_earnings wallet with rental amount
        $db->execute(
            "UPDATE user_wallets SET balance = balance + ?, updated_at = NOW() WHERE id = ?",
            [$rental_amount, $vendor_pending_wallet['id']]
        );
        
        // Record transaction for rental payment
        $db->execute(
            "INSERT INTO transactions (
                user_id, from_wallet_id, to_wallet_id, order_id, 
                transaction_type, amount, description, 
                reference, status, created_at
            ) VALUES (?, NULL, ?, ?, 'rental_payment', ?, ?, ?, 'completed', NOW())",
            [
                $vendor_user_id,
                $vendor_pending_wallet['id'],
                $orderId,
                $rental_amount,
                "Rental payment for order {$orderNumber}",
                $reference
            ]
        );
        
        // Update online_payments table
        $paymentModel->updateStatus($reference, 'successful', [
            'order_id' => $orderId,
            'gateway_response' => $verification,
            'gateway_reference' => $verification['reference'] ?? $reference
        ]);
        
        // COMMIT ALL CHANGES
        $db->commit();
        
        // Clear session
        unset($_SESSION['pending_booking']);
        
        // Queue emails
        $_SESSION['send_order_emails'] = [
            'order_id' => $orderId,
            'customer_email' => Auth::user()['email'],
            'vendor_id' => $booking['vendor_id']
        ];
        
        // Success redirect
        redirect("booking-confirmation.php?order={$orderNumber}");
        
    } catch (Exception $e) {
        $db->rollback();
        throw $e;
    }
    
} catch (Exception $e) {
    error_log("Payment callback error: " . $e->getMessage());
    error_log("Stack trace: " . $e->getTraceAsString());
    
    if (isset($paymentModel) && isset($reference)) {
        try {
            $paymentModel->updateStatus($reference, 'failed', [
                'error_message' => $e->getMessage()
            ]);
        } catch (Exception $updateError) {
            error_log("Failed to update payment: " . $updateError->getMessage());
        }
    }
    
    redirect('items.php?error=processing_failed');
}