// static/js/pos-cart.js  (enhanced: per-item +/- and remove, promo codes, wholesale pricing)

let cartDB = null;

// ---------- DB HELPERS ----------

async function getDB() {
    if (cartDB) return cartDB;
    if (!window.swiftposOpenDB) {
        throw new Error("swiftposOpenDB is not defined. Make sure product-cache.js is loaded first.");
    }
    cartDB = await window.swiftposOpenDB();
    return cartDB;
}

async function loadCartFromDB() {
    const db = await getDB();
    return new Promise((resolve) => {
        const txItems = db.transaction("cart_items", "readonly");
        const storeItems = txItems.objectStore("cart_items");
        const itemsReq = storeItems.getAll();
        itemsReq.onsuccess = () => {
            const items = itemsReq.result || [];
            const txTotals = db.transaction("cart_totals", "readonly");
            const storeTotals = txTotals.objectStore("cart_totals");
            const totalsReq = storeTotals.get("current");
            totalsReq.onsuccess = () => {
                const totals = totalsReq.result || {
                    id: "current", subtotal: 0, discount: 0, tax: 0, grandTotal: 0
                };
                resolve({ items, totals });
            };
        };
    });
}

async function saveCartToDB(items, totals) {
    const db = await getDB();
    return new Promise((resolve) => {
        const tx = db.transaction(["cart_items", "cart_totals"], "readwrite");
        const storeItems = tx.objectStore("cart_items");
        const storeTotals = tx.objectStore("cart_totals");
        const clearReq = storeItems.clear();
        clearReq.onsuccess = () => {
            items.forEach((item) => storeItems.put(item));
            storeTotals.put(totals);
            tx.oncomplete = () => resolve();
        };
    });
}

// ---------- PROMO CODE STATE ----------
window._posPromoCode = null;    // active promo code string
window._posPromoDiscount = 0;  // discount amount in currency units

// ---------- CART LOGIC ----------

function resolvePrice(item) {
    // Wholesale pricing: if the current quantity in cart meets the threshold,
    // use wholesale price. This ensures the cart always uses correct price.
    if (item.wholesalePrice && item.wholesaleMinQty > 0 && item.quantity >= item.wholesaleMinQty) {
        return Number(item.wholesalePrice) || 0;
    }
    // Graceful fallback: old cached items may store 'price' instead of 'basePrice'
    return Number(item.basePrice || item.price || 0);
}

function recalcTotals(items) {
    let subtotal = 0;
    items.forEach((item) => {
        item.price = resolvePrice(item);
        subtotal += item.price * item.quantity;
    });

    // Apply promo discount
    let discount = window._posPromoDiscount || 0;
    if (discount > subtotal) discount = subtotal;

    // VAT — reads the same global set by the Classic POS template
    const vatRate = parseFloat(window.swiftposVatRate || 0);
    const tax = parseFloat(((subtotal - discount) * vatRate / 100).toFixed(2));
    const grandTotal = subtotal - discount + tax;
    return { id: "current", subtotal, discount, tax, grandTotal };
}

