<?php
session_start();
header('Content-Type: application/json');
require_once 'db.php'; // $conn = PDO

try {
    $user_id = $_SESSION['user_id'] ?? null;
    $session_token = session_id();

    // Get or create cart
    if ($user_id) {
        $stmt = $conn->prepare("SELECT id FROM carts WHERE user_id = :uid LIMIT 1");
        $stmt->execute([':uid' => $user_id]);
    } else {
        $stmt = $conn->prepare("SELECT id FROM carts WHERE session_token = :token LIMIT 1");
        $stmt->execute([':token' => $session_token]);
    }

    $cart = $stmt->fetch(PDO::FETCH_ASSOC);
    if (!$cart) {
        // Create cart (include user_id if available)
        if ($user_id) {
            $stmt = $conn->prepare("INSERT INTO carts (user_id, session_token) VALUES (:uid, :token)");
            $stmt->execute([':uid' => $user_id, ':token' => $session_token]);
        } else {
            $stmt = $conn->prepare("INSERT INTO carts (session_token) VALUES (:token)");
            $stmt->execute([':token' => $session_token]);
        }
        $cart_id = $conn->lastInsertId();
    } else {
        $cart_id = $cart['id'];
    }

    // Helper: get cart summary (total items, total price)
    $getSummary = function($cart_id) use ($conn) {
        $stmt = $conn->prepare("SELECT COALESCE(SUM(qty),0) AS total_items, COALESCE(SUM(qty * price),0) AS total_price FROM cart_items WHERE cart_id = :cid");
        $stmt->execute([':cid' => $cart_id]);
        $s = $stmt->fetch(PDO::FETCH_ASSOC);
        return [
            'total_items' => intval($s['total_items'] ?? 0),
            'total_price' => floatval($s['total_price'] ?? 0)
        ];
    };

    $response = ['success' => true];

    // -------------------
    // 1) check_item (front-end uses this to toggle "In Cart" badge)
    // expects POST: check_item=1, id = product_id
    // -------------------
    if (isset($_POST['check_item'], $_POST['id'])) {
        $pid = intval($_POST['id']);
        $stmt = $conn->prepare("SELECT id, qty FROM cart_items WHERE cart_id = :cid AND product_id = :pid LIMIT 1");
        $stmt->execute([':cid' => $cart_id, ':pid' => $pid]);
        $item = $stmt->fetch(PDO::FETCH_ASSOC);
        $response['in_cart'] = $item ? true : false;
        if ($item) {
            $response['qty'] = intval($item['qty']);
            $response['cart_item_id'] = intval($item['id']);
        }
        $response += $getSummary($cart_id);
        echo json_encode($response);
        exit;
    }

    // -------------------
    // 2) add_item (preserve previous behaviour, but store current price)
    // expects POST: add_item=1, id = product_id
    // -------------------
    if (isset($_POST['add_item'], $_POST['id'])) {
        $pid = intval($_POST['id']);

        // fetch current product price
        $stmt = $conn->prepare("SELECT id, price, name FROM products WHERE id = :id LIMIT 1");
        $stmt->execute([':id' => $pid]);
        $product = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$product) {
            echo json_encode(['success' => false, 'message' => 'Product not found']);
            exit;
        }
        $price = floatval($product['price']);

        // check existing cart item by product_id
        $stmt = $conn->prepare("SELECT id, qty FROM cart_items WHERE cart_id = :cid AND product_id = :pid LIMIT 1");
        $stmt->execute([':cid' => $cart_id, ':pid' => $pid]);
        $item = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($item) {
            // increment qty and refresh price snapshot
            $stmt = $conn->prepare("UPDATE cart_items SET qty = qty + 1, price = :price WHERE id = :id");
            $stmt->execute([':price' => $price, ':id' => $item['id']]);
            $response['cart_item_id'] = intval($item['id']);
            $response['qty'] = intval($item['qty']) + 1;
        } else {
            // insert new cart item with current price snapshot
            $stmt = $conn->prepare("INSERT INTO cart_items (cart_id, product_id, qty, price, created_at) VALUES (:cid, :pid, 1, :price, NOW())");
            $stmt->execute([':cid' => $cart_id, ':pid' => $pid, ':price' => $price]);
            $response['cart_item_id'] = intval($conn->lastInsertId());
            $response['qty'] = 1;
        }

        $response['in_cart'] = true;
        $response['product'] = ['id' => intval($product['id']), 'name' => $product['name'], 'price' => $price];
        $response += $getSummary($cart_id);
        echo json_encode($response);
        exit;
    }

    // -------------------
    // 3) remove_item
    // expects POST: remove_item=1, id = either cart_item_id OR product_id
    //   - this supports both remove-from-listing (product_id) and remove-from-cart (cart_item_id)
    // -------------------
    if (isset($_POST['remove_item'], $_POST['id'])) {
        $id = intval($_POST['id']);

        // first try to interpret id as cart_item id that belongs to this cart
        $stmt = $conn->prepare("SELECT id FROM cart_items WHERE id = :id AND cart_id = :cid LIMIT 1");
        $stmt->execute([':id' => $id, ':cid' => $cart_id]);
        $byCartItem = $stmt->fetch(PDO::FETCH_ASSOC);

        if ($byCartItem) {
            // delete by cart_item id
            $stmt = $conn->prepare("DELETE FROM cart_items WHERE id = :id AND cart_id = :cid");
            $stmt->execute([':id' => $id, ':cid' => $cart_id]);
        } else {
            // assume id is product_id
            $pid = $id;
            $stmt = $conn->prepare("DELETE FROM cart_items WHERE cart_id = :cid AND product_id = :pid");
            $stmt->execute([':cid' => $cart_id, ':pid' => $pid]);
        }

        $response['in_cart'] = false;
        $response += $getSummary($cart_id);
        echo json_encode($response);
        exit;
    }

    // -------------------
    // 4) update_quantity (cart page updates)
    // expects POST: update_quantity=1, id = cart_item_id, quantity = new qty
    // returns new subtotal for that item and updated totals for cart
    // -------------------
    if (isset($_POST['update_quantity'], $_POST['id'], $_POST['quantity'])) {
        $cart_item_id = intval($_POST['id']);
        $quantity = max(1, intval($_POST['quantity']));

        // verify cart_item belongs to this cart and get product_id
        $stmt = $conn->prepare("SELECT product_id FROM cart_items WHERE id = :id AND cart_id = :cid LIMIT 1");
        $stmt->execute([':id' => $cart_item_id, ':cid' => $cart_id]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        if (!$row) {
            echo json_encode(['success' => false, 'message' => 'Cart item not found']);
            exit;
        }

        $product_id = intval($row['product_id']);

        // fetch current product price (use current product price or keep using stored price? we update to current)
        $stmt = $conn->prepare("SELECT price FROM products WHERE id = :pid LIMIT 1");
        $stmt->execute([':pid' => $product_id]);
        $current_price = floatval($stmt->fetchColumn() ?? 0);

        // update cart item qty and price snapshot
        $stmt = $conn->prepare("UPDATE cart_items SET qty = :qty, price = :price WHERE id = :id AND cart_id = :cid");
        $stmt->execute([':qty' => $quantity, ':price' => $current_price, ':id' => $cart_item_id, ':cid' => $cart_id]);

        $subtotal = $quantity * $current_price;
        $summary = $getSummary($cart_id);

        echo json_encode([
            'success' => true,
            'subtotal' => $subtotal,
            'total_items' => $summary['total_items'],
            'total_price' => $summary['total_price']
        ]);
        exit;
    }

    // -------------------
    // 5) clear_cart
    // expects POST: clear_cart=1
    // -------------------
    if (isset($_POST['clear_cart'])) {
        $stmt = $conn->prepare("DELETE FROM cart_items WHERE cart_id = :cid");
        $stmt->execute([':cid' => $cart_id]);

        echo json_encode(['success' => true, 'total_items' => 0, 'total_price' => 0]);
        exit;
    }

    // If no known action, return current totals
    $response += $getSummary($cart_id);
    echo json_encode($response);
    exit;

} catch (PDOException $e) {
    http_response_code(500);
    echo json_encode(['success' => false, 'error' => $e->getMessage()]);
    exit;
}
