<?php
// ============================================================
// backend/api/orders/OrderController.php
// ============================================================

class OrderController {

    private PDO $db;

    public function __construct() {
        $this->db = getDB();
    }

    // POST /orders  — requires auth
    public function create(): void {
        $user  = requireAuth();
        $body  = $GLOBALS['body'];

        $items   = $body['items']       ?? [];
        $address = trim($body['address']    ?? '');
        $phone   = trim($body['phone']      ?? '');
        $ref     = trim($body['payment_ref'] ?? '');

        if (empty($items))   sendError('Order items required', 422);
        if (!$address)        sendError('Delivery address required', 422);
        if (!$phone)          sendError('Phone number required', 422);
        if (!$ref)            sendError('Payment reference required', 422);

        // Verify payment
        $verified = $this->verifyPaystackPayment($ref);
        if (!$verified['status']) sendError('Payment verification failed: ' . $verified['message'], 402);

        // Fetch product prices from DB (never trust client-side prices)
        $ids   = array_column($items, 'product_id');
        $in    = implode(',', array_fill(0, count($ids), '?'));
        $stmt  = $this->db->prepare("SELECT * FROM products WHERE id IN ($in)");
        $stmt->execute($ids);
        $products = [];
        foreach ($stmt->fetchAll() as $p) $products[$p['id']] = $p;

        // Calculate total
        $total = 0;
        foreach ($items as $item) {
            $pid = (int)($item['product_id'] ?? 0);
            $qty = (int)($item['quantity']   ?? 1);
            if (!isset($products[$pid])) sendError("Product #$pid not found", 404);
            if ($products[$pid]['stock'] < $qty) sendError("Not enough stock for: {$products[$pid]['name']}", 409);
            $total += $products[$pid]['price'] * $qty;
        }

        // Begin transaction
        $this->db->beginTransaction();
        try {
            // Create order
            $stmt = $this->db->prepare(
                'INSERT INTO orders (user_id, total, status, payment_ref, address, phone)
                 VALUES (?, ?, "paid", ?, ?, ?)'
            );
            $stmt->execute([$user['id'], $total, $ref, $address, $phone]);
            $orderId = (int) $this->db->lastInsertId();

            // Create order items and decrement stock
            foreach ($items as $item) {
                $pid   = (int)$item['product_id'];
                $qty   = (int)$item['quantity'];
                $price = (float)$products[$pid]['price'];

                $stmt = $this->db->prepare(
                    'INSERT INTO order_items (order_id, product_id, quantity, unit_price) VALUES (?, ?, ?, ?)'
                );
                $stmt->execute([$orderId, $pid, $qty, $price]);

                $stmt = $this->db->prepare('UPDATE products SET stock = stock - ? WHERE id = ?');
                $stmt->execute([$qty, $pid]);
            }

            // Log payment
            $stmt = $this->db->prepare(
                'INSERT INTO payments (user_id, reference, amount, type, related_id, status)
                 VALUES (?, ?, ?, "order", ?, "success")'
            );
            $stmt->execute([$user['id'], $ref, $total, $orderId]);

            $this->db->commit();
            sendSuccess(['order_id' => $orderId, 'total' => $total], 'Order placed successfully', 201);

        } catch (Exception $e) {
            $this->db->rollBack();
            sendError('Order failed: ' . $e->getMessage(), 500);
        }
    }

    // GET /orders/mine  — requires auth
    public function myOrders(): void {
        $user = requireAuth();
        $stmt = $this->db->prepare(
            'SELECT o.*, 
                    (SELECT JSON_ARRAYAGG(
                        JSON_OBJECT(
                            "product_id", oi.product_id,
                            "name", p.name,
                            "quantity", oi.quantity,
                            "unit_price", oi.unit_price
                        )
                    ) FROM order_items oi JOIN products p ON p.id = oi.product_id WHERE oi.order_id = o.id) AS items
             FROM orders o
             WHERE o.user_id = ?
             ORDER BY o.created_at DESC'
        );
        $stmt->execute([$user['id']]);
        $orders = $stmt->fetchAll();
        foreach ($orders as &$order) {
            $order['items'] = json_decode($order['items'], true);
        }
        sendSuccess($orders);
    }

    // GET /orders/{id}  — requires auth, own order only
    public function show(string $id): void {
        $user = requireAuth();
        $stmt = $this->db->prepare(
            'SELECT * FROM orders WHERE id = ? AND user_id = ?'
        );
        $stmt->execute([$id, $user['id']]);
        $order = $stmt->fetch();
        if (!$order) sendError('Order not found', 404);

        $stmt = $this->db->prepare(
            'SELECT oi.*, p.name, p.image FROM order_items oi JOIN products p ON p.id = oi.product_id WHERE oi.order_id = ?'
        );
        $stmt->execute([$order['id']]);
        $order['items'] = $stmt->fetchAll();
        sendSuccess($order);
    }

    // ---- private ----

    private function verifyPaystackPayment(string $reference): array {
        $ch = curl_init("https://api.paystack.co/transaction/verify/$reference");
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HTTPHEADER     => [
                'Authorization: Bearer ' . PAYSTACK_SECRET_KEY,
            ],
        ]);
        $response = curl_exec($ch);
        curl_close($ch);
        $data = json_decode($response, true);
        if (!$data || !$data['status'] || $data['data']['status'] !== 'success') {
            return ['status' => false, 'message' => $data['message'] ?? 'Unknown', 'amount' => 0];
        }
        return ['status' => true, 'message' => 'OK', 'amount' => $data['data']['amount'] / 100];
    }
}