function renderCartUI(items, totals) {
    const tbody = document.getElementById("cart-items-body");
    const subtotalEl = document.getElementById("cart-subtotal");
    const grandTotalEl = document.getElementById("cart-grand-total");
    const cartPayloadField = document.getElementById("cart-payload-field");
    const discountRowEl = document.getElementById("cart-discount-row");
    const discountAmountEl = document.getElementById("cart-discount-amount");
    const headerTotalEl = document.getElementById("headerTotal");
    const itemCountEl = document.getElementById("itemCount");
    const cartItemCountEl = document.getElementById("cartItemCount");

    const USE_COMMA = window.swiftposUseCommaSeparator || false;
    const SYM = window.swiftposCurrencySymbol || '';

    function fmt(val) {
        let num = Number(val).toFixed(2);
        if (USE_COMMA) {
            let parts = num.split(".");
            parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
            num = parts.join(".");
        }
        return SYM + num;
    }

    if (!tbody) return;

    tbody.innerHTML = "";

    items.forEach((item) => {
        const resolvedPrice = resolvePrice(item);
        const isWholesale = item.wholesalePrice && item.wholesaleMinQty > 0 && item.quantity >= item.wholesaleMinQty;
        const tr = document.createElement("tr");
        tr.dataset.productId = item.productId;
        tr.innerHTML = `
            <td>
                ${item.name}
                ${isWholesale ? '<span class="badge bg-success ms-1 small">Wholesale</span>' : ''}
            </td>
            <td>
                <div class="d-flex align-items-center gap-1">
                    <button type="button" class="btn btn-outline-secondary btn-sm px-2 py-0 cart-qty-btn" data-action="dec" data-product-id="${item.productId}" title="Decrease">−</button>
                    <span class="fw-semibold px-1">${item.quantity}</span>
                    <button type="button" class="btn btn-outline-secondary btn-sm px-2 py-0 cart-qty-btn" data-action="inc" data-product-id="${item.productId}" title="Increase">+</button>
                </div>
            </td>
            <td>${fmt(resolvedPrice)}</td>
            <td>${fmt(resolvedPrice * item.quantity)}</td>
            <td>
                <button type="button" class="btn btn-sm btn-outline-danger px-2 py-0 cart-remove-btn" data-product-id="${item.productId}" title="Remove item">✕</button>
            </td>
        `;
        tbody.appendChild(tr);
    });

    if (subtotalEl) subtotalEl.textContent = fmt(totals.subtotal).replace(SYM, '');
    if (grandTotalEl) grandTotalEl.textContent = fmt(totals.grandTotal).replace(SYM, '');
    if (headerTotalEl) headerTotalEl.textContent = fmt(totals.grandTotal).replace(SYM, '');

    // Tax row (Classic POS has id="cart-tax-amount" in totals panel)
    const taxAmountEl = document.getElementById('cart-tax-amount');
    const taxRowEl = document.getElementById('cart-tax-row');
    if (taxAmountEl) taxAmountEl.textContent = fmt(totals.tax || 0).replace(SYM, '');
    if (taxRowEl) {
        if ((totals.tax || 0) > 0) {
            taxRowEl.classList.remove('d-none');
        } else {
            taxRowEl.classList.add('d-none');
        }
    }

    // Item count badges
    const totalItems = items.reduce((sum, i) => sum + i.quantity, 0);
    if (itemCountEl) itemCountEl.textContent = totalItems;
    if (cartItemCountEl) cartItemCountEl.textContent = totalItems;

    // Discount row
    if (discountRowEl && discountAmountEl) {
        if (totals.discount > 0) {
            discountRowEl.classList.remove('d-none');
            discountAmountEl.textContent = SYM + totals.discount.toFixed(2);
        } else {
            discountRowEl.classList.add('d-none');
        }
    }

    // Payload for form submit
    if (cartPayloadField) {
        cartPayloadField.value = JSON.stringify({
            items,
            totals,
            promo_code: window._posPromoCode || null,
            discount_amount: totals.discount || 0
        });
    }
}

async function addItemToCartFromUI() {
    const dropdown = document.getElementById("product-dropdown");
    const qtyInput = document.getElementById("quantity-input");
    if (!dropdown || !qtyInput) return;

    const productId = parseInt(dropdown.value);
    if (!productId) {
        alert("Please select a product first.");
        return;
    }

    const quantity = parseInt(qtyInput.value || "1");
    if (quantity <= 0) return;

    // Grab full product info from cache to check variants properly
    let allProducts = [];
    if (window.swiftposLoadProducts) allProducts = await window.swiftposLoadProducts();
    const product = allProducts.find(p => p.id === productId);

    if (!product) {
        // Fallback if not found in cache (should be rare)
        return;
    }

    if (product.has_variants && product.variants && product.variants.length > 0 && window.swiftVariantPicker) {
        window.swiftVariantPicker.open(product, async function(chosen) {
            await _coreAddItem(product, chosen, quantity);
        });
    } else {
        await _coreAddItem(product, null, quantity);
    }
}

