/**
 * Tap2Order – Kitchen Display System (KDS) JavaScript
 * Auto-refresh, order management, timers, sounds, notifications
 */

(function () {
  'use strict';

  /* ===========================================================
     1. Configuration & State
     =========================================================== */
  const KDS = {
    refreshInterval: (window.KDS_CONFIG && KDS_CONFIG.refreshInterval) || 10000,
    refreshTimer: null,
    timerInterval: null,
    orders: [],
    filters: { type: 'all', sort: 'newest' },
    soundEnabled: (window.KDS_CONFIG && KDS_CONFIG.soundEnabled !== undefined) ? !!KDS_CONFIG.soundEnabled : true,
    notificationsEnabled: false,
    fullscreen: false,
    overdueThreshold: 30 * 60 * 1000,
    audioContext: null,
    urls: {
      orders: (window.KDS_CONFIG && KDS_CONFIG.ajaxOrders) || '/ajax/kitchen_orders.php',
      statusUpdate: (window.KDS_CONFIG && KDS_CONFIG.ajaxAction) || '/ajax/kitchen_action.php',
      print: (window.KDS_CONFIG && KDS_CONFIG.printUrl) || '/ajax/print_order.php'
    }
  };

  /* ===========================================================
     2. Initialization
     =========================================================== */
  document.addEventListener('DOMContentLoaded', () => {
    loadOrders();
    initClock();
    initFilters();
    initFullscreen();
    initSoundSettings();
    startAutoRefresh();
    startTimerUpdates();
    requestNotificationPermission();
    bindActionButtons();
    renderOrders();
    updateOrderCounts();

    // Play initial sound indicator
    console.log('Kitchen Display System initialized');
  });

  /* ===========================================================
     3. Clock Display
     =========================================================== */
  function initClock() {
    const clockEl = document.getElementById('kds-clock');
    if (!clockEl) return;

    function updateClock() {
      const now = new Date();
      clockEl.textContent = now.toLocaleTimeString('en-US', {
        hour: '2-digit',
        minute: '2-digit',
        second: '2-digit',
        hour12: false
      });
    }

    updateClock();
    setInterval(updateClock, 1000);
  }

  /* ===========================================================
     4. Order Loading & Auto-Refresh
     =========================================================== */
  function loadOrders() {
    fetchOrders()
      .then(data => {
        if (data.success && data.orders) {
          var prevCount = KDS.orders.length;
          KDS.orders = data.orders;

          if (KDS.orders.length > prevCount && prevCount > 0) {
            playNewOrderSound();
            showNewOrderBanner(KDS.orders.length - prevCount);
            if (KDS.notificationsEnabled) {
              sendBrowserNotification('New Order', KDS.orders.length - prevCount + ' new order(s) received!');
            }
          }

          renderOrders();
          updateOrderCounts();
        }
      })
      .catch(function(err) {
        console.error('Failed to load orders:', err);
      });
  }

  function fetchOrders() {
    const params = new URLSearchParams();
    if (KDS.filters.type !== 'all') {
      params.append('type', KDS.filters.type);
    }

    const url = KDS.urls.orders + (params.toString() ? '?' + params.toString() : '');

    return fetch(url, {
      headers: {
        'Accept': 'application/json',
        'X-Requested-With': 'XMLHttpRequest'
      },
      credentials: 'same-origin'
    }).then(r => {
      if (!r.ok) throw new Error('Failed to fetch');
      return r.json();
    });
  }

  function startAutoRefresh() {
    stopAutoRefresh();
    KDS.refreshTimer = setInterval(loadOrders, KDS.refreshInterval);
  }

  function stopAutoRefresh() {
    if (KDS.refreshTimer) {
      clearInterval(KDS.refreshTimer);
      KDS.refreshTimer = null;
    }
  }

  /* ===========================================================
     5. Timer Updates (elapsed time display)
     =========================================================== */
  function startTimerUpdates() {
    KDS.timerInterval = setInterval(updateAllTimers, 1000);
  }

  function updateAllTimers() {
    document.querySelectorAll('.kds-card-timer[data-created-at]').forEach(timer => {
      const createdAt = new Date(timer.dataset.createdAt);
      const elapsed = Date.now() - createdAt.getTime();
      const seconds = Math.floor(elapsed / 1000);
      const minutes = Math.floor(seconds / 60);
      const hrs = Math.floor(minutes / 60);
      const mins = minutes % 60;
      const secs = seconds % 60;

      timer.textContent = `${String(hrs).padStart(2, '0')}:${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;

      // Color coding based on elapsed time
      timer.classList.remove('timer-warning', 'timer-danger');
      if (elapsed > KDS.overdueThreshold) {
        timer.classList.add('timer-danger');
        // Add overdue class to the card
        const card = timer.closest('.kds-order-card');
        if (card && !card.classList.contains('overdue')) {
          card.classList.add('overdue');
        }
      } else if (elapsed > KDS.overdueThreshold * 0.7) {
        timer.classList.add('timer-warning');
      }
    });
  }

  function formatElapsed(milliseconds) {
    const seconds = Math.floor(milliseconds / 1000);
    const minutes = Math.floor(seconds / 60);
    const hrs = Math.floor(minutes / 60);
    const mins = minutes % 60;
    const secs = seconds % 60;
    return `${String(hrs).padStart(2, '0')}:${String(mins).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
  }

  /* ===========================================================
     6. Rendering Orders
     =========================================================== */
  function renderOrders() {
    const columns = {
      new: document.getElementById('col-new'),
      preparing: document.getElementById('col-preparing'),
      ready: document.getElementById('col-ready'),
      served: document.getElementById('col-served')
    };

    // Clear existing cards
    Object.values(columns).forEach(col => {
      if (col) col.innerHTML = '';
    });

    // Sort orders
    const sorted = sortOrders(KDS.orders);

    sorted.forEach(order => {
      var status = (order.status || 'new').toLowerCase();
      if (status === 'confirmed') status = 'new';
      var targetCol = columns[status] || columns.new;
      if (!targetCol) return;

      const card = createOrderCard(order);
      targetCol.appendChild(card);
    });

    // Show empty states
    Object.entries(columns).forEach(([status, col]) => {
      if (col && col.children.length === 0) {
        col.innerHTML = `
          <div class="kds-empty">
            <i class="fas ${status === 'new' ? 'fa-bell' : status === 'preparing' ? 'fa-fire' : status === 'ready' ? 'fa-check-circle' : 'fa-clipboard-check'}"></i>
            <p>No ${status} orders</p>
          </div>
        `;
      }
    });

    // Start timers for new elements
    updateAllTimers();
    updateOrderCounts();
  }

  function createOrderCard(order) {
    const card = document.createElement('div');
    card.className = 'kds-order-card';
    card.dataset.orderId = order.id;

    const createdAt = order.created_at || order.timestamp || new Date().toISOString();
    const elapsed = Date.now() - new Date(createdAt).getTime();
    const isOverdue = elapsed > KDS.overdueThreshold;
    if (isOverdue) card.classList.add('overdue');

    const typeClass = (order.order_type || 'dine-in').toLowerCase().replace(/[^a-z]/g, '-');
    const items = order.items || [];

    let itemsHtml = items.map(item => {
      const addons = (item.addons || []).map(a => a.name || a).join(', ');
      const variation = item.variation_name || item.variation || '';
      const note = item.notes || item.special_instructions || '';

      return `
        <div class="kds-item">
          <span class="kds-item-qty">${item.quantity || 1}</span>
          <div>
            <div class="kds-item-name">${escapeHtml(item.name || item.item_name || '')}</div>
            ${variation ? `<div class="kds-item-variation">${escapeHtml(variation)}</div>` : ''}
            ${addons ? `<div class="kds-item-addons">+ ${escapeHtml(addons)}</div>` : ''}
            ${note ? `<div class="kds-item-note"><i class="fas fa-comment-dots"></i> ${escapeHtml(note)}</div>` : ''}
          </div>
        </div>
      `;
    }).join('');

    const tableLabel = order.table_number ? `Table ${order.table_number}` : (order.customer_name || 'N/A');

    card.innerHTML = `
      <div class="kds-card-top">
        <span class="kds-card-order-id">#${order.id || order.order_number || ''}</span>
        <span class="kds-card-order-type ${typeClass}">${order.order_type || 'Dine-in'}</span>
      </div>
      <div class="kds-card-timer" data-created-at="${createdAt}">
        ${formatElapsed(elapsed)}
      </div>
      <div class="kds-card-items">
        ${itemsHtml}
      </div>
      <div class="kds-card-table">
        <i class="fas ${order.order_type === 'takeaway' ? 'fa-shopping-bag' : order.order_type === 'delivery' ? 'fa-motorcycle' : 'fa-utensils'}"></i>
        ${escapeHtml(tableLabel)}
      </div>
      <div class="kds-card-actions">
        ${getActionButtons(order)}
      </div>
    `;

    return card;
  }

  function getActionButtons(order) {
    const status = (order.status || 'new').toLowerCase();

    switch (status) {
      case 'new':
        return `
          <button class="kds-action-btn btn-start" onclick="KitchenApp.updateStatus(${order.id}, 'preparing')">
            <i class="fas fa-fire"></i> Start Preparing
          </button>
          <button class="kds-action-btn btn-bump" onclick="KitchenApp.updateStatus(${order.id}, 'cancelled')">
            <i class="fas fa-times"></i> Cancel
          </button>
        `;
      case 'preparing':
        return `
          <button class="kds-action-btn btn-ready" onclick="KitchenApp.updateStatus(${order.id}, 'ready')">
            <i class="fas fa-check-circle"></i> Mark Ready
          </button>
          <button class="kds-action-btn btn-bump" onclick="KitchenApp.printTicket(${order.id})">
            <i class="fas fa-print"></i> Print
          </button>
        `;
      case 'ready':
        return `
          <button class="kds-action-btn btn-serve" onclick="KitchenApp.updateStatus(${order.id}, 'served')">
            <i class="fas fa-clipboard-check"></i> Mark Served
          </button>
          <button class="kds-action-btn btn-bump" onclick="KitchenApp.printTicket(${order.id})">
            <i class="fas fa-print"></i> Print
          </button>
        `;
      case 'served':
        return `
          <button class="kds-action-btn btn-bump" onclick="KitchenApp.bumpOrder(${order.id})">
            <i class="fas fa-archive"></i> Archive
          </button>
        `;
      default:
        return '';
    }
  }

  /* ===========================================================
     7. Order Status Update
     =========================================================== */
  function updateOrderStatus(orderId, newStatus) {
    var csrfToken = (window.KDS_CONFIG && KDS_CONFIG.csrfToken) || getCsrfToken();
    var params = new URLSearchParams();
    var action = 'update_status';
    if (newStatus === 'preparing') action = 'start_preparing';
    else if (newStatus === 'ready') action = 'mark_ready';
    else if (newStatus === 'served') action = 'mark_served';
    params.append('action', action);
    params.append('order_id', orderId);
    if (newStatus === 'cancelled') {
      params.append('status', 'cancelled');
    }
    params.append('csrf_token', csrfToken);

    fetch(KDS.urls.statusUpdate, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Accept': 'application/json',
        'X-Requested-With': 'XMLHttpRequest'
      },
      credentials: 'same-origin',
      body: params.toString()
    })
      .then(r => r.json())
      .then(data => {
        if (data.success || data.message) {
          // Update local state
          const order = KDS.orders.find(o => o.id === orderId);
          if (order) {
            order.status = newStatus;
          }

          // If status is cancelled or archived, remove from list
          if (['cancelled', 'archived'].includes(newStatus)) {
            KDS.orders = KDS.orders.filter(o => o.id !== orderId);
          }

          renderOrders();

          // Flash effect
          const card = document.querySelector(`.kds-order-card[data-order-id="${orderId}"]`);
          if (card) {
            card.style.animation = 'none';
            card.offsetHeight; // trigger reflow
            card.style.animation = 'fadeInUp 0.3s ease';
          }
        }
      })
      .catch(err => {
        console.error('Failed to update status:', err);
        showToast('Failed to update order status', 'error');
      });
  }

  function bumpOrder(orderId) {
    KDS.orders = KDS.orders.filter(function(o) { return o.id !== orderId; });
    renderOrders();
  }

  /* ===========================================================
     8. Sorting
     =========================================================== */
  function sortOrders(orders) {
    const sorted = [...orders];

    switch (KDS.filters.sort) {
      case 'oldest':
        sorted.sort((a, b) => new Date(a.created_at) - new Date(b.created_at));
        break;
      case 'newest':
        sorted.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
        break;
      case 'table':
        sorted.sort((a, b) => (a.table_number || 0) - (b.table_number || 0));
        break;
      case 'overdue':
        sorted.sort((a, b) => {
          const aTime = Date.now() - new Date(a.created_at).getTime();
          const bTime = Date.now() - new Date(b.created_at).getTime();
          return bTime - aTime;
        });
        break;
      default:
        sorted.sort((a, b) => new Date(a.created_at) - new Date(b.created_at));
    }

    return sorted;
  }

  /* ===========================================================
     9. Filters
     =========================================================== */
  function initFilters() {
    document.querySelectorAll('.filter-btn').forEach(btn => {
      btn.addEventListener('click', function () {
        document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
        this.classList.add('active');
        KDS.filters.type = this.dataset.filter || 'all';
        loadOrders();
      });
    });

    const sortSelect = document.getElementById('sort-select');
    if (sortSelect) {
      sortSelect.addEventListener('change', function () {
        KDS.filters.sort = this.value;
        renderOrders();
      });
    }
  }

  /* ===========================================================
     10. Order Counts
     =========================================================== */
  function updateOrderCounts() {
    var counts = { new: 0, preparing: 0, ready: 0 };

    KDS.orders.forEach(function(order) {
      var status = (order.status || 'new').toLowerCase();
      if (status === 'confirmed') status = 'new';
      if (counts[status] !== undefined) {
        counts[status]++;
      }
    });

    const total = KDS.orders.length;

    // Update column header counts
    Object.entries(counts).forEach(([status, count]) => {
      const countEl = document.querySelector(`#col-${status}`)?.closest('.kds-column')?.querySelector('.column-count');
      if (countEl) countEl.textContent = count;
    });

    // Update topbar count
    const topCount = document.getElementById('total-orders-count');
    if (topCount) topCount.textContent = `${total} order${total !== 1 ? 's' : ''}`;

    // Update page title with count
    document.title = total > 0 ? `(${total}) Kitchen Display - Tap2Order` : 'Kitchen Display - Tap2Order';

    // Badge on favicon if needed
    updateFaviconBadge(total);
  }

  function updateFaviconBadge(count) {
    let badge = document.querySelector('.favicon-badge');
    if (count > 0) {
      if (!badge) {
        const canvas = document.createElement('canvas');
        canvas.width = 32;
        canvas.height = 32;
        const ctx = canvas.getContext('2d');
        ctx.fillStyle = '#e74c3c';
        ctx.beginPath();
        ctx.arc(24, 8, 8, 0, 2 * Math.PI);
        ctx.fill();
        ctx.fillStyle = '#fff';
        ctx.font = 'bold 10px Arial';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        ctx.fillText(count > 9 ? '9+' : count, 24, 8);

        const link = document.createElement('link');
        link.rel = 'icon';
        link.type = 'image/png';
        link.href = canvas.toDataURL();
        link.className = 'favicon-badge';
        document.head.appendChild(link);
      }
    } else if (badge) {
      badge.remove();
    }
  }

  /* ===========================================================
     11. Sound for New Orders
     =========================================================== */
  function playNewOrderSound() {
    if (!KDS.soundEnabled) return;

    try {
      if (!KDS.audioContext) {
        KDS.audioContext = new (window.AudioContext || window.webkitAudioContext)();
      }

      const ctx = KDS.audioContext;
      const oscillator = ctx.createOscillator();
      const gainNode = ctx.createGain();

      oscillator.connect(gainNode);
      gainNode.connect(ctx.destination);

      oscillator.type = 'sine';
      oscillator.frequency.setValueAtTime(880, ctx.currentTime);
      oscillator.frequency.setValueAtTime(660, ctx.currentTime + 0.1);
      oscillator.frequency.setValueAtTime(880, ctx.currentTime + 0.2);

      gainNode.gain.setValueAtTime(0.3, ctx.currentTime);
      gainNode.gain.exponentialRampToValueAtTime(0.01, ctx.currentTime + 0.5);

      oscillator.start(ctx.currentTime);
      oscillator.stop(ctx.currentTime + 0.5);
    } catch (e) {
      // Audio not supported or blocked
    }
  }

  /* ===========================================================
     12. New Order Banner
     =========================================================== */
  function showNewOrderBanner(count) {
    const banner = document.getElementById('new-order-banner');
    if (!banner) return;

    banner.textContent = `🔔 ${count} New Order${count > 1 ? 's' : ''} Received!`;
    banner.classList.add('show');

    setTimeout(() => {
      banner.classList.remove('show');
    }, 4000);
  }

  /* ===========================================================
     13. Browser Notifications
     =========================================================== */
  function requestNotificationPermission() {
    if ('Notification' in window) {
      if (Notification.permission === 'default') {
        Notification.requestPermission().then(permission => {
          KDS.notificationsEnabled = permission === 'granted';
        });
      } else {
        KDS.notificationsEnabled = Notification.permission === 'granted';
      }
    }
  }

  function sendBrowserNotification(title, body) {
    if (!KDS.notificationsEnabled) return;

    try {
      const notification = new Notification(title, {
        body: body,
        icon: '/assets/img/kitchen-icon.png',
        badge: '/assets/img/badge-icon.png',
        tag: 'kds-notification',
        requireInteraction: false,
        silent: false
      });

      notification.onclick = function () {
        window.focus();
        notification.close();
      };

      setTimeout(() => notification.close(), 5000);
    } catch (e) {
      // Notifications not supported
    }
  }

  /* ===========================================================
     14. Print Kitchen Ticket
     =========================================================== */
  function printKitchenTicket(orderId) {
    var csrfToken = (window.KDS_CONFIG && KDS_CONFIG.csrfToken) || getCsrfToken();
    var params = new URLSearchParams();
    params.append('order_id', orderId);
    params.append('type', 'kitchen_ticket');
    params.append('csrf_token', csrfToken);

    fetch(KDS.urls.print, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Accept': 'application/json',
        'X-Requested-With': 'XMLHttpRequest'
      },
      credentials: 'same-origin',
      body: params.toString()
    })
      .then(function(r) { return r.json(); })
      .then(function(data) {
        if (data.success && data.html) {
          var printWindow = window.open('', '_blank', 'width=400,height=600');
          if (printWindow) {
            printWindow.document.write(data.html);
            printWindow.document.close();
            printWindow.focus();
            setTimeout(function() {
              printWindow.print();
              printWindow.close();
            }, 500);
          }
        } else {
          showToast('Failed to generate print data', 'error');
        }
      })
      .catch(function(err) {
        console.error('Print error:', err);
        showToast('Failed to print', 'error');
      });
  }

  /* ===========================================================
     15. Fullscreen Toggle
     =========================================================== */
  function initFullscreen() {
    const btn = document.getElementById('fullscreen-btn');
    if (btn) {
      btn.addEventListener('click', toggleFullscreen);
    }

    document.addEventListener('fullscreenchange', () => {
      KDS.fullscreen = !!document.fullscreenElement;
      document.body.classList.toggle('kds-fullscreen', KDS.fullscreen);
      const icon = btn?.querySelector('i');
      if (icon) {
        icon.className = KDS.fullscreen ? 'fas fa-compress' : 'fas fa-expand';
      }
    });
  }

  function toggleFullscreen() {
    if (!document.fullscreenElement) {
      document.documentElement.requestFullscreen().catch(err => {
        console.warn('Fullscreen request failed:', err);
      });
    } else {
      document.exitFullscreen();
    }
  }

  /* ===========================================================
     16. Sound Settings
     =========================================================== */
  function initSoundSettings() {
    const toggle = document.getElementById('sound-toggle');
    if (toggle) {
      toggle.checked = KDS.soundEnabled;
      toggle.addEventListener('change', function () {
        KDS.soundEnabled = this.checked;
        localStorage.setItem('kds_sound', KDS.soundEnabled ? '1' : '0');
      });

      const saved = localStorage.getItem('kds_sound');
      if (saved !== null) {
        KDS.soundEnabled = saved === '1';
        toggle.checked = KDS.soundEnabled;
      }
    }
  }

  /* ===========================================================
     17. Action Button Bindings
     =========================================================== */
  function bindActionButtons() {
    // Refresh button
    document.getElementById('refresh-btn')?.addEventListener('click', () => {
      loadOrders();
      const icon = document.querySelector('#refresh-btn i');
      if (icon) {
        icon.classList.add('fa-spin');
        setTimeout(() => icon.classList.remove('fa-spin'), 1000);
      }
    });
  }

  /* ===========================================================
     18. Utility Functions
     =========================================================== */
  function escapeHtml(str) {
    if (!str) return '';
    const div = document.createElement('div');
    div.textContent = str;
    return div.innerHTML;
  }

  function getCsrfToken() {
    const meta = document.querySelector('meta[name="csrf-token"]');
    return meta ? meta.getAttribute('content') : '';
  }

  function showToast(message, type = 'info') {
    // Simple fallback toast
    const toast = document.createElement('div');
    const colors = { success: '#27ae60', error: '#e74c3c', warning: '#f39c12', info: '#3498db' };
    toast.style.cssText = `position:fixed;top:80px;right:20px;z-index:9999;background:#fff;padding:12px 20px;border-left:4px solid ${colors[type]};border-radius:8px;box-shadow:0 4px 20px rgba(0,0,0,0.15);font-size:14px;animation:toastSlideIn 0.3s ease;`;
    toast.textContent = message;
    document.body.appendChild(toast);
    setTimeout(() => {
      toast.style.opacity = '0';
      toast.style.transition = 'opacity 0.3s ease';
      setTimeout(() => toast.remove(), 300);
    }, 3000);
  }

  /* ===========================================================
     19. Public API
     =========================================================== */
  window.KitchenApp = {
    updateStatus: updateOrderStatus,
    bumpOrder,
    printTicket: printKitchenTicket,
    toggleFullscreen,
    loadOrders,
    getOrders: () => KDS.orders,
    setRefreshInterval(ms) {
      KDS.refreshInterval = ms;
      startAutoRefresh();
    }
  };

})();
