/**
 * Payfrit HUD - Heads Up Display for Task Management
 *
 * Displays tasks as vertical bars that grow over 60 seconds.
 * Bars flash when they exceed the target time.
 * Workers can tap to view details or long-press to accept.
 */

const HUD = {
  // Configuration
  config: {
    pollInterval: 1000,        // Poll every second for smooth animation
    targetSeconds: 60,         // Target time to accept a task
    apiBaseUrl: '/api/tasks',  // API endpoint
    businessId: parseInt(localStorage.getItem('payfrit_portal_business')) || 0,
  },

  // State
  tasks: [],
  selectedTask: null,
  longPressTimer: null,
  isConnected: true,
  businessName: '',

  // Chat state
  chatTaskId: null,
  chatMessages: [],
  chatPollInterval: null,
  lastMessageId: 0,

  // Category names (will be loaded from API)
  categories: {
    1: { name: 'Orders', color: '#ef4444' },
    2: { name: 'Pickup', color: '#f59e0b' },
    3: { name: 'Delivery', color: '#22c55e' },
    4: { name: 'Support', color: '#3b82f6' },
    5: { name: 'Kitchen', color: '#8b5cf6' },
    6: { name: 'Other', color: '#ec4899' },
  },

  // Initialize
  init() {
    this.updateClock();
    setInterval(() => this.updateClock(), 1000);
    setInterval(() => this.updateBars(), 1000);
    setInterval(() => this.fetchTasks(), 3000);

    // Initial fetch (also gets business name)
    this.fetchTasks();

    // Close overlay on background tap
    document.getElementById('taskOverlay').addEventListener('click', (e) => {
      if (e.target.id === 'taskOverlay') {
        this.closeOverlay();
      }
    });

    // Monitor online/offline status
    window.addEventListener('online', () => {
      console.log('[HUD] Back online');
      this.setConnected(true);
      this.fetchTasks();
    });

    window.addEventListener('offline', () => {
      console.log('[HUD] Went offline');
      this.setConnected(false);
    });

    // Initial connection check
    if (!navigator.onLine) {
      this.setConnected(false);
    }

    console.log('[HUD] Initialized');
  },

  // Update the clock display
  updateClock() {
    const now = new Date();
    const hours = String(now.getHours()).padStart(2, '0');
    const minutes = String(now.getMinutes()).padStart(2, '0');
    const seconds = String(now.getSeconds()).padStart(2, '0');
    document.getElementById('clock').textContent = `${hours}:${minutes}:${seconds}`;
  },

  // Fetch tasks from API
  async fetchTasks() {
    // Check if online before attempting fetch
    if (!navigator.onLine) {
      this.setConnected(false);
      return;
    }

    try {
      const response = await fetch(`${this.config.apiBaseUrl}/listPending.cfm`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ BusinessID: this.config.businessId })
      });

      const data = await response.json();

      if (data.OK) {
        this.tasks = data.TASKS || [];
        this.renderTasks();
        this.setConnected(true);

        // Update business name from response
        if (data.BUSINESS_NAME && !this.businessName) {
          this.businessName = data.BUSINESS_NAME;
          document.getElementById('businessName').textContent = ' - ' + this.businessName;
        }
      } else {
        console.error('[HUD] API error:', data.ERROR);
        this.setConnected(false);
      }
    } catch (err) {
      console.error('[HUD] Fetch error:', err);
      this.setConnected(false);
    }
  },

  // Render task bars
  renderTasks() {
    const container = document.getElementById('taskContainer');
    const emptyState = document.getElementById('emptyState');

    // Show/hide empty state
    if (this.tasks.length === 0) {
      emptyState.style.display = 'block';
    } else {
      emptyState.style.display = 'none';
    }

    // Get existing bar elements
    const existingBars = container.querySelectorAll('.task-bar');
    const existingIds = new Set();
    existingBars.forEach(bar => existingIds.add(parseInt(bar.dataset.taskId)));

    // Get current task IDs
    const currentIds = new Set(this.tasks.map(t => t.TaskID));

    // Remove bars for tasks that no longer exist
    existingBars.forEach(bar => {
      const id = parseInt(bar.dataset.taskId);
      if (!currentIds.has(id)) {
        bar.remove();
      }
    });

    // Add or update bars
    this.tasks.forEach(task => {
      let bar = container.querySelector(`.task-bar[data-task-id="${task.TaskID}"]`);

      if (!bar) {
        bar = this.createTaskBar(task);
        container.appendChild(bar);
      }

      this.updateTaskBar(bar, task);
    });
  },

  // Create a new task bar element
  createTaskBar(task) {
    const bar = document.createElement('div');
    bar.className = 'task-bar';
    bar.dataset.taskId = task.TaskID;
    bar.dataset.category = task.TaskCategoryID || 1;

    // Apply dynamic category color
    const categoryColor = this.getCategoryColor(task);
    bar.style.setProperty('--bar-color', categoryColor);

    bar.innerHTML = `
      <span class="task-time"></span>
      <span class="task-id">#${task.TaskID}</span>
      <span class="task-label">${this.getName(task)}</span>
    `;

    // Touch/click handlers
    bar.addEventListener('mousedown', (e) => this.onBarPress(task, e));
    bar.addEventListener('mouseup', () => this.onBarRelease());
    bar.addEventListener('mouseleave', () => this.onBarRelease());
    bar.addEventListener('touchstart', (e) => this.onBarPress(task, e));
    bar.addEventListener('touchend', () => this.onBarRelease());
    bar.addEventListener('click', () => this.onBarTap(task));

    return bar;
  },

  // Update task bar height and state
  updateTaskBar(bar, task) {
    const elapsed = this.getElapsedSeconds(task.CreatedOn);
    const percentage = Math.min(elapsed / this.config.targetSeconds * 100, 100);

    bar.style.height = `${percentage}%`;

    // Update time display
    const timeEl = bar.querySelector('.task-time');
    if (timeEl) {
      timeEl.textContent = this.formatElapsed(elapsed);
    }

    // Flash if overdue
    if (elapsed >= this.config.targetSeconds) {
      bar.classList.add('flashing');
    } else {
      bar.classList.remove('flashing');
    }
  },

  // Update all bars (called every second)
  updateBars() {
    const bars = document.querySelectorAll('.task-bar');
    bars.forEach(bar => {
      const taskId = parseInt(bar.dataset.taskId);
      const task = this.tasks.find(t => t.TaskID === taskId);
      if (task) {
        this.updateTaskBar(bar, task);
      }
    });
  },

  // Get elapsed seconds since task creation
  getElapsedSeconds(createdOn) {
    if (!createdOn) return 0;
    const created = new Date(createdOn);
    if (isNaN(created.getTime())) return 0;
    const now = new Date();
    return Math.max(0, Math.floor((now - created) / 1000));
  },

  // Format elapsed time as mm:ss
  formatElapsed(seconds) {
    if (isNaN(seconds) || seconds < 0) seconds = 0;
    const mins = Math.floor(seconds / 60);
    const secs = seconds % 60;
    return `${mins}:${String(secs).padStart(2, '0')}`;
  },

  // Get category/task type name - prefer task type for service bell tasks
  getName(task) {
    if (task && task.TaskTypeName && task.TaskTypeName.length > 0) {
      return task.TaskTypeName;
    }
    if (task && task.Name) {
      return task.Name;
    }
    return this.categories[task?.TaskCategoryID]?.name || 'Task';
  },

  // Get task type color from tt_TaskTypes
  getCategoryColor(task) {
    if (task && task.TaskTypeColor && task.TaskTypeColor.length > 0) {
      return task.TaskTypeColor;
    }
    return '#9C27B0'; // Default purple
  },

  // Handle bar press (start long press timer)
  onBarPress(task, e) {
    e.preventDefault();
    this.longPressTimer = setTimeout(() => {
      this.acceptTaskDirect(task);
    }, 800); // 800ms for long press
  },

  // Handle bar release (cancel long press)
  onBarRelease() {
    if (this.longPressTimer) {
      clearTimeout(this.longPressTimer);
      this.longPressTimer = null;
    }
  },

  // Handle bar tap (show details)
  onBarTap(task) {
    if (this.longPressTimer) {
      clearTimeout(this.longPressTimer);
      this.longPressTimer = null;
    }
    this.showDetails(task);
  },

  // Show task details overlay
  showDetails(task) {
    this.selectedTask = task;
    const overlay = document.getElementById('taskOverlay');
    const detail = document.getElementById('taskDetail');

    const elapsed = this.getElapsedSeconds(task.CreatedOn);
    const categoryName = this.getName(task);
    const categoryColor = this.getCategoryColor(task);

    document.getElementById('detailTitle').textContent = task.Title || `Task #${task.TaskID}`;
    document.getElementById('detailCategory').textContent = categoryName;
    document.getElementById('detailCreated').textContent = new Date(task.CreatedOn).toLocaleTimeString();
    document.getElementById('detailWaiting').textContent = this.formatElapsed(elapsed);
    document.getElementById('detailInfo').textContent = task.Details || '-';

    // Show location if available
    const locationRow = document.getElementById('detailLocationRow');
    const locationValue = document.getElementById('detailLocation');
    if (task.ServicePointName && task.ServicePointName.length > 0) {
      locationValue.textContent = task.ServicePointName;
      locationRow.style.display = 'flex';
    } else {
      locationRow.style.display = 'none';
    }

    detail.style.setProperty('--detail-color', categoryColor);
    overlay.classList.add('visible');
  },

  // Close overlay
  closeOverlay() {
    document.getElementById('taskOverlay').classList.remove('visible');
    this.selectedTask = null;
  },

  // Accept task from overlay
  acceptTask() {
    if (this.selectedTask) {
      this.acceptTaskDirect(this.selectedTask);
      this.closeOverlay();
    }
  },

  // Accept task directly (long press or button)
  async acceptTaskDirect(task) {
    console.log('[HUD] Accepting task:', task.TaskID);

    try {
      const response = await fetch(`${this.config.apiBaseUrl}/accept.cfm`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          TaskID: task.TaskID,
          BusinessID: this.config.businessId
        })
      });

      const data = await response.json();

      if (data.OK) {
        // Remove from local list immediately
        this.tasks = this.tasks.filter(t => t.TaskID !== task.TaskID);
        this.renderTasks();
        this.showFeedback('Task accepted!', 'success');

        // If it's a chat task, open the chat modal
        if (this.isChatTask(task)) {
          this.openChat(task);
        }
      } else {
        this.showFeedback(data.ERROR || 'Failed to accept', 'error');
      }
    } catch (err) {
      console.error('[HUD] Accept error:', err);
      this.showFeedback('Failed to accept task', 'error');
    }
  },

  // Show feedback message
  showFeedback(message, type) {
    // Simple console feedback for now
    console.log(`[HUD] ${type}: ${message}`);
    // TODO: Add toast notification
  },

  // Set connection status
  setConnected(connected) {
    this.isConnected = connected;
    const indicator = document.getElementById('statusIndicator');
    if (connected) {
      indicator.classList.remove('disconnected');
    } else {
      indicator.classList.add('disconnected');
    }
  },

  // Check if task is a chat task
  isChatTask(task) {
    if (!task) return false;
    const name = (task.TaskTypeName || task.Title || '').toLowerCase();
    return name.includes('chat');
  },

  // Open chat modal for a task
  openChat(task) {
    this.chatTaskId = task.TaskID;
    this.chatMessages = [];
    this.lastMessageId = 0;

    document.getElementById('chatTitle').textContent = task.Title || 'Chat';
    document.getElementById('chatMessages').innerHTML = '<div class="chat-loading">Loading messages...</div>';
    document.getElementById('chatOverlay').classList.add('visible');
    document.getElementById('chatInput').focus();

    // Load messages immediately and start polling
    this.loadMessages();
    this.chatPollInterval = setInterval(() => this.loadMessages(), 2000);
  },

  // Close chat modal
  closeChat() {
    document.getElementById('chatOverlay').classList.remove('visible');
    if (this.chatPollInterval) {
      clearInterval(this.chatPollInterval);
      this.chatPollInterval = null;
    }
    this.chatTaskId = null;
    this.chatMessages = [];
    this.lastMessageId = 0;
  },

  // Load chat messages
  async loadMessages() {
    if (!this.chatTaskId) return;

    try {
      const response = await fetch('/api/chat/getMessages.cfm', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          TaskID: this.chatTaskId,
          AfterMessageID: this.lastMessageId
        })
      });

      const data = await response.json();

      if (data.OK) {
        const messages = data.MESSAGES || [];

        // If first load, replace all; otherwise append new messages
        if (this.lastMessageId === 0) {
          this.chatMessages = messages;
        } else if (messages.length > 0) {
          this.chatMessages = [...this.chatMessages, ...messages];
        }

        // Update last message ID
        if (messages.length > 0) {
          this.lastMessageId = messages[messages.length - 1].MessageID;
        }

        this.renderMessages();

        // Check if chat was closed
        if (data.CHAT_CLOSED) {
          this.showFeedback('Chat has ended', 'info');
          this.closeChat();
        }
      }
    } catch (err) {
      console.error('[HUD] Load messages error:', err);
    }
  },

  // Render chat messages
  renderMessages() {
    const container = document.getElementById('chatMessages');

    if (this.chatMessages.length === 0) {
      container.innerHTML = '<div class="chat-loading">No messages yet. Start the conversation!</div>';
      return;
    }

    container.innerHTML = this.chatMessages.map(msg => {
      const isStaff = msg.SenderType === 'staff' || msg.SenderType === 'worker';
      const time = new Date(msg.CreatedOn).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });

      return `
        <div class="chat-message ${isStaff ? 'staff' : 'customer'}">
          <div class="sender">${msg.SenderName || (isStaff ? 'Staff' : 'Customer')}</div>
          <div class="text">${this.escapeHtml(msg.MessageBody)}</div>
          <div class="time">${time}</div>
        </div>
      `;
    }).join('');

    // Scroll to bottom
    container.scrollTop = container.scrollHeight;
  },

  // Send a chat message
  async sendMessage() {
    const input = document.getElementById('chatInput');
    const message = input.value.trim();

    if (!message || !this.chatTaskId) return;

    input.value = '';
    input.disabled = true;

    try {
      const response = await fetch('/api/chat/sendMessage.cfm', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          TaskID: this.chatTaskId,
          Message: message,
          SenderType: 'staff'
        })
      });

      const data = await response.json();

      if (data.OK) {
        // Add message locally for immediate feedback
        this.chatMessages.push({
          MessageID: data.MessageID || Date.now(),
          MessageBody: message,
          SenderType: 'staff',
          SenderName: 'Staff',
          CreatedOn: new Date().toISOString()
        });
        this.renderMessages();
      } else {
        this.showFeedback('Failed to send message', 'error');
      }
    } catch (err) {
      console.error('[HUD] Send message error:', err);
      this.showFeedback('Failed to send message', 'error');
    }

    input.disabled = false;
    input.focus();
  },

  // End the chat (complete the task)
  async endChat() {
    if (!this.chatTaskId) return;

    if (!confirm('End this chat?')) return;

    try {
      const response = await fetch('/api/tasks/completeChat.cfm', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ TaskID: this.chatTaskId })
      });

      const data = await response.json();

      if (data.OK) {
        this.showFeedback('Chat ended', 'success');
        this.closeChat();
      } else {
        this.showFeedback(data.ERROR || 'Failed to end chat', 'error');
      }
    } catch (err) {
      console.error('[HUD] End chat error:', err);
      this.showFeedback('Failed to end chat', 'error');
    }
  },

  // Escape HTML for safe rendering
  escapeHtml(text) {
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
  }
};

