<?php

class OrderController {

    // ─── CHECKOUT ─────────────────────────────────────
    public static function checkout(): void {
        $user   = AuthController::requireAuth();
        $userId = $user['id'];
        $body   = getJsonBody();

        $name        = trim($body['name'] ?? '');
        $phone       = trim($body['phone'] ?? '');
        $address     = trim($body['address'] ?? '');
        $city        = trim($body['city'] ?? '');
        $state       = trim($body['state'] ?? '');
        $pincode     = trim($body['pincode'] ?? '');
        $startDate   = trim($body['start_date'] ?? date('Y-m-d'));
        $rentalDays  = max(1, (int)($body['rental_days'] ?? 3));
        $instructions = trim($body['special_instructions'] ?? '');
        $paymentMethod = trim($body['payment_method'] ?? 'cod');

        // ✅ Validation
        $errors = [];
        if (!$name)    $errors['name'] = 'Name required';
        if (!$phone)   $errors['phone'] = 'Phone required';
        if (!$address) $errors['address'] = 'Address required';
        if (!$city)    $errors['city'] = 'City required';
        if (!$pincode) $errors['pincode'] = 'Pincode required';
        if ($errors) sendError('Validation failed', 422, $errors);

        $db = getDb();

        // ✅ Fetch cart
        $stmt = $db->prepare("
            SELECT ci.product_id, ci.quantity,
                   p.price, p.discount_percent, p.stock, p.name
            FROM cart_items ci
            JOIN products p ON p.id = ci.product_id
            WHERE ci.user_id = ?
        ");
        $stmt->bind_param('i', $userId);
        $stmt->execute();
        $items = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
        $stmt->close();

        if (empty($items)) sendError('Cart is empty', 400);

        // ✅ Calculate total
        $total = 0;
        $returnDate = date('Y-m-d', strtotime("$startDate +$rentalDays days"));

        foreach ($items as $item) {
            if ($item['stock'] < $item['quantity']) {
                sendError("Out of stock: {$item['name']}", 409);
            }

            $price = ProductController::effectivePrice(
                (float)$item['price'],
                (int)$item['discount_percent']
            );

            $total += $price * $item['quantity'] * $rentalDays;
        }

        $shipping = "$name, $phone, $address, $city, $state - $pincode";

        // ✅ Create order ONLY (no stock update yet)
        $stmt = $db->prepare("
            INSERT INTO orders 
            (user_id, total_price, status, shipping_address,
             special_instructions, start_date, return_date, rental_days,
             payment_status, created_at)
            VALUES (?, ?, 'Pending', ?, ?, ?, ?, ?, 'Pending', NOW())
        ");
        $stmt->bind_param(
            'idssssi',
            $userId,
            $total,
            $shipping,
            $instructions,
            $startDate,
            $returnDate,
            $rentalDays
        );
        $stmt->execute();
        $orderId = $stmt->insert_id;
        $stmt->close();

        // ✅ Insert order items (NO stock reduce)
        $stmtItem = $db->prepare("
            INSERT INTO order_items (order_id, product_id, product_name, quantity, price)
            VALUES (?, ?, ?, ?, ?)
        ");

        foreach ($items as $item) {
            $price = ProductController::effectivePrice(
                (float)$item['price'],
                (int)$item['discount_percent']
            );

            $stmtItem->bind_param(
                'iisid',
                $orderId,
                $item['product_id'],
                $item['name'],
                $item['quantity'],
                $price
            );
            $stmtItem->execute();
        }

        $stmtItem->close();

        // ─── Razorpay ─────────────────────────────────────
        $razorpayOrder = null;

        if ($paymentMethod === 'razorpay' || $paymentMethod === 'upi') {

            $amount = (int) round($total * 100);

            $ch = curl_init('https://api.razorpay.com/v1/orders');
            curl_setopt_array($ch, [
                CURLOPT_RETURNTRANSFER => true,
                CURLOPT_POST => true,
                CURLOPT_USERPWD => RAZORPAY_KEY_ID . ':' . RAZORPAY_KEY_SECRET,
                CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
                CURLOPT_POSTFIELDS => json_encode([
                    'amount' => $amount,
                    'currency' => 'INR',
                    'receipt' => "order_$orderId"
                ])
            ]);

            $response = curl_exec($ch);
            $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            curl_close($ch);

            if ($httpCode !== 200) {
                sendError('Razorpay order creation failed', 500);
            }

            $razorpayOrder = json_decode($response, true);
            $razorpayOrderId = $razorpayOrder['id'];

            $stmt = $db->prepare("
                UPDATE orders 
                SET payment_method = ?, razorpay_order_id = ?
                WHERE id = ?
            ");
            $stmt->bind_param('ssi', $paymentMethod, $razorpayOrderId, $orderId);
            $stmt->execute();
            $stmt->close();

        } else {
            // COD
            $stmt = $db->prepare("
                UPDATE orders 
                SET payment_status = 'COD', payment_method = ?, status='Confirmed'
                WHERE id = ?
            ");
            $stmt->bind_param('si', $paymentMethod, $orderId);
            $stmt->execute();
            $stmt->close();

            // ✅ For COD → reduce stock + clear cart immediately
            self::finalizeOrder($db, $userId, $orderId);
        }

        sendSuccess([
            'order_id' => $orderId,
            'razorpay_order' => $razorpayOrder,
            'total' => round($total, 2),
        ], 'Checkout successful', 201);
    }

    // ─── VERIFY PAYMENT ─────────────────────────────────
    public static function verifyPayment(): void {
        $user   = AuthController::requireAuth();
        $userId = $user['id'];
        $body   = getJsonBody();

        $orderId    = (int)($body['order_id'] ?? 0);
        $paymentId  = trim($body['razorpay_payment_id'] ?? '');
        $signature  = trim($body['razorpay_signature'] ?? '');

        if (!$orderId || !$paymentId || !$signature) {
            sendError('Missing payment data', 422);
        }

        $db = getDb();

        // Get Razorpay order
        $stmt = $db->prepare("
            SELECT razorpay_order_id 
            FROM orders 
            WHERE id = ? AND user_id = ?
        ");
        $stmt->bind_param('ii', $orderId, $userId);
        $stmt->execute();
        $row = $stmt->get_result()->fetch_assoc();
        $stmt->close();

        if (!$row) sendError('Order not found', 404);

        $dbOrderId = $row['razorpay_order_id'];

        // Verify signature
        $generated = hash_hmac(
            'sha256',
            "$dbOrderId|$paymentId",
            RAZORPAY_KEY_SECRET
        );

        if (!hash_equals($generated, $signature)) {
            sendError('Invalid signature', 400);
        }

        // Update order
        $stmt = $db->prepare("
            UPDATE orders 
            SET payment_status = 'Paid',
                payment_id = ?,
                status = 'Confirmed'
            WHERE id = ? AND user_id = ?
        ");
        $stmt->bind_param('sii', $paymentId, $orderId, $userId);
        $stmt->execute();
        $stmt->close();

        // ✅ AFTER PAYMENT SUCCESS
        self::finalizeOrder($db, $userId, $orderId);

        sendSuccess(null, 'Payment verified');
    }

    // ─── FINAL STEP (COMMON) ────────────────────────────
    private static function finalizeOrder($db, $userId, $orderId): void {

        // Reduce stock
        $stmt = $db->prepare("
            UPDATE products p
            JOIN order_items oi ON p.id = oi.product_id
            SET p.stock = p.stock - oi.quantity
            WHERE oi.order_id = ?
        ");
        $stmt->bind_param('i', $orderId);
        $stmt->execute();
        $stmt->close();

        // Clear cart
        $stmt = $db->prepare("DELETE FROM cart_items WHERE user_id = ?");
        $stmt->bind_param('i', $userId);
        $stmt->execute();
        $stmt->close();
    }



    // ─── GET /api/orders ──────────────────────────────────────────────────────
    public static function listOrders(): void {
        $user   = AuthController::requireAuth();
        $userId = $user['id'];
        $db     = getDb();

        $stmt = $db->prepare(
            "SELECT id, total_price, status, payment_status, rental_days,
                    start_date, return_date, created_at
             FROM orders WHERE user_id = ? ORDER BY created_at DESC"
        );
        $stmt->bind_param('i', $userId);
        $stmt->execute();
        $orders = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
        $stmt->close();

        sendSuccess($orders);
    }

    // ─── GET /api/orders/{id} ─────────────────────────────────────────────────
    public static function orderById(string $id): void {
        $user   = AuthController::requireAuth();
        $userId = $user['id'];
        $db     = getDb();

        $stmt = $db->prepare(
            "SELECT id, total_price, shipping_address, special_instructions,
                    status, payment_status, rental_days, start_date, return_date, created_at
             FROM orders WHERE id = ? AND user_id = ? LIMIT 1"
        );
        $stmt->bind_param('ii', $id, $userId);
        $stmt->execute();
        $order = $stmt->get_result()->fetch_assoc();
        $stmt->close();

        if (!$order) sendError('Order not found', 404);

        // Load order items with product image
        $stmt = $db->prepare(
            "SELECT oi.product_id, oi.product_name, oi.quantity, oi.price,
                    p.images
             FROM order_items oi
             LEFT JOIN products p ON p.id = oi.product_id
             WHERE oi.order_id = ?"
        );
        $stmt->bind_param('i', $id);
        $stmt->execute();
        $order['items'] = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
        $stmt->close();

        sendSuccess($order);
    }

    // ─── POST /api/orders/update-status ───────────────────────────────────────
    public static function updateStatus(): void {
        // In a real app, you would verify if the user has an ADMIN role here.
        // For now, since there's no admin role in the users table, we'll implement the logic.
        $body = getJsonBody();
        $orderId = (int)($body['order_id'] ?? 0);
        $status  = trim($body['status'] ?? '');

        if (!$orderId || !$status) {
            sendError('Order ID and status are required', 422);
        }

        $db = getDb();
        $stmt = $db->prepare("UPDATE orders SET status = ? WHERE id = ?");
        $stmt->bind_param('si', $status, $orderId);
        
        if ($stmt->execute()) {
            $stmt->close();
            sendSuccess(['order_id' => $orderId, 'status' => $status], 'Order status updated successfully');
        } else {
            $stmt->close();
            sendError('Failed to update order status', 500);
        }
    }
}