async function _coreAddItem(product, chosenVariant, quantity) {
    const { items } = await loadCartFromDB();
    
    // Create unique cart Id for variants (e.g., '12-4' = Product 12, Variant 4)
    const cartId = chosenVariant ? (product.id + '-' + chosenVariant.id) : product.id;
    const existing = items.find((i) => i.productId === cartId);

    if (existing) {
        existing.quantity += quantity;
    } else {
        let finalName = product.name;
        let finalPrice = parseFloat(product.price || 0);
        let finalStock = parseInt(product.stock_quantity || 0);

        if (chosenVariant) {
            finalName += ' (' + chosenVariant.display_label + ')';
            finalPrice = parseFloat(chosenVariant.price || parseFloat(product.price || 0));
            finalStock = parseInt(chosenVariant.stock_quantity || 0);
        }

        const wholesalePrice = parseFloat(product.wholesale_price || product.wholesalePrice || "0");
        const wholesaleMinQty = parseInt(product.wholesale_min_quantity || product.wholesaleMinQty || "0");

        items.push({
            id: cartId,
            productId: cartId,
            parentProductId: product.id,
            variantId: chosenVariant ? chosenVariant.id : null,
            name: finalName,
            basePrice: finalPrice,
            wholesalePrice: wholesalePrice,
            wholesaleMinQty: wholesaleMinQty,
            price: finalPrice,  // will be recalculated by resolvePrice
            quantity: quantity,
            stock_quantity: finalStock
        });
    }

    const totals = recalcTotals(items);
    await saveCartToDB(items, totals);
    renderCartUI(items, totals);

    // Reset UI quantity
    const qtyInput = document.getElementById("quantity-input");
    if (qtyInput) qtyInput.value = 1;

    // Reset dropdown visually
    const dropdown = document.getElementById("product-dropdown");
    if (dropdown && window.jQuery && jQuery(dropdown).data('select2')) {
        jQuery(dropdown).val(null).trigger('change');
    } else if (dropdown) {
        dropdown.value = "";
    }
}

async function updateItemQuantity(productId, delta) {
    const pid = parseInt(productId);
    const { items } = await loadCartFromDB();
    const item = items.find((i) => i.productId === pid);
    if (!item) return;

    item.quantity += delta;
    if (item.quantity <= 0) {
        // Remove the item
        const newItems = items.filter((i) => i.productId !== pid);
        const totals = recalcTotals(newItems);
        await saveCartToDB(newItems, totals);
        renderCartUI(newItems, totals);
        return;
    }

    const totals = recalcTotals(items);
    await saveCartToDB(items, totals);
    renderCartUI(items, totals);
}

async function removeItemFromCart(productId) {
    const pid = parseInt(productId);
    const { items } = await loadCartFromDB();
    const newItems = items.filter((i) => i.productId !== pid);
    const totals = recalcTotals(newItems);
    await saveCartToDB(newItems, totals);
    renderCartUI(newItems, totals);
}

async function clearCart() {
    window._posPromoCode = null;
    window._posPromoDiscount = 0;
    const promoInput = document.getElementById('promo-code-input');
    const promoMsg = document.getElementById('promo-message');
    if (promoInput) promoInput.value = '';
    if (promoMsg) { promoMsg.textContent = ''; promoMsg.className = 'small mt-1'; }

    const db = await getDB();
    const items = [];
    const totals = recalcTotals(items);
    await saveCartToDB(items, totals);
    renderCartUI(items, totals);
}

// ---------- PROMO CODE LOGIC ----------

