<?php
/**
 * Cart Template - Server-side cart
 */

if (!defined('ABSPATH')) {
    exit;
}

$checkout_url = \Instinctor\Services\PageService::resolveUrl('checkout');
$shop_url = \Instinctor\Services\PageService::resolveUrl('shop');

// Get current currency
$currency = \Instinctor\Services\CurrencyService::getCurrentCurrency();

// Impulse block settings (if rendered via Impulse page builder)
$impulseSettings = $GLOBALS['instinctor_cart_settings'] ?? null;
$cartTitle   = $impulseSettings ? ($impulseSettings['title'] ?? 'Your Order') : __('Your Order', 'instinctor');
$emptyText   = $impulseSettings ? ($impulseSettings['empty_text'] ?? 'No items yet') : __('No items yet', 'instinctor');
$btnText     = $impulseSettings ? ($impulseSettings['checkout_btn_text']   ?? 'Place order')  : 'Place order';
$btnBg       = $impulseSettings ? ($impulseSettings['checkout_btn_bg']     ?? '#1d2327')   : '#1d2327';
$btnColor    = $impulseSettings ? ($impulseSettings['checkout_btn_color']  ?? '#ffffff')   : '#ffffff';
$btnRadius   = $impulseSettings ? intval($impulseSettings['border_radius'] ?? 4)       : 4;
$btnSize     = 14;

// Simple confirmation mode: "Place order" records no payment/address — it just
// shows an in-page "Order received" with the items and clears the cart. For demo
// / pickup-style restaurants. Off by default so real stores keep normal checkout.
$simpleCheckout = \Instinctor\Core\Config::get('instinctor_simple_checkout', '') ? '1' : '';

// Simple-confirmation copy is config-driven with GENERIC defaults, so non-pizza
// stores never inherit pizza-specific wording. The pizza demo sets its own copy.
$confirmMsg  = \Instinctor\Core\Config::get('instinctor_simple_checkout_message', '') ?: __('Thanks! Your order has been received.', 'instinctor');
$confirmBack = \Instinctor\Core\Config::get('instinctor_simple_checkout_back', '') ?: __('Continue', 'instinctor');

// Cart width: never full-width on desktop. Default 50% (centered). Mobile
// defaults to 100% and is independent of the desktop value (an explicit
// max_width_mobile overrides, else 100%, never inherited) so a 50% desktop
// does not shrink the phone cart. Block renders only; the standalone /cart
// page (no Impulse settings) keeps its 800px default.
$cartHasWidth = is_array($impulseSettings);
$cartDeskW = 50; $cartMobW = 100;
if ($cartHasWidth) {
    if (isset($impulseSettings['max_width']) && $impulseSettings['max_width'] !== '') {
        $cartDeskW = max(1, min(100, intval($impulseSettings['max_width'])));
    }
    if (isset($impulseSettings['max_width_mobile']) && $impulseSettings['max_width_mobile'] !== '') {
        $cartMobW = max(1, min(100, intval($impulseSettings['max_width_mobile'])));
    }
}
?>

<?php if ($cartHasWidth): wp_add_inline_style('instinctor-page-inline', '@media(max-width:767px){.instinctor-cart{max-width:' . (int) $cartMobW . '%!important}}'); endif; ?>
<div class="instinctor-cart"<?php echo $cartHasWidth ? ' style="max-width:' . (int) $cartDeskW . '%"' : ''; ?>>
    <h1><?php echo esc_html($cartTitle); ?></h1>
    
    <div id="instinctor-cart-app">
        <div class="instinctor-loading"><div class="instinctor-spinner"></div></div>
    </div>
</div>

<?php ob_start(); ?>
(function() {
    var IC_CONFIRM = { msg: <?php echo wp_json_encode($confirmMsg); ?>, back: <?php echo wp_json_encode($confirmBack); ?> };
    const apiUrl = (window.instinctorFrontend && window.instinctorFrontend.apiUrl) ? window.instinctorFrontend.apiUrl : '<?php echo esc_js(rest_url('instinctor/v1/')); ?>';
    // Shared addon label cache, populated by loadCart, reused by re-renders
    let cachedAddonLabels = {};
    const nonce = (window.instinctorFrontend && window.instinctorFrontend.nonce) ? window.instinctorFrontend.nonce : '<?php echo esc_js(wp_create_nonce('wp_rest')); ?>';
    const checkoutUrl = '<?php echo esc_js($checkout_url); ?>';
    const shopUrl = '<?php echo esc_js($shop_url); ?>';
    const checkoutBtnText   = '<?php echo esc_js($btnText); ?>';
    const checkoutBtnBg     = '<?php echo esc_js($btnBg); ?>';
    const checkoutBtnColor  = '<?php echo esc_js($btnColor); ?>';
    const checkoutBtnRadius = <?php echo intval($btnRadius); ?>;
    const checkoutBtnSize   = <?php echo intval($btnSize); ?>;
    const simpleCheckout    = '<?php echo esc_js($simpleCheckout); ?>';
    let lastCart = null;

    // Currency settings
    const currencySymbol = '<?php echo esc_js($currency->symbol ?? '$'); ?>';
    const currencyPosition = '<?php echo esc_js($currency->symbol_position ?? 'left'); ?>';
    const exchangeRate = <?php echo floatval($currency->exchange_rate ?? 1); ?>;
    const currencyDecimals = <?php echo intval($currency->decimals ?? 2); ?>;
    const thousandSep = '<?php echo esc_js($currency->thousand_separator ?? ','); ?>';
    const decimalSep = '<?php echo esc_js($currency->decimal_separator ?? '.'); ?>';

    function formatCurrency(amount) {
        // Convert using exchange rate
        let converted = parseFloat(amount) * exchangeRate;
        
        // Format number
        let formatted = converted.toFixed(currencyDecimals);
        let parts = formatted.split('.');
        parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, thousandSep);
        if (parts[1]) {
            formatted = parts[0] + decimalSep + parts[1];
        } else {
            formatted = parts[0];
        }
        
        // Apply symbol position
        switch (currencyPosition) {
            case 'right': return formatted + currencySymbol;
            case 'left_space': return currencySymbol + ' ' + formatted;
            case 'right_space': return formatted + ' ' + currencySymbol;
            default: return currencySymbol + formatted;
        }
    }

    async function loadCart() {
        try {
            const response = await fetch(apiUrl + 'cart', {
                headers: { 'X-WP-Nonce': nonce }
            });
            const data = await response.json();
            const cart = data.data;

            renderCart(cart, {});
        } catch (error) {
            console.error('Failed to load cart:', error);
            document.getElementById('instinctor-cart-app').innerHTML = '<p>Failed to load cart.</p>';
        }
    }

    function renderCart(cart, addonLabels) {
        addonLabels = addonLabels || {};
        lastCart = cart;
        const container = document.getElementById('instinctor-cart-app');
        
        if (!cart || Object.keys(cart.items).length === 0) {
            container.innerHTML = `
                <div class="instinctor-cart-empty">
                    <div class="instinctor-empty-icon">
                        <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5">
                            <circle cx="9" cy="21" r="1"/><circle cx="20" cy="21" r="1"/>
                            <path d="M1 1h4l2.68 13.39a2 2 0 002 1.61h9.72a2 2 0 002-1.61L23 6H6"/>
                        </svg>
                    </div>
                    <h2><?php echo esc_html($emptyText); ?></h2>
                    <p>Add an item to get started.</p>
                    <a href="${shopUrl}" class="instinctor-btn instinctor-btn-primary">Back to menu</a>
                </div>
            `;
            return;
        }

        let itemsHtml = '';
        for (const key in cart.items) {
            const item = cart.items[key];
            const meta = item.meta || {};
            const hasBooking = meta.booking_date && meta.booking_time;

            let bookingInfo = '';
            if (hasBooking) {
                const dateFormatted = new Date(meta.booking_date + 'T00:00:00').toLocaleDateString(undefined, { 
                    weekday: 'short', year: 'numeric', month: 'short', day: 'numeric' 
                });
                bookingInfo = `
                    <div class="instinctor-cart-item-booking" style="font-size: 12px; color: #666; margin-top: 6px; padding: 8px; background: #f5f5f5; border-radius: 4px;">
                        <strong>Appointment:</strong> ${dateFormatted} at ${meta.booking_time}
                        ${meta.booking_note ? `<br><em>Note: ${meta.booking_note}</em>` : ''}
                    </div>
                `;
            }

            // Addon selections, keys are names, values are customer input
            let addonsInfo = '';
            if (meta.addons && typeof meta.addons === 'object' && Object.keys(meta.addons).length > 0) {
                const addonLines = Object.entries(meta.addons).map(([name, val]) => {
                    // Configurator ingredients arrive as numeric keys (0,1,2…) with the
                    // ingredient name as the value — show just the name (no "0: " prefix).
                    // Real add-ons use a label key, so keep "Label: value" for those.
                    const display = /^\d+$/.test(name) ? val : ((val === '1' || val === 1) ? name : (name + ': ' + val));
                    return `<span style="display:inline-block;background:#f0f0f0;border-radius:3px;padding:1px 6px;font-size:11px;color:#555;margin:2px 2px 0 0">${display}</span>`;
                }).join('');
                if (addonLines) addonsInfo = `<div style="margin-top:5px;line-height:1.6">${addonLines}</div>`;
            }
            
            itemsHtml += `
                <div class="instinctor-cart-item" data-key="${key}">
                    ${item.image ? `<div class="instinctor-cart-item-image"><img src="${item.image}" alt=""></div>` : ''}
                    <div class="instinctor-cart-item-details">
                        <div class="instinctor-cart-item-name">${item.name}</div>
                        ${addonsInfo}
                        ${bookingInfo}
                    </div>
                    <div class="instinctor-cart-item-quantity">
                        ${hasBooking ? `<span class="instinctor-qty-value">${item.quantity}</span>` : `
                        <button type="button" class="instinctor-qty-btn" data-action="decrease" data-key="${key}" aria-label="Less">&minus;</button>
                        <span class="instinctor-qty-value">${item.quantity}</span>
                        <button type="button" class="instinctor-qty-btn" data-action="increase" data-key="${key}" aria-label="More">+</button>
                        `}
                    </div>
                    <div class="instinctor-cart-item-total">${formatCurrency(item.price * item.quantity)}</div>
                    <button type="button" class="instinctor-cart-item-remove" data-key="${key}" aria-label="Remove">
                        <svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
                    </button>
                </div>
            `;
        }

        container.innerHTML = `
            <div class="instinctor-cart-items">${itemsHtml}</div>
            <div class="instinctor-cart-footer">
                <div class="instinctor-cart-totals">
                    ${cart.totals.bundle_discount > 0 ? `
                    <div class="instinctor-totals-row instinctor-discount-row">
                        <span>Bundle discount</span>
                        <span class="instinctor-total-amount" style="color:#555">-${formatCurrency(cart.totals.bundle_discount)}</span>
                    </div>` : ''}
                    ${cart.totals.discount > 0 ? `
                    <div class="instinctor-totals-row instinctor-discount-row">
                        <span>${cart.coupon ? 'Coupon (' + cart.coupon.code + ')' : 'Discount'}</span>
                        <span class="instinctor-total-amount" style="color:#555">-${formatCurrency(cart.totals.discount)}</span>
                    </div>` : ''}
                    ${cart.totals.gift_card > 0 ? `
                    <div class="instinctor-totals-row instinctor-discount-row">
                        <span>Gift card</span>
                        <span class="instinctor-total-amount" style="color:#555">-${formatCurrency(cart.totals.gift_card)}</span>
                    </div>` : ''}
                    ${cart.totals.tax > 0 ? `
                    <div class="instinctor-totals-row">
                        <span>Tax</span>
                        <span class="instinctor-total-amount">${formatCurrency(cart.totals.tax)}</span>
                    </div>` : ''}
                    <div class="instinctor-totals-row instinctor-total">
                        <span>Total</span>
                        <span class="instinctor-total-amount">${formatCurrency(cart.totals.total)}</span>
                    </div>
                </div>
                <div class="instinctor-cart-actions">
                    <a href="${shopUrl}" class="instinctor-btn instinctor-btn-secondary">Back to menu</a>
                    ${simpleCheckout
                        ? `<button type="button" class="instinctor-btn instinctor-place-order" style="background:${checkoutBtnBg};color:${checkoutBtnColor};border-radius:${checkoutBtnRadius}px;font-size:${checkoutBtnSize}px;border:none">${checkoutBtnText}</button>`
                        : `<a href="${checkoutUrl}" class="instinctor-btn" style="background:${checkoutBtnBg};color:${checkoutBtnColor};border-radius:${checkoutBtnRadius}px;font-size:${checkoutBtnSize}px">${checkoutBtnText}</a>`}
                </div>
            </div>
        `;

        bindEvents();
    }

    async function updateQuantity(key, change) {
        const item = document.querySelector(`.instinctor-cart-item[data-key="${key}"]`);
        if (!item) return;
        const qtySpan = item.querySelector('.instinctor-qty-value');
        if (!qtySpan) return;
        let newQty = parseInt(qtySpan.textContent) + change;
        
        if (newQty < 1) {
            await removeItem(key);
            return;
        }

        try {
            const response = await fetch(apiUrl + 'cart/update', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-WP-Nonce': nonce
                },
                body: JSON.stringify({ item_key: key, quantity: newQty })
            });
            const data = await response.json();
            const updatedCart = data.data || data.cart;
            if (updatedCart) {
                renderCart(updatedCart, cachedAddonLabels);
                document.dispatchEvent(new CustomEvent('instinctor:cart:updated', { detail: updatedCart }));
            }
        } catch (error) {
            console.error('Failed to update cart:', error);

        }
    }

    async function removeItem(key) {
        try {
            const response = await fetch(apiUrl + 'cart/remove', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-WP-Nonce': nonce
                },
                body: JSON.stringify({ item_key: key })
            });
            const data = await response.json();
            const removedCart = data.data || data.cart;
            renderCart(removedCart, cachedAddonLabels);
            document.dispatchEvent(new CustomEvent('instinctor:cart:updated', { detail: removedCart }));
        } catch (error) {
            console.error('Failed to remove item:', error);
        }
    }

    // Simple confirmation: show the placed order in-page (real items, no payment),
    // then empty the session cart. No DB order / no email — this is the demo path.
    async function placeOrderSimple() {
        const cart = lastCart;
        if (!cart || !cart.items || !Object.keys(cart.items).length) return;
        const container = document.getElementById('instinctor-cart-app');
        let rows = '';
        for (const key in cart.items) {
            const it = cart.items[key];
            rows += `<div class="instinctor-confirm-row"><span>${it.name}${it.quantity > 1 ? ' × ' + it.quantity : ''}</span><span>${formatCurrency(it.price * it.quantity)}</span></div>`;
        }
        container.innerHTML = `
            <div class="instinctor-confirm">
                <div class="instinctor-confirm-icon">
                    <svg width="44" height="44" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><polyline points="22 4 12 14.01 9 11.01"/></svg>
                </div>
                <h2>Order received</h2>
                <p>${IC_CONFIRM.msg}</p>
                <div class="instinctor-confirm-items">${rows}
                    <div class="instinctor-confirm-row instinctor-confirm-total"><span>Total</span><span>${formatCurrency(cart.totals.total)}</span></div>
                </div>
                <a href="${shopUrl || '/pizza/'}" class="instinctor-btn instinctor-btn-primary">${IC_CONFIRM.back}</a>
            </div>`;
        // No cart/clear endpoint — remove each item so the next order starts fresh.
        for (const k of Object.keys(cart.items)) {
            try { await fetch(apiUrl + 'cart/remove', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-WP-Nonce': nonce }, body: JSON.stringify({ item_key: k }) }); } catch (_e) {}
        }
        lastCart = { items: {}, totals: { total: 0 } };
        document.dispatchEvent(new CustomEvent('instinctor:cart:updated', { detail: lastCart }));
    }

    function bindEvents() {
        // Use event delegation on the app container, survives re-renders
        const app = document.getElementById('instinctor-cart-app');
        if (!app || app._boundEvents) return;
        app._boundEvents = true;
        app.addEventListener('click', function(e) {
            const placeBtn = e.target.closest('.instinctor-place-order');
            if (placeBtn) {
                e.preventDefault();
                placeBtn.disabled = true; placeBtn.textContent = 'Placing order...';
                placeOrderSimple();
                return;
            }
            const qtyBtn = e.target.closest('.instinctor-qty-btn');
            if (qtyBtn) {
                const key = qtyBtn.dataset.key;
                const change = qtyBtn.dataset.action === 'increase' ? 1 : -1;
                updateQuantity(key, change);
                return;
            }
            const removeBtn = e.target.closest('.instinctor-cart-item-remove');
            if (removeBtn) {
                removeItem(removeBtn.dataset.key);
            }
        });
    }

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', loadCart);
    } else {
        loadCart();
    }
})();
<?php $_inst_ljs = ob_get_clean(); wp_add_inline_script('instinctor-frontend-js', $_inst_ljs, 'after'); ?>

<?php ob_start(); ?>
.instinctor-cart { width: 100%; max-width: 800px; margin: 0 auto; padding: 32px 20px; box-sizing: border-box; }
.instinctor-cart h1 { font-size: 24px; font-weight: 600; margin: 0 0 24px; }

.instinctor-cart-empty { text-align: center; padding: 60px 20px; }
.instinctor-empty-icon { color: #d2d2d7; margin-bottom: 16px; }
.instinctor-cart-empty h2 { font-size: 18px; font-weight: 600; margin: 0 0 8px; }
.instinctor-cart-empty p { color: #86868b; margin: 0 0 20px; }

.instinctor-cart-item { display: flex; align-items: center; gap: 14px; padding: 14px 0; border-bottom: 1px solid #e8e8ed; }
.instinctor-cart-item-image { width: 56px; height: 56px; flex: 0 0 auto; background: #f5f5f7; border-radius: 8px; overflow: hidden; }
.instinctor-cart-item-image img { width: 100%; height: 100%; object-fit: cover; }
.instinctor-cart-item-details { flex: 1 1 auto; min-width: 0; }
.instinctor-cart-item-name { font-weight: 600; font-size: 15px; }

/* compact pill stepper, sits inline at the end of the row with the line total */
.instinctor-cart-item-quantity { flex: 0 0 auto; display: inline-flex; align-items: center; border: 1px solid #d2d2d7; border-radius: 999px; overflow: hidden; }
.instinctor-qty-btn { width: 28px; height: 28px; border: none; background: #fff; cursor: pointer; font-size: 15px; line-height: 1; color: #1d1d1f; padding: 0; }
.instinctor-qty-btn:hover { background: #f0f0f0; }
.instinctor-qty-value { min-width: 26px; text-align: center; font-size: 14px; font-weight: 500; }

.instinctor-cart-item-total { flex: 0 0 auto; font-weight: 600; font-size: 15px; min-width: 70px; text-align: right; }
.instinctor-cart-item-remove { flex: 0 0 auto; width: 28px; background: none; border: none; cursor: pointer; color: #b0b0b5; padding: 0; display: flex; align-items: center; justify-content: center; }
.instinctor-cart-item-remove:hover { color: #c62828; }

.instinctor-cart-footer { margin-top: 18px; }
/* padding-right clears the 28px remove + 14px gap so the Total amount lines up
   exactly under the item line totals */
.instinctor-cart-totals { padding-right: 42px; margin-bottom: 22px; }
.instinctor-totals-row { display: flex; justify-content: flex-end; gap: 24px; padding: 4px 0; font-size: 14px; color: #1d1d1f; }
.instinctor-totals-row.instinctor-total { font-size: 19px; font-weight: 700; padding-top: 8px; }
.instinctor-total-amount { min-width: 70px; text-align: right; }

.instinctor-cart-actions { display: flex; justify-content: flex-end; gap: 12px; }
.instinctor-btn { display: inline-flex; align-items: center; justify-content: center; height: 46px; padding: 0 28px; font-size: 15px; font-weight: 600; border-radius: 8px; text-decoration: none; cursor: pointer; }
.instinctor-btn-primary { background: #1d1d1f; color: #fff; border: none; }
.instinctor-btn-primary:hover { background: #000; color: #fff; }
.instinctor-btn-secondary { background: #fff; color: #1d1d1f; border: 1px solid #d2d2d7; }
.instinctor-btn-secondary:hover { border-color: #1d1d1f; color: #1d1d1f; }

.instinctor-confirm { text-align: center; padding: 24px 0 8px; }
.instinctor-confirm-icon { color: #2e7d32; margin-bottom: 10px; }
.instinctor-confirm h2 { font-size: 23px; font-weight: 700; margin: 0 0 6px; }
.instinctor-confirm p { color: #86868b; margin: 0 0 22px; font-size: 15px; }
.instinctor-confirm-items { max-width: 420px; margin: 0 auto 24px; text-align: left; background: #f5f5f7; border-radius: 12px; padding: 14px 18px; }
.instinctor-confirm-row { display: flex; justify-content: space-between; gap: 16px; padding: 5px 0; font-size: 14px; color: #1d1d1f; }
.instinctor-confirm-row.instinctor-confirm-total { border-top: 1px solid #d2d2d7; margin-top: 6px; padding-top: 10px; font-weight: 700; font-size: 17px; }

.instinctor-loading { text-align: center; padding: 40px; }
.instinctor-spinner { display: inline-block; width: 24px; height: 24px; border: 2px solid #e8e8ed; border-top-color: #1d1d1f; border-radius: 50%; animation: spin 0.6s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

@media (max-width: 600px) {
    .instinctor-cart { padding: 24px 16px; }
    .instinctor-cart-item { gap: 10px; }
    .instinctor-cart-item-total { min-width: 56px; font-size: 14px; }
    .instinctor-cart-totals { padding-right: 38px; }   /* mobile gap is 10px (10+28) */
    .instinctor-cart-actions { flex-direction: column-reverse; }   /* Place order on top */
    .instinctor-btn { width: 100%; }
}
<?php $_inst_lcss = ob_get_clean(); wp_add_inline_style("instinctor-page-inline", $_inst_lcss); ?>
