const { createApp, ref, computed, onMounted, onUnmounted, watch } = Vue;

// Order Card Component
const OrderCard = {
    props: {
        transaction: { type: Object, required: true },
        itemWidth: { type: Number, default: 220 },
        cardHeight: { type: Number, default: 600 },
        lineSpacing: { type: Number, default: 100 },
        stackHeight: { type: Number, default: 85 }
    },
    emits: ['start-all', 'done-all', 'toggle-item-status'],
    setup(props, { emit }) {
        const columns = ref([]);
        
        const allItemsCooking = computed(() => props.transaction.items.every(item => item.status === 'cooking'));
        const allItemsDone = computed(() => props.transaction.items.every(item => item.status === 'done'));
        
        const cardWidth = computed(() => {
            const columnCount = columns.value.length;
            const gap = 10;
            const padding = 30;
            return (columnCount * props.itemWidth) + ((columnCount - 1) * gap) + padding;
        });
        
        const calculateItemHeight = (item) => {
            const baseHeight = 60; // Base height for an item
            const contentLineHeight = 22 * (props.lineSpacing / 100);
            const padding = 20;
            let contentLines = item.toppings?.length || 0;
            if (item.note) contentLines++;
            return baseHeight + (contentLines * contentLineHeight) + padding;
        };
        
        const distributeItemsIntoColumns = () => {
            const newColumns = [];
            let currentColumn = [];
            let currentHeight = 0;
            const maxColumnHeight = (props.cardHeight - 100) * (props.stackHeight / 100);
            
            props.transaction.items.forEach(item => {
                const itemHeight = calculateItemHeight(item);
                if (currentHeight + itemHeight > maxColumnHeight && currentColumn.length > 0) {
                    newColumns.push([...currentColumn]);
                    currentColumn = [];
                    currentHeight = 0;
                }
                currentColumn.push(item);
                currentHeight += itemHeight + 10; // 10 is gap
            });
            
            if (currentColumn.length > 0) newColumns.push([...currentColumn]);
            columns.value = newColumns;
        };
        
        const handleStartAll = () => emit('start-all', props.transaction.transactionId, allItemsCooking.value ? 'pause' : 'start');
        const handleDoneAll = () => emit('done-all', props.transaction.transactionId, allItemsDone.value ? 'reset' : 'done');
        const handleItemClick = (itemId) => emit('toggle-item-status', itemId);
        
        watch(() => props.transaction.items, distributeItemsIntoColumns, { deep: true });
        watch([() => props.lineSpacing, () => props.stackHeight], distributeItemsIntoColumns);
        
        onMounted(distributeItemsIntoColumns);
        
        return { columns, cardWidth, allItemsCooking, allItemsDone, handleStartAll, handleDoneAll, handleItemClick };
    },
    template: `
        <div class="order-card" :style="{ width: cardWidth + 'px' }">
            <div class="order-card-header">
                <div class="order-card-info">
                    <div class="order-card-table">Meja {{ transaction.tableId }}</div>
                    <div class="order-card-time">{{ formatTime(transaction.orderTime) }}</div>
                    <div class="order-card-waiter">{{ transaction.waiter }}</div>
                </div>
                <div class="order-card-id">{{ transaction.transactionId }}</div>
            </div>
            <div class="order-card-items">
                <div class="order-items-columns">
                    <div v-for="(column, columnIndex) in columns" :key="columnIndex" class="order-column">
                        <div v-for="item in column" :key="item.id" class="order-item" :class="item.status" @click="handleItemClick(item.id)">
                            <div class="item-header">
                                <div class="item-name">{{ item.itemName }}</div>
                                <div class="item-quantity">{{ item.quantity }}x</div>
                            </div>
                            <div class="item-details">
                                <div v-if="item.toppings.length > 0" class="item-toppings">
                                    <div v-for="topping in item.toppings" :key="topping.id" class="topping-item">
                                        <i class="bi bi-plus-circle"></i>
                                        <span>{{ topping.itemName }}</span>
                                        <span class="topping-quantity" v-if="topping.quantity > 1"> ({{ topping.quantity }}x)</span>
                                    </div>
                                </div>
                                <div v-if="item.note" class="item-note">
                                    <i class="bi bi-chat-quote"></i>
                                    <span>{{ item.note }}</span>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
            <div class="order-card-footer">
                <button class="order-card-btn start" :class="{ active: allItemsCooking }" @click="handleStartAll">
                    <i :class="allItemsCooking ? 'bi bi-pause-fill' : 'bi bi-play-fill'"></i>
                    {{ allItemsCooking ? 'Pause' : 'Start' }}
                </button>
                <button class="order-card-btn done" :class="{ active: allItemsDone }" @click="handleDoneAll">
                    <i :class="allItemsDone ? 'bi bi-arrow-clockwise' : 'bi bi-check-lg'"></i>
                    {{ allItemsDone ? 'Reset' : 'Done' }}
                </button>
            </div>
        </div>
    `,
    methods: {
        formatTime(timeString) {
            const date = new Date(timeString);
            return date.toLocaleTimeString('id-ID', { hour: '2-digit', minute: '2-digit' });
        }
    }
};