async function applyPromoCode(code) {
    if (!code) return;
    const promoMsg = document.getElementById('promo-message');
    const promoBtn = document.getElementById('apply-promo-btn');

    if (promoMsg) promoMsg.textContent = 'Checking…';

    try {
        const { items } = await loadCartFromDB();
        const currentSubtotal = items.reduce((sum, i) => sum + resolvePrice(i) * i.quantity, 0);

        const url = window.swiftposPromoApiUrl || '/api/promo/validate/';
        const resp = await fetch(url, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRFToken': (document.querySelector('[name=csrfmiddlewaretoken]') || {}).value || ''
            },
            body: JSON.stringify({ code: code, order_total: currentSubtotal })
        });
        const data = await resp.json();

        if (data.valid) {
            const discountAmt = parseFloat(data.discount_amount || 0);

            window._posPromoCode = code;
            window._posPromoDiscount = discountAmt;

            if (promoMsg) {
                promoMsg.textContent = `✓ ${data.message}`;
                promoMsg.className = 'small mt-1 text-success fw-semibold';
            }

            // Re-render cart with discount
            const totals = recalcTotals(items);
            await saveCartToDB(items, totals);
            renderCartUI(items, totals);
        } else {
            window._posPromoCode = null;
            window._posPromoDiscount = 0;
            if (promoMsg) {
                promoMsg.textContent = data.message || 'Invalid promo code.';
                promoMsg.className = 'small mt-1 text-danger';
            }
        }
    } catch (e) {
        if (promoMsg) {
            promoMsg.textContent = 'Network error checking promo.';
            promoMsg.className = 'small mt-1 text-danger';
        }
    }
}

// ---------- INIT / EVENT BINDING ----------

async function initCart() {
    const cartTableBody = document.getElementById("cart-items-body");
    if (!cartTableBody) return;

    // 1. Load existing cart and render — always recalculate totals
    //    so VAT rate changes are immediately reflected
    const { items } = await loadCartFromDB();
    const totals = recalcTotals(items);
    await saveCartToDB(items, totals);
    renderCartUI(items, totals);

    // 2. Add to Cart button
    const addBtn = document.getElementById("add-item-btn");
    if (addBtn) {
        addBtn.addEventListener("click", () => addItemToCartFromUI());
    }

    // 3. Per-item controls (event delegation on tbody)
    cartTableBody.addEventListener("click", (event) => {
        // Remove button
        const removeBtn = event.target.closest(".cart-remove-btn");
        if (removeBtn) {
            removeItemFromCart(removeBtn.dataset.productId);
            return;
        }
        // +/- buttons
        const qtyBtn = event.target.closest(".cart-qty-btn");
        if (qtyBtn) {
            const delta = qtyBtn.dataset.action === 'inc' ? 1 : -1;
            updateItemQuantity(qtyBtn.dataset.productId, delta);
        }
    });

    // 4. Clear Cart button
    const clearBtn = document.getElementById("clear-cart-btn");
    if (clearBtn) {
        clearBtn.addEventListener("click", () => clearCart());
    }

    // 5. Promo code button
    const promoBtn = document.getElementById("apply-promo-btn");
    if (promoBtn) {
        promoBtn.addEventListener("click", () => {
            const code = (document.getElementById("promo-code-input") || {}).value || '';
            applyPromoCode(code.trim().toUpperCase());
        });
    }
    // Also allow Enter key in promo input
    const promoInput = document.getElementById("promo-code-input");
    if (promoInput) {
        promoInput.addEventListener("keydown", (e) => {
            if (e.key === "Enter") {
                e.preventDefault();
                applyPromoCode(promoInput.value.trim().toUpperCase());
            }
        });
    }
}

// Expose API
window.swiftposCart = {
    init: initCart,
    loadCartFromDB,
    saveCartToDB,
    clearCart,
    renderCartUI
};

document.addEventListener("DOMContentLoaded", () => {
    initCart();
});