// Global functions for onclick handlers
function closeOverlay() {
  HUD.closeOverlay();
}

function acceptTask() {
  HUD.acceptTask();
}

function toggleFullscreen() {
  const body = document.body;
  const isMaximized = body.classList.contains('maximized');

  if (isMaximized) {
    // Restore normal view
    body.classList.remove('maximized');
    // Also exit native fullscreen if active
    if (document.fullscreenElement) {
      document.exitFullscreen().catch(() => {});
    } else if (document.webkitFullscreenElement) {
      document.webkitExitFullscreen();
    }
  } else {
    // Maximize - hide header for more space
    body.classList.add('maximized');

    // Also try native fullscreen on desktop
    const elem = document.documentElement;
    if (elem.requestFullscreen) {
      elem.requestFullscreen().catch(() => {});
    } else if (elem.webkitRequestFullscreen) {
      elem.webkitRequestFullscreen();
    }
  }
}

// Exit maximized mode when exiting native fullscreen
document.addEventListener('fullscreenchange', () => {
  if (!document.fullscreenElement) {
    document.body.classList.remove('maximized');
  }
});
document.addEventListener('webkitfullscreenchange', () => {
  if (!document.webkitFullscreenElement) {
    document.body.classList.remove('maximized');
  }
});

// Initialize on load
document.addEventListener('DOMContentLoaded', () => {
  HUD.init();
});