// Main App
createApp({
    components: { OrderCard },
    setup() {
        // State
        const menuActive = ref(false);
        const showTableSelector = ref(false);
        const selectedTable = ref('');
        const currentKdsId = ref(5);
        const orders = ref([]);
        const autoRefresh = ref(true);
        const refreshInterval = ref(3);
        const soundEnabled = ref(true);
        const notifications = ref([]);
        const globalFilter = ref('all');
        const refreshTimer = ref(null);
        const cardHeight = ref(600);
        
        // POINT 2: State untuk Undo/Redo
        const undoStack = ref([]);
        const redoStack = ref([]);
        const MAX_UNDO_STEPS = 15;

        // POINT 3 & 4: Display settings diubah
        const itemWidthSetting = ref(220);
        const lineSpacingSetting = ref(120);
        const stackHeightSetting = ref(80);
        const itemNameFontSizeSetting = ref(100);
        const itemDetailsFontSizeSetting = ref(100);

        const availableTables = ref(['17f', '17a', '19', '22', 'sofa 15', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10']);
        const statusOptions = ref([{ value: 'all', label: 'Semua' }, { value: 'new', label: 'Baru' }, { value: 'cooking', label: 'Masak' }, { value: 'done', label: 'Selesai' }]);

        const createNotificationSound = () => { /* ... (kode tidak berubah) ... */ };

        const updateCSSVariables = () => {
            document.documentElement.style.setProperty('--item-width', `${itemWidthSetting.value}px`);
            document.documentElement.style.setProperty('--line-spacing', `${lineSpacingSetting.value}%`);
            document.documentElement.style.setProperty('--stack-height', `${stackHeightSetting.value}%`);
            document.documentElement.style.setProperty('--item-name-font-size', `${itemNameFontSizeSetting.value}%`);
            document.documentElement.style.setProperty('--item-details-font-size', `${itemDetailsFontSizeSetting.value}%`);
        };

        const saveSettingsToLocalStorage = () => {
            const settings = {
                itemWidth: itemWidthSetting.value,
                lineSpacing: lineSpacingSetting.value,
                stackHeight: stackHeightSetting.value,
                itemNameFontSize: itemNameFontSizeSetting.value,
                itemDetailsFontSize: itemDetailsFontSizeSetting.value
            };
            localStorage.setItem('kdsDisplaySettings', JSON.stringify(settings));
        };

        const loadSettingsFromLocalStorage = () => {
            const savedSettings = localStorage.getItem('kdsDisplaySettings');
            alert(JSON.stringify(savedSettings));
            if (savedSettings) {
                const settings = JSON.parse(savedSettings);
                itemWidthSetting.value = settings.itemWidth || 220;
                lineSpacingSetting.value = settings.lineSpacing || 120;
                stackHeightSetting.value = settings.stackHeight || 80;
                itemNameFontSizeSetting.value = settings.itemNameFontSize || 100;
                itemDetailsFontSizeSetting.value = settings.itemDetailsFontSize || 100;
            }
        };

        const resetDisplaySettings = () => {
            itemWidthSetting.value = 220;
            lineSpacingSetting.value = 120;
            stackHeightSetting.value = 80;
            itemNameFontSizeSetting.value = 100;
            itemDetailsFontSizeSetting.value = 100;
            addNotification('info', 'Pengaturan tampilan direset ke default');
        };

        const groupedTransactions = computed(() => {
            const filtered = globalFilter.value === 'all' ? orders.value : orders.value.filter(o => o.status === globalFilter.value);
            const tableFiltered = selectedTable.value ? filtered.filter(o => o.table_id === selectedTable.value) : filtered;

            const transactions = {};
            tableFiltered.forEach(order => {
                if (order.item_type !== 'main' || order.parent_uid) return;
                
                if (!transactions[order.transaction_id]) {
                    transactions[order.transaction_id] = {
                        transactionId: order.transaction_id,
                        tableId: order.table_id,
                        waiter: order.waiter,
                        orderTime: order.order_time,
                        items: []
                    };
                }
                const toppings = orders.value
                    .filter(o => o.parent_uid === order.item_uid && (o.item_type === 'topping' || o.item_type === 'paket'))
                    .map(t => ({ id: t.id, itemName: t.item_name, quantity: t.quantity }));
                
                transactions[order.transaction_id].items.push({ ...order, toppings });
            });
            return Object.values(transactions).filter(t => t.items.length > 0);
        });

        const newOrdersCount = computed(() => orders.value.filter(o => o.status === 'new' && o.item_type === 'main').length);
        const cookingOrdersCount = computed(() => orders.value.filter(o => o.status === 'cooking' && o.item_type === 'main').length);
        const doneOrdersCount = computed(() => orders.value.filter(o => o.status === 'done' && o.item_type === 'main').length);
        const filteredOrders = computed(() => orders.value.filter(o => o.status !== 'cleared'));

        // POINT 2: Fungsi untuk Undo/Redo & interaksi DB
        const recordAction = (action) => {
            undoStack.value.push(action);
            if (undoStack.value.length > MAX_UNDO_STEPS) undoStack.value.shift();
            redoStack.value = [];
        };

        const updateItemStatusInDB = async (ids, newStatus) => {
            if (!ids || ids.length === 0) return false;
            const formData = new FormData();
            formData.append('action', 'update_kds_status');
            formData.append('ids', JSON.stringify(ids));
            formData.append('status', newStatus);

            try {
                const response = await fetch('crud.php', { method: 'POST', body: formData });
                const responseData = await response.text();
                if (responseData === "1") {
                    ids.forEach(id => {
                        const item = orders.value.find(o => o.id === id);
                        if (item) item.status = newStatus;
                    });
                    return true;
                }
                addNotification('error', 'Gagal update status di DB');
                return false;
            } catch (error) {
                console.error('Error:', error);
                addNotification('error', 'Kesalahan koneksi');
                return false;
            }
        };

        const toggleItemStatus = async (itemId) => {
            const item = orders.value.find(o => o.id === itemId);
            if (!item) return;
            const oldStatus = item.status;
            const newStatus = oldStatus === 'new' ? 'cooking' : oldStatus === 'cooking' ? 'done' : 'new';
            
            if (await updateItemStatusInDB([itemId], newStatus)) {
                recordAction({ type: 'single_status', items: [{ id: itemId, from: oldStatus, to: newStatus }] });
                addNotification('success', `Status item diperbarui`);
            }
        };

        const processBatchStatusChange = async (transactionId, newStatusProvider) => {
            const itemsToChange = orders.value.filter(o => o.transaction_id === transactionId && o.item_type === 'main');
            const actionItems = itemsToChange.map(item => ({ id: item.id, from: item.status, to: newStatusProvider(item.status) }));
            const ids = actionItems.map(item => item.id);
            const commonNewStatus = actionItems.length > 0 ? actionItems[0].to : null;

            if (await updateItemStatusInDB(ids, commonNewStatus)) {
                recordAction({ type: 'batch_status', items: actionItems });
                addNotification('success', `Status transaksi ${transactionId} diperbarui`);
            }
        };

        const handleStartAll = (transactionId, action) => processBatchStatusChange(transactionId, () => action === 'start' ? 'cooking' : 'new');
        const handleDoneAll = (transactionId, action) => processBatchStatusChange(transactionId, () => action === 'done' ? 'done' : 'new');

        const undo = async () => {
            if (undoStack.value.length === 0) return;
            const lastAction = undoStack.value.pop();
            const idsToUpdate = lastAction.items.map(i => i.id);
            // We need to revert each item to its 'from' state.
            // For simplicity in this implementation, we assume a common 'from' state for batch actions.
            const revertStatus = lastAction.items[0].from;
            
            if (await updateItemStatusInDB(idsToUpdate, revertStatus)) {
                redoStack.value.push(lastAction);
                addNotification('info', 'Aksi dibatalkan (Undo)');
            } else {
                undoStack.value.push(lastAction); // Re-add if failed
            }
        };

        const redo = async () => {
            if (redoStack.value.length === 0) return;
            const lastUndo = redoStack.value.pop();
            const idsToUpdate = lastUndo.items.map(i => i.id);
            const reapplyStatus = lastUndo.items[0].to;

            if (await updateItemStatusInDB(idsToUpdate, reapplyStatus)) {
                undoStack.value.push(lastUndo);
                addNotification('info', 'Aksi diulangi (Redo)');
            } else {
                redoStack.value.push(lastUndo); // Re-add if failed
            }
        };
        
        const clearCompletedOrders = async () => {
            const doneItems = orders.value.filter(order => order.status === 'done');
            if (doneItems.length === 0) {
                addNotification('warning', 'Tidak ada pesanan selesai');
                return;
            }
            const actionItems = doneItems.map(item => ({ id: item.id, from: 'done', to: 'cleared' }));
            const ids = actionItems.map(item => item.id);

            if (await updateItemStatusInDB(ids, 'cleared')) {
                recordAction({ type: 'clear_done', items: actionItems });
                addNotification('success', `${ids.length} item selesai dibersihkan`);
                // Optimistically remove from view
                orders.value = orders.value.filter(o => o.status !== 'cleared');
            }
        };

        const addNotification = (type, message) => {
            const id = Date.now();
            notifications.value.push({ type, message, id });
            setTimeout(() => removeNotification(id), 3000);
        };
        const removeNotification = (id) => {
            const index = notifications.value.findIndex(n => n.id === id);
            if (index > -1) notifications.value.splice(index, 1);
        };
        const getNotificationIcon = (type) => ({ success: 'bi-check-circle-fill', warning: 'bi-exclamation-triangle-fill', error: 'bi-x-circle-fill', info: 'bi-info-circle-fill' }[type] || 'bi-bell-fill');
        const loadOrders = async () => {
            try {
                const sql = `SELECT * FROM kds_orders WHERE kds_id = ${currentKdsId.value} AND status != 'cleared' ORDER BY order_time ASC`;
                const data = await ambil_select('kds_orders', sql);
                const newOrdersData = JSON.parse(data);
                
                const oldOrderIds = new Set(orders.value.map(o => o.id));
                const newIncoming = newOrdersData.filter(o => !oldOrderIds.has(o.id) && o.status === 'new');
                if (newIncoming.length > 0 && soundEnabled.value) {
                    createNotificationSound();
                    addNotification('info', `${newIncoming.length} pesanan baru masuk`);
                }
                orders.value = newOrdersData;
            } catch (error) {
                console.error('Error loading orders:', error);
                addNotification('error', 'Gagal memuat pesanan');
            }
        };
        const startAutoRefresh = () => {
            clearInterval(refreshTimer.value);
            if (autoRefresh.value) {
                refreshTimer.value = setInterval(loadOrders, refreshInterval.value * 1000);
            }
        };
        const getStatusCount = (status) => status === 'all' ? orders.value.filter(o=>o.item_type === 'main').length : orders.value.filter(o => o.status === status && o.item_type === 'main').length;

        watch([itemWidthSetting, lineSpacingSetting, stackHeightSetting, itemNameFontSizeSetting, itemDetailsFontSizeSetting], () => {
            updateCSSVariables();
            saveSettingsToLocalStorage();
        });
        watch([autoRefresh, refreshInterval, currentKdsId], startAutoRefresh, { immediate: true });

        onMounted(() => {
            loadSettingsFromLocalStorage();
            updateCSSVariables();
            loadOrders();
            const statusIndicatorsHeight = 50;
            const containerPadding = 30;
            cardHeight.value = window.innerHeight - statusIndicatorsHeight - containerPadding;
        });
        onUnmounted(() => clearInterval(refreshTimer.value));

        return {
            menuActive, showTableSelector, selectedTable, currentKdsId, orders, autoRefresh, refreshInterval, soundEnabled, notifications, globalFilter, cardHeight, undoStack, redoStack,
            itemWidthSetting, lineSpacingSetting, stackHeightSetting, itemNameFontSizeSetting, itemDetailsFontSizeSetting,
            availableTables, statusOptions,
            groupedTransactions, newOrdersCount, cookingOrdersCount, doneOrdersCount, filteredOrders,
            toggleMenu: () => menuActive.value = !menuActive.value,
            selectTable: (table) => { selectedTable.value = table; showTableSelector.value = false; },
            clearTableFilter: () => selectedTable.value = '',
            setGlobalFilter: (status) => globalFilter.value = status,
            getStatusCount, toggleItemStatus, handleStartAll, handleDoneAll, clearCompletedOrders,
            addNotification, removeNotification, getNotificationIcon, resetDisplaySettings, undo, redo
        };
    }
}).mount('#app');