/**
 * TASKMATE - Main Application
 * ===========================
 * Entry point and initialization
 */

import store from './store.js';
import api from './api.js';
import authManager from './auth.js';
import syncManager from './sync.js';
import offlineManager from './offline.js';
import boardManager from './board.js';
import taskModalManager from './task-modal.js';
import calendarViewManager from './calendar.js';
import listViewManager from './list.js';
import shortcutsManager from './shortcuts.js';
import undoManager from './undo.js';
// Tour/Tutorial entfernt
import adminManager from './admin.js';
import proposalsManager from './proposals.js';
import notificationManager from './notifications.js';
import giteaManager from './gitea.js';
import knowledgeManager from './knowledge.js';
import codingManager from './coding.js';
import mobileManager from './mobile.js';
import reminderManager from './reminders.js';
import pwaManager from './pwa.js';
import { $, $$, debounce, getFromStorage, setToStorage } from './utils.js';

class App {
  constructor() {
    this.isInitialized = false;
  }

  // =====================
  // INITIALIZATION
  // =====================

  async init() {
    console.log('[App] Initializing...');

    // Initialize offline storage
    await offlineManager.init();

    // Check authentication
    const isAuthenticated = await authManager.init();

    if (isAuthenticated) {
      // Check if user is admin
      if (authManager.isAdmin()) {
        await this.initializeAdminApp();
      } else {
        await this.initializeApp();
      }
    } else {
      this.showLoginScreen();
    }

    // Bind global events
    this.bindGlobalEvents();

    // Register service worker
    this.registerServiceWorker();

    console.log('[App] Initialized');
    this.isInitialized = true;
  }

  async initializeApp() {
    this.showAppScreen();

    // Connect to WebSocket
    syncManager.connect();

    // Load initial data
    await this.loadInitialData();

    // Initialize proposals manager
    await proposalsManager.init();

    // Initialize notification manager
    await notificationManager.init();

    // Initialize gitea manager
    await giteaManager.init();

    // Initialize coding manager
    await codingManager.init();

    // Initialize knowledge manager
    await knowledgeManager.init();


    // Initialize mobile features
    mobileManager.init();
    
    // Initialize PWA features
    pwaManager.init();

    // Update UI
    this.updateUserMenu();

    // Dispatch event for mobile menu
    document.dispatchEvent(new CustomEvent('projects:loaded'));
  }

  async initializeAdminApp() {
    // Initialize admin manager FIRST (loads DOM elements)
    await adminManager.init();

    // Then show the screen
    this.showAdminScreen();
  }

  // =====================
  // DATA LOADING
  // =====================

  async loadInitialData() {
    store.setLoading(true);

    try {
      // Load users
      const users = await api.getUsers();
      store.setUsers(users);

      // Load projects
      const projects = await api.getProjects();
      store.setProjects(projects);

      // Set current project
      let currentProjectId = getFromStorage('current_project_id');
      if (!currentProjectId && projects.length > 0) {
        currentProjectId = projects[0].id;
      }

      if (currentProjectId) {
        await this.loadProject(currentProjectId);
      }

      // Populate project selector
      this.populateProjectSelector();
    } catch (error) {
      console.error('[App] Failed to load initial data:', error);

      // Try loading from offline cache
      if (!navigator.onLine || error.isOffline) {
        await this.loadFromCache();
      } else {
        this.showError('Fehler beim Laden der Daten');
      }
    } finally {
      store.setLoading(false);
    }
  }

  async loadProject(projectId) {
    store.setCurrentProject(projectId);

    try {
      const [columns, tasks, labels, reminders] = await Promise.all([
        api.getColumns(projectId),
        api.getTasks(projectId),
        api.getLabels(projectId),
        api.getReminders(projectId)
      ]);

      store.setColumns(columns);
      store.setTasks(tasks);
      store.setLabels(labels);
      store.setReminders(reminders);

      // Update project selector
      const projectSelect = $('#project-select');
      if (projectSelect) {
        projectSelect.value = projectId;
      }
    } catch (error) {
      console.error('[App] Failed to load project:', error);

      if (!navigator.onLine || error.isOffline) {
        await offlineManager.loadOfflineData();
      } else {
        throw error;
      }
    }
  }

  async loadFromCache() {
    console.log('[App] Loading from offline cache');

    const projects = await offlineManager.getCachedProjects();
    store.setProjects(projects);

    const currentProjectId = getFromStorage('current_project_id');
    if (currentProjectId) {
      store.setCurrentProject(currentProjectId);
      await offlineManager.loadOfflineData();
    }

    this.populateProjectSelector();
    store.setSyncStatus('offline');
  }

  // =====================
  // UI SCREENS
  // =====================

  showLoginScreen() {
    $('#login-screen')?.classList.remove('hidden');
    $('#app-screen')?.classList.add('hidden');
    $('#admin-screen')?.classList.remove('active');
  }

  showAppScreen() {
    $('#login-screen')?.classList.add('hidden');
    $('#app-screen')?.classList.remove('hidden');
    $('#admin-screen')?.classList.remove('active');
  }

  showAdminScreen() {
    $('#login-screen')?.classList.add('hidden');
    $('#app-screen')?.classList.add('hidden');
    adminManager.show();
  }

  // =====================
  // EVENT BINDING
  // =====================

  bindGlobalEvents() {
    // Auth events
    window.addEventListener('auth:login', () => this.handleLogin());
    window.addEventListener('auth:logout', () => this.handleLogout());

    // View switching
    $$('.view-tab')?.forEach(tab => {
      tab.addEventListener('click', () => {
        const view = tab.dataset.view;
        this.switchView(view);
      });
    });

    // Project selector
    $('#project-select')?.addEventListener('change', (e) => {
      this.loadProject(parseInt(e.target.value));
    });

    // Add project button
    $('#btn-new-project')?.addEventListener('click', () => {
      this.openProjectModal('create');
    });

    // Edit project button
    $('#btn-edit-project')?.addEventListener('click', () => {
      const currentProject = store.getCurrentProject();
      if (currentProject) {
        this.openProjectModal('edit', currentProject);
      } else {
        this.showError('Kein Projekt ausgewählt');
      }
    });

    // Search - Hybrid search with client-side filtering and server search
    this.setupSearch();

    // Filter toggle popover
    $('#btn-filter-toggle')?.addEventListener('click', (e) => {
      e.stopPropagation();
      $('#filter-popover')?.classList.toggle('hidden');
    });

    // Close popover on click outside
    document.addEventListener('click', (e) => {
      const popover = $('#filter-popover');
      const toggleBtn = $('#btn-filter-toggle');
      if (popover && !popover.contains(e.target) && !toggleBtn?.contains(e.target)) {
        popover.classList.add('hidden');
      }
    });

    // Filter changes - checkbox listeners for static filters
    $('#filter-priority-list')?.addEventListener('change', () => this.applyCheckboxFilters());
    $('#filter-due-list')?.addEventListener('change', () => this.applyCheckboxFilters());
    $('#filter-assignee-list')?.addEventListener('change', () => this.applyCheckboxFilters());
    $('#filter-labels-list')?.addEventListener('change', () => this.applyCheckboxFilters());

    // Reset filters
    $('#btn-clear-filters')?.addEventListener('click', () => {
      store.resetFilters();
      this.resetFilterInputs();
      this.updateFilterButtonState();
      $('#filter-popover')?.classList.add('hidden');
    });

    // Open archive modal
    $('#btn-show-archived')?.addEventListener('click', () => {
      this.openArchiveModal();
    });

    // Modal events
    window.addEventListener('modal:open', (e) => this.handleModalOpen(e.detail));
    window.addEventListener('modal:close', (e) => this.handleModalClose(e.detail));

    // Toast events
    window.addEventListener('toast:show', (e) => this.showToast(e.detail));

    // Confirm dialog events
    window.addEventListener('confirm:show', (e) => this.showConfirmDialog(e.detail));

    // Column select dialog events
    window.addEventListener('column-select:show', (e) => this.showColumnSelectDialog(e.detail));

    // Lightbox events
    window.addEventListener('lightbox:open', (e) => this.openLightbox(e.detail));

    // App refresh
    window.addEventListener('app:refresh', () => this.refresh());

    // Notification navigation - open task from inbox
    window.addEventListener('notification:open-task', (e) => {
      const taskId = e.detail.taskId;
      if (taskId) {
        // Switch to board view first
        this.switchView('board');
        // Open task modal
        setTimeout(() => {
          window.dispatchEvent(new CustomEvent('modal:open', {
            detail: { modalId: 'task-modal', mode: 'edit', data: { taskId } }
          }));
        }, 100);
      }
    });

    // Notification navigation - open proposal from inbox
    window.addEventListener('notification:open-proposal', (e) => {
      const proposalId = e.detail.proposalId;
      if (proposalId) {
        // Switch to proposals view
        this.switchView('proposals');
        // Highlight the proposal after view is loaded
        setTimeout(() => {
          proposalsManager.scrollToAndHighlight(proposalId);
        }, 300);
      }
    });

    // Notification navigation - open knowledge entry from inbox
    window.addEventListener('notification:open-knowledge', (e) => {
      const { entryId, categoryId } = e.detail;
      if (entryId && categoryId) {
        // Switch to knowledge view
        this.switchView('knowledge');
        // Select category and expand entry after view is loaded
        setTimeout(async () => {
          await knowledgeManager.selectCategory(categoryId);
          // Expand the specific entry
          knowledgeManager.expandedEntries.add(entryId);
          const entryElement = document.querySelector(`[data-entry-id="${entryId}"]`);
          if (entryElement) {
            entryElement.scrollIntoView({ behavior: 'smooth', block: 'center' });
            entryElement.classList.add('highlight');
            // Remove highlight after animation
            setTimeout(() => {
              entryElement.classList.remove('highlight');
            }, 2000);
          }
        }, 300);
      }
    });

    // Online/Offline
    window.addEventListener('online', () => this.handleOnline());
    window.addEventListener('offline', () => this.handleOffline());

    // Mobile events
    document.addEventListener('project:selected', (e) => {
      const projectId = e.detail?.projectId;
      if (projectId) {
        this.loadProject(projectId);
      }
    });

    document.addEventListener('auth:logout', () => {
      authManager.logout();
    });

    document.addEventListener('admin:open', () => {
      // Redirect to admin screen for admins
      if (authManager.isAdmin()) {
        this.showAdminScreen();
      }
    });

    document.addEventListener('task:move', async (e) => {
      const { taskId, columnId, position } = e.detail;
      if (taskId && columnId !== undefined) {
        await boardManager.moveTask(taskId, columnId, position);
      }
    });

    // Close modal on overlay click
    $('.modal-overlay')?.addEventListener('click', () => {
      // Check if task-modal is open - let it handle its own close (with auto-save)
      if (store.isModalOpen('task-modal')) {
        window.dispatchEvent(new CustomEvent('modal:close', {
          detail: { modalId: 'task-modal' }
        }));
      } else {
        store.closeAllModals();
        this.hideAllModals();
      }
    });

    // Column modal form
    $('#column-form')?.addEventListener('submit', (e) => this.handleColumnFormSubmit(e));

    // Column filter category dropdown - show/hide custom filter input
    $('#column-filter-category')?.addEventListener('change', (e) => {
      const customGroup = $('#column-custom-filter-group');
      if (customGroup) {
        customGroup.classList.toggle('hidden', e.target.value !== 'custom');
      }
    });

    // Project modal form
    $('#project-form')?.addEventListener('submit', (e) => this.handleProjectFormSubmit(e));

    // Delete project button
    $('#btn-delete-project')?.addEventListener('click', () => this.handleDeleteProject());

    // Label modal form
    $('#label-form')?.addEventListener('submit', (e) => this.handleLabelFormSubmit(e));

    // Export button
    $('#btn-export')?.addEventListener('click', () => this.exportProject());

    // Import button
    $('#btn-import')?.addEventListener('click', () => this.importProject());

    // User menu toggle
    $('#user-menu-btn')?.addEventListener('click', (e) => {
      e.stopPropagation();
      this.toggleUserMenu();
    });

    // Close user menu when clicking outside
    document.addEventListener('click', (e) => {
      const userMenu = $('.user-menu');
      if (userMenu && !userMenu.contains(e.target)) {
        $('#user-dropdown')?.classList.add('hidden');
      }
    });

    // Logout button
    $('#btn-logout')?.addEventListener('click', () => {
      authManager.logout();
    });

    // Settings button
    $('#btn-settings')?.addEventListener('click', () => {
      this.handleModalOpen({ modalId: 'settings-modal' });
      $('#user-dropdown')?.classList.add('hidden');
      this.initColorPicker();
    });

    // Color picker options (preset colors)
    $('#user-color-options')?.addEventListener('click', (e) => {
      const colorOption = e.target.closest('.color-option');
      if (colorOption) {
        this.handleColorSelect(colorOption.dataset.color);
      }
    });

    // Color picker custom color input - use 'change' to only save when selection is complete
    $('#user-color-custom')?.addEventListener('change', (e) => {
      this.handleColorSelect(e.target.value);
    });

    // Also update preview in real-time while selecting (without saving)
    $('#user-color-custom')?.addEventListener('input', (e) => {
      const preview = $('#user-color-preview');
      if (preview) {
        preview.style.backgroundColor = e.target.value;
      }
    });

    // Modal close buttons (data-close-modal)
    $$('[data-close-modal]')?.forEach(btn => {
      btn.addEventListener('click', () => {
        const modal = btn.closest('.modal');
        if (modal) {
          this.handleModalClose({ modalId: modal.id });
        }
      });
    });

    // Change password form
    $('#change-password-form')?.addEventListener('submit', (e) => this.handleChangePassword(e));
  }

  // =====================
  // PASSWORD CHANGE
  // =====================

  async handleChangePassword(e) {
    e.preventDefault();

    const currentPassword = $('#current-password')?.value;
    const newPassword = $('#new-password')?.value;
    const confirmPassword = $('#confirm-password')?.value;
    const errorEl = $('#password-error');

    // Validation
    if (!currentPassword || !newPassword || !confirmPassword) {
      this.showPasswordError('Bitte alle Felder ausfüllen.');
      return;
    }

    if (newPassword.length < 8) {
      this.showPasswordError('Das neue Passwort muss mindestens 8 Zeichen lang sein.');
      return;
    }

    if (newPassword !== confirmPassword) {
      this.showPasswordError('Die Passwörter stimmen nicht überein.');
      return;
    }

    try {
      await authManager.changePassword(currentPassword, newPassword);

      // Success
      this.handleModalClose({ modalId: 'settings-modal' });
      $('#change-password-form')?.reset();
      if (errorEl) errorEl.classList.add('hidden');

      this.showSuccess('Passwort erfolgreich geändert');
    } catch (error) {
      this.showPasswordError(error.message || 'Fehler beim Ändern des Passworts.');
    }
  }

  showPasswordError(message) {
    const errorEl = $('#password-error');
    if (errorEl) {
      errorEl.textContent = message;
      errorEl.classList.remove('hidden');
    }
  }

  // =====================
  // COLOR PICKER
  // =====================

  initColorPicker() {
    const currentUser = authManager.getUser();
    const currentColor = currentUser?.color || authManager.getUserColor();

    // Update preview
    const preview = $('#user-color-preview');
    const previewInitial = $('#user-color-preview-initial');
    if (preview) {
      preview.style.backgroundColor = currentColor;
    }
    if (previewInitial && currentUser) {
      previewInitial.textContent = currentUser.username || 'U';
    }

    // Update custom color picker
    const customColorInput = $('#user-color-custom');
    if (customColorInput) {
      customColorInput.value = currentColor;
    }

    // Mark selected color (if it matches a preset)
    $$('.color-option').forEach(option => {
      option.classList.toggle('selected', option.dataset.color.toUpperCase() === currentColor.toUpperCase());
    });
  }

  async handleColorSelect(color) {
    if (!color) return;

    // Update preview immediately
    const preview = $('#user-color-preview');
    if (preview) {
      preview.style.backgroundColor = color;
    }

    // Update custom color picker
    const customColorInput = $('#user-color-custom');
    if (customColorInput) {
      customColorInput.value = color;
    }

    // Update selected state for presets
    $$('.color-option').forEach(option => {
      option.classList.toggle('selected', option.dataset.color.toUpperCase() === color.toUpperCase());
    });

    try {
      // Save to backend
      await api.updateUserColor(color);

      // Update authManager (also updates localStorage)
      authManager.updateUserColor(color);

      // Get current user from authManager
      const currentUser = authManager.getUser();

      // Update users list in store
      if (currentUser) {
        const users = store.get('users');
        const updatedUsers = users.map(u =>
          u.id === currentUser.id ? { ...u, color } : u
        );
        store.setUsers(updatedUsers);
      }

      // Update user avatar in header
      const userAvatar = $('#user-menu-btn');
      if (userAvatar) {
        userAvatar.style.backgroundColor = color;
      }

      // Re-render board to update task cards with new color
      boardManager.render();

      // Re-render calendar if active
      if (store.get('currentView') === 'calendar') {
        calendarViewManager.render();
      }

      this.showSuccess('Farbe erfolgreich geaendert');
    } catch (error) {
      this.showError(error.message || 'Fehler beim Speichern der Farbe');
    }
  }

  // =====================
  // AUTH HANDLERS
  // =====================

  async handleLogin() {
    // Check if user is admin
    if (authManager.isAdmin()) {
      await this.initializeAdminApp();
    } else {
      await this.initializeApp();
    }
  }

  handleLogout() {
    store.reset();
    syncManager.disconnect();
    adminManager.hide();
    notificationManager.reset();
    this.showLoginScreen();
  }

  // =====================
  // VIEW SWITCHING
  // =====================

  switchView(view) {
    store.setCurrentView(view);

    // Update tabs
    $$('.view-tab')?.forEach(tab => {
      tab.classList.toggle('active', tab.dataset.view === view);
    });

    // Show/hide views
    $$('.view')?.forEach(v => {
      const isActive = v.id === `view-${view}`;
      v.classList.toggle('active', isActive);
      v.classList.toggle('hidden', !isActive);
    });

    // Clear search field when switching views
    const searchInput = $('#search-input');
    if (searchInput && searchInput.value) {
      searchInput.value = '';
      store.setFilter('search', '');
      store.setState({ searchResultIds: [] }, 'CLEAR_SEARCH_RESULTS');
      proposalsManager.setSearchQuery('');
      knowledgeManager.setSearchQuery('');
      $('#search-clear')?.classList.add('hidden');
      $('.search-container')?.classList.remove('has-search');
    }

    // Load proposals when switching to proposals view - reset to active (non-archived)
    if (view === 'proposals') {
      proposalsManager.resetToActiveView();
    }

    // Show/hide coding manager
    if (view === 'coding') {
      codingManager.show();
    } else {
      codingManager.hide();
    }

    // Show/hide knowledge manager
    if (view === 'knowledge') {
      knowledgeManager.show();
    } else {
      knowledgeManager.hide();
    }

    // Initialize contacts view when switching to it
    if (view === 'contacts') {
      window.initContactsPromise = window.initContactsPromise || import('./contacts.js').then(module => {
        if (module.contactsManager && !module.contactsManager.isInitialized) {
          return module.contactsManager.init();
        }
      });
      window.initContactsPromise.catch(error => {
        console.error('[App] Contacts module error:', error);
      });
    }

    // Render list view when switching to it (delayed to ensure store is updated)
    if (view === 'list') {
      setTimeout(() => listViewManager.render(), 10);
    }

    // Render calendar view when switching to it
    if (view === 'calendar') {
      setTimeout(() => {
        calendarViewManager.render();
      }, 10);
    }
  }

  // =====================
  // PROJECT SELECTOR
  // =====================

  populateProjectSelector() {
    const select = $('#project-select');
    if (!select) return;

    const projects = store.get('projects');
    select.innerHTML = '';

    projects.forEach(project => {
      const option = document.createElement('option');
      option.value = project.id;
      option.textContent = project.name;
      select.appendChild(option);
    });

    // Set current value
    const currentProjectId = store.get('currentProjectId');
    if (currentProjectId) {
      select.value = currentProjectId;
    }

    // Also populate filter assignee
    this.populateAssigneeFilter();
    this.populateLabelFilter();
  }

  populateAssigneeFilter() {
    const list = $('#filter-assignee-list');
    if (!list) return;

    const users = store.get('users');
    list.innerHTML = '';

    users.forEach(user => {
      const label = document.createElement('label');
      label.className = 'filter-checkbox-item';
      label.innerHTML = `<input type="checkbox" name="filter-assignee" value="${user.id}"><span>${user.displayName || user.email || 'Unbekannt'}</span>`;
      list.appendChild(label);
    });
  }

  populateLabelFilter() {
    const list = $('#filter-labels-list');
    if (!list) return;

    const labels = store.get('labels');
    list.innerHTML = '';

    labels.forEach(label => {
      const item = document.createElement('label');
      item.className = 'filter-checkbox-item';
      item.innerHTML = `<input type="checkbox" name="filter-labels" value="${label.id}"><span>${label.name}</span>`;
      list.appendChild(item);
    });
  }

  applyCheckboxFilters() {
    const getCheckedValues = (name) => {
      const checkboxes = document.querySelectorAll(`input[name="${name}"]:checked`);
      return Array.from(checkboxes).map(cb => cb.value);
    };

    const priority = getCheckedValues('filter-priority');
    const assignee = getCheckedValues('filter-assignee');
    const label = getCheckedValues('filter-labels');
    const dueDate = getCheckedValues('filter-due');

    store.setFilter('priority', priority.length > 0 ? priority : '');
    store.setFilter('assignee', assignee.length > 0 ? assignee : '');
    store.setFilter('label', label.length > 0 ? label : '');
    store.setFilter('dueDate', dueDate.length > 0 ? dueDate : '');

    this.updateFilterButtonState();
  }

  resetFilterInputs() {
    const checkboxes = document.querySelectorAll('#filter-popover input[type="checkbox"]');
    checkboxes.forEach(cb => cb.checked = false);

    const search = $('#search-input');
    const searchClear = $('#search-clear');
    const searchContainer = $('.search-container');

    if (search) search.value = '';
    if (searchClear) searchClear.classList.add('hidden');
    if (searchContainer) searchContainer.classList.remove('has-search');
  }

  updateFilterButtonState() {
    const btn = $('#btn-filter-toggle');
    if (!btn) return;

    const groups = ['filter-priority', 'filter-assignee', 'filter-labels', 'filter-due'];
    const activeCount = groups.filter(name => {
      return document.querySelectorAll(`input[name="${name}"]:checked`).length > 0;
    }).length;

    const label = btn.querySelector('span');
    if (label) {
      label.textContent = activeCount > 0 ? `Filter (${activeCount})` : 'Filter';
    }
    btn.classList.toggle('has-filters', activeCount > 0);
  }

  async openArchiveModal() {
    this.handleModalOpen({ modalId: 'archive-modal' });

    const archiveList = $('#archive-list');
    const archiveEmpty = $('#archive-empty');

    // Ladeindikator anzeigen
    if (archiveList) {
      archiveList.classList.remove('hidden');
      archiveList.innerHTML = '<div style="text-align:center;padding:2rem;color:var(--text-secondary)">Lade archivierte Aufgaben...</div>';
    }
    if (archiveEmpty) archiveEmpty.classList.add('hidden');

    try {
      const projectId = store.get('currentProjectId');
      const allTasks = await api.getTasks(projectId, { archived: true });
      const archivedTasks = allTasks.filter(t => t.archived);
      this.renderArchiveList(archivedTasks);
    } catch (error) {
      console.error('Failed to load archived tasks:', error);
      if (archiveList) {
        archiveList.innerHTML = '<div style="text-align:center;padding:2rem;color:var(--danger)">Fehler beim Laden der archivierten Aufgaben</div>';
      }
    }
  }

  renderArchiveList(tasks) {
    const archiveList = $('#archive-list');
    const archiveEmpty = $('#archive-empty');
    if (!archiveList) return;

    const columns = store.get('columns');

    if (tasks.length === 0) {
      archiveList.classList.add('hidden');
      archiveEmpty?.classList.remove('hidden');
      return;
    }

    archiveList.classList.remove('hidden');
    archiveEmpty?.classList.add('hidden');

    // Sort by archived date (most recent first) - use updatedAt as proxy
    tasks.sort((a, b) => new Date(b.updatedAt || 0) - new Date(a.updatedAt || 0));

    const priorityLabels = { high: 'Hoch', medium: 'Mittel', low: 'Niedrig' };

    archiveList.innerHTML = tasks.map(task => {
      const column = columns.find(c => c.id === task.columnId);
      const columnName = column?.name || 'Unbekannt';

      return `
        <div class="archive-item" data-task-id="${task.id}">
          <div class="archive-item-info" onclick="app.openArchivedTask('${task.id}')">
            <div class="archive-item-title">${this.escapeHtml(task.title)}</div>
            <div class="archive-item-meta">
              <span class="priority-badge ${task.priority || 'medium'}">${priorityLabels[task.priority] || 'Mittel'}</span>
              <span>Spalte: ${this.escapeHtml(columnName)}</span>
              ${task.dueDate ? `<span>Fällig: ${new Date(task.dueDate).toLocaleDateString('de-DE')}</span>` : ''}
            </div>
          </div>
          <div class="archive-item-actions">
            <button class="btn btn-sm btn-primary" onclick="app.restoreTask('${task.id}')">Wiederherstellen</button>
            <button class="btn btn-sm btn-text text-danger" onclick="app.deleteArchivedTask('${task.id}')">Löschen</button>
          </div>
        </div>
      `;
    }).join('');
  }

  async restoreTask(taskId) {
    try {
      const projectId = store.get('currentProjectId');
      const response = await api.restoreTask(projectId, taskId);

      // Task in den Store einfuegen (vorher nur in Archivliste, nicht im Store)
      const restoredTask = response?.task;
      if (restoredTask) {
        const existing = store.getTaskById ? store.getTaskById(taskId) : null;
        if (existing) {
          store.updateTask(taskId, { ...restoredTask, archived: false });
        } else {
          store.addTask({ ...restoredTask, archived: false });
        }
      } else {
        store.updateTask(taskId, { archived: false });
      }

      this.showSuccess('Aufgabe wiederhergestellt');

      // Re-render board
      if (this.board) {
        this.board.render();
      }

      // Archivliste neu laden
      const allTasks = await api.getTasks(projectId, { archived: true });
      this.renderArchiveList(allTasks.filter(t => t.archived));
    } catch (error) {
      console.error('Restore error:', error);
      this.showError('Fehler beim Wiederherstellen');
    }
  }

  openArchivedTask(taskId) {
    // Close archive modal first
    this.handleModalClose({ modalId: 'archive-modal' });

    // Open task modal
    if (this.taskModal) {
      this.taskModal.open(taskId);
    }
  }

  async deleteArchivedTask(taskId) {
    window.dispatchEvent(new CustomEvent('confirm:show', {
      detail: {
        message: 'Möchten Sie diese Aufgabe endgültig löschen?',
        confirmText: 'Löschen',
        confirmClass: 'btn-danger',
        onConfirm: async () => {
          try {
            const projectId = store.get('currentProjectId');
            await api.deleteTask(projectId, taskId);
            store.removeTask(taskId);
            this.showSuccess('Aufgabe gelöscht');

            // Archivliste neu laden
            const allTasks = await api.getTasks(projectId, { archived: true });
            this.renderArchiveList(allTasks.filter(t => t.archived));
          } catch (error) {
            this.showError('Fehler beim Löschen');
          }
        }
      }
    }));
  }

  escapeHtml(text) {
    if (!text) return '';
    const div = document.createElement('div');
    div.textContent = text;
    return div.innerHTML;
  }

  // =====================
  // SEARCH
  // =====================

  setupSearch() {
    const searchInput = $('#search-input');
    const searchClear = $('#search-clear');
    const searchSpinner = $('#search-spinner');
    const searchContainer = $('.search-container');

    if (!searchInput) return;

    // Abort controller for canceling pending server requests
    let searchAbortController = null;

    // Update UI based on search state
    const updateSearchUI = (value) => {
      const hasValue = value && value.trim().length > 0;
      searchClear?.classList.toggle('hidden', !hasValue);
      searchContainer?.classList.toggle('has-search', hasValue);
    };

    // Clear search function
    const clearSearch = () => {
      searchInput.value = '';
      store.setFilter('search', '');
      store.setState({ searchResultIds: [] }, 'CLEAR_SEARCH_RESULTS');
      updateSearchUI('');
      searchInput.focus();

      // Clear view-specific search
      proposalsManager.setSearchQuery('');
      knowledgeManager.setSearchQuery('');
      
      // Clear contacts search
      import('./contacts.js').then(module => {
        if (module.contactsManager) {
          module.contactsManager.searchQuery = '';
          module.contactsManager.loadContacts();
        }
      }).catch(() => {});

      // Cancel any pending server search
      if (searchAbortController) {
        searchAbortController.abort();
        searchAbortController = null;
      }
      searchSpinner?.classList.add('hidden');
    };

    // Perform server search (for deep search in subtasks, links, etc.)
    const performServerSearch = debounce(async (query) => {
      if (!query || query.trim().length < 2) {
        searchSpinner?.classList.add('hidden');
        // Clear server search results when query is too short
        store.setState({ searchResultIds: [] }, 'CLEAR_SEARCH_RESULTS');
        return;
      }

      const projectId = store.get('currentProjectId');
      if (!projectId) {
        searchSpinner?.classList.add('hidden');
        return;
      }

      // Cancel previous request
      if (searchAbortController) {
        searchAbortController.abort();
      }
      searchAbortController = new AbortController();

      try {
        searchSpinner?.classList.remove('hidden');

        const results = await api.searchTasks(projectId, query);

        // Store the IDs of tasks found by server search
        // These will bypass the client-side search filter
        const serverResultIds = results.map(t => t.id);
        store.setState({ searchResultIds: serverResultIds }, 'SET_SEARCH_RESULTS');

        // Merge server results with current tasks (add any that aren't already loaded)
        const currentTasks = store.get('tasks');
        const currentTaskIds = new Set(currentTasks.map(t => t.id));

        const newTasks = results.filter(t => !currentTaskIds.has(t.id));
        if (newTasks.length > 0) {
          // Add newly found tasks to the store
          store.setState({
            tasks: [...currentTasks, ...newTasks]
          }, 'SEARCH_RESULTS_MERGED');
        }
      } catch (error) {
        if (error.name !== 'AbortError') {
          console.error('Server search failed:', error);
        }
      } finally {
        searchSpinner?.classList.add('hidden');
        searchAbortController = null;
      }
    }, 500);

    // Input event - immediate client-side filter + delayed server search
    searchInput.addEventListener('input', (e) => {
      const value = e.target.value;
      updateSearchUI(value);

      // Check current view
      const currentView = store.get('currentView');

      if (currentView === 'proposals') {
        // Search proposals only
        proposalsManager.setSearchQuery(value);
      } else if (currentView === 'knowledge') {
        // Search knowledge base
        knowledgeManager.setSearchQuery(value);
      } else if (currentView === 'contacts') {
        // Search contacts
        import('./contacts.js').then(module => {
          if (module.contactsManager) {
            module.contactsManager.searchQuery = value;
            module.contactsManager.loadContacts();
          }
        }).catch(() => {});
      } else {
        // Immediate client-side filtering for tasks
        store.setFilter('search', value);

        // Delayed server search for deep content (subtasks, links, attachments, comments)
        performServerSearch(value);
      }
    });

    // Clear button click
    searchClear?.addEventListener('click', clearSearch);

    // Escape key to clear search
    searchInput.addEventListener('keydown', (e) => {
      if (e.key === 'Escape') {
        e.preventDefault();
        clearSearch();
      }
    });

    // Global Escape key handler (when search input is not focused)
    document.addEventListener('keydown', (e) => {
      if (e.key === 'Escape' && searchInput.value && document.activeElement !== searchInput) {
        clearSearch();
      }
    });

    // Initialize UI state (in case there's a value from before)
    updateSearchUI(searchInput.value);
  }

  // =====================
  // USER MENU
  // =====================

  updateUserMenu() {
    const user = authManager.getUser();
    if (!user) return;

    const avatar = $('#user-initial');
    if (avatar) {
      avatar.textContent = authManager.getUserInitials();
    }

    const avatarBtn = $('#user-menu-btn');
    if (avatarBtn) {
      avatarBtn.style.backgroundColor = authManager.getUserColor();
    }

    const userName = $('#user-name');
    if (userName) userName.textContent = user.username;

    const userRole = $('#user-role');
    if (userRole) userRole.textContent = user.role === 'admin' ? 'Administrator' : 'Benutzer';

    // Notify mobile menu
    document.dispatchEvent(new CustomEvent('user:updated'));
  }

  toggleUserMenu() {
    const dropdown = $('#user-dropdown');
    if (dropdown) {
      dropdown.classList.toggle('hidden');
    }
  }

  // =====================
  // MODALS
  // =====================

  handleModalOpen(detail) {
    const { modalId, mode, data } = detail;
    const modal = $(`#${modalId}`);
    const overlay = $('.modal-overlay');

    if (modal) {
      modal.classList.remove('hidden');
      modal.classList.add('visible');
      modal.dataset.mode = mode || 'create';

      if (data) {
        modal.dataset.data = JSON.stringify(data);
      }

      // Handle column-modal specific setup
      if (modalId === 'column-modal') {
        const titleEl = $('#column-modal-title');
        const nameInput = $('#column-name');
        const colorInput = $('#column-color');
        const deleteBtn = $('#btn-delete-column');

        if (mode === 'edit' && data) {
          if (titleEl) titleEl.textContent = 'Spalte bearbeiten';
          if (nameInput) nameInput.value = data.name || '';
          if (colorInput) colorInput.value = data.color || '#00D4FF';
          if (deleteBtn) deleteBtn.style.display = '';
        } else {
          if (titleEl) titleEl.textContent = 'Neue Spalte';
          if (nameInput) nameInput.value = '';
          if (colorInput) colorInput.value = '#00D4FF';
          if (deleteBtn) deleteBtn.style.display = 'none';
        }
      }
    }

    if (overlay) {
      overlay.classList.remove('hidden');
      overlay.classList.add('visible');
    }

    store.openModal(modalId);
  }

  handleModalClose(detail) {
    const { modalId } = detail;
    const modal = $(`#${modalId}`);
    const overlay = $('.modal-overlay');

    if (modal) {
      modal.classList.remove('visible');
      setTimeout(() => modal.classList.add('hidden'), 200);
    }

    // Only hide overlay if no other modals are open
    const openModals = store.get('openModals').filter(id => id !== modalId);
    if (openModals.length === 0 && overlay) {
      overlay.classList.remove('visible');
      setTimeout(() => overlay.classList.add('hidden'), 200);
    }

    store.closeModal(modalId);
  }

  hideAllModals() {
    $$('.modal').forEach(modal => {
      modal.classList.remove('visible');
      setTimeout(() => modal.classList.add('hidden'), 200);
    });

    const overlay = $('.modal-overlay');
    if (overlay) {
      overlay.classList.remove('visible');
      setTimeout(() => overlay.classList.add('hidden'), 200);
    }
  }

  // =====================
  // TOAST NOTIFICATIONS
  // =====================

  showToast({ message, type = 'info', duration = 4000 }) {
    const container = $('#toast-container') || this.createToastContainer();

    const toast = document.createElement('div');
    toast.className = `toast toast-${type}`;

    const icon = this.getToastIcon(type);

    toast.innerHTML = `
      <span class="toast-icon">${icon}</span>
      <span class="toast-message">${message}</span>
      <button class="toast-close">&times;</button>
    `;

    // Close button handler
    toast.querySelector('.toast-close')?.addEventListener('click', () => {
      this.removeToast(toast);
    });

    container.appendChild(toast);

    // Trigger animation
    requestAnimationFrame(() => {
      toast.classList.add('visible');
    });

    // Auto remove
    if (duration > 0) {
      setTimeout(() => this.removeToast(toast), duration);
    }
  }

  createToastContainer() {
    const container = document.createElement('div');
    container.id = 'toast-container';
    container.className = 'toast-container';
    document.body.appendChild(container);
    return container;
  }

  removeToast(toast) {
    toast.classList.remove('visible');
    setTimeout(() => toast.remove(), 300);
  }

  getToastIcon(type) {
    const icons = {
      success: '✓',
      error: '✕',
      warning: '⚠',
      info: 'ℹ'
    };
    return icons[type] || icons.info;
  }

  showError(message) {
    this.showToast({ message, type: 'error' });
  }

  showSuccess(message) {
    this.showToast({ message, type: 'success' });
  }

  // =====================
  // CONFIRM DIALOG
  // =====================

  showConfirmDialog({ message, confirmText = 'OK', confirmClass = '', onConfirm }) {
    const modal = $('#confirm-modal');
    const messageEl = $('#confirm-message');
    const confirmBtn = $('#confirm-ok');
    const cancelBtn = $('#confirm-cancel');

    if (messageEl) messageEl.textContent = message;
    if (confirmBtn) {
      confirmBtn.textContent = confirmText;
      confirmBtn.className = `btn ${confirmClass || 'btn-primary'}`;
    }

    // Show modal
    this.handleModalOpen({ modalId: 'confirm-modal' });

    // One-time event handlers
    const handleConfirm = () => {
      this.handleModalClose({ modalId: 'confirm-modal' });
      if (onConfirm) onConfirm();
      cleanup();
    };

    const handleCancel = () => {
      this.handleModalClose({ modalId: 'confirm-modal' });
      cleanup();
    };

    const cleanup = () => {
      confirmBtn?.removeEventListener('click', handleConfirm);
      cancelBtn?.removeEventListener('click', handleCancel);
    };

    confirmBtn?.addEventListener('click', handleConfirm);
    cancelBtn?.addEventListener('click', handleCancel);
  }

  // =====================
  // COLUMN SELECT DIALOG
  // =====================

  showColumnSelectDialog({ message, columns, onSelect }) {
    const modal = $('#column-select-modal');
    const messageEl = $('#column-select-message');
    const dropdown = $('#column-select-dropdown');
    const confirmBtn = $('#column-select-ok');
    const cancelBtn = $('#column-select-cancel');

    if (messageEl) messageEl.textContent = message;

    // Spalten in Dropdown einfügen
    if (dropdown) {
      dropdown.innerHTML = '';
      columns.forEach(column => {
        const option = document.createElement('option');
        option.value = column.id;
        option.textContent = column.name;
        dropdown.appendChild(option);
      });
    }

    // Show modal
    this.handleModalOpen({ modalId: 'column-select-modal' });

    // One-time event handlers
    const handleConfirm = () => {
      const selectedColumnId = parseInt(dropdown?.value);
      this.handleModalClose({ modalId: 'column-select-modal' });
      if (onSelect && selectedColumnId) onSelect(selectedColumnId);
      cleanup();
    };

    const handleCancel = () => {
      this.handleModalClose({ modalId: 'column-select-modal' });
      cleanup();
    };

    const cleanup = () => {
      confirmBtn?.removeEventListener('click', handleConfirm);
      cancelBtn?.removeEventListener('click', handleCancel);
    };

    confirmBtn?.addEventListener('click', handleConfirm);
    cancelBtn?.addEventListener('click', handleCancel);
  }

  // =====================
  // LIGHTBOX
  // =====================

  openLightbox({ imageUrl, filename }) {
    const lightbox = $('#lightbox');
    const image = $('#lightbox-image');

    if (image) {
      image.src = imageUrl;
      image.alt = filename || '';
    }

    if (lightbox) {
      lightbox.classList.remove('hidden');
    }

    // Close handlers
    const closeHandler = () => {
      lightbox?.classList.add('hidden');
      document.removeEventListener('keydown', escHandler);
    };

    const escHandler = (e) => {
      if (e.key === 'Escape') closeHandler();
    };

    $('#lightbox-close')?.addEventListener('click', closeHandler, { once: true });
    lightbox?.addEventListener('click', (e) => {
      if (e.target === lightbox) closeHandler();
    }, { once: true });
    document.addEventListener('keydown', escHandler);
  }

  // =====================
  // FORM HANDLERS
  // =====================

  async handleColumnFormSubmit(e) {
    e.preventDefault();

    const modal = $('#column-modal');
    const mode = modal?.dataset.mode;
    const nameInput = $('#column-name');
    const colorInput = $('#column-color');
    const filterCategorySelect = $('#column-filter-category');
    const customFilterInput = $('#column-custom-filter');

    const name = nameInput?.value.trim();
    const color = colorInput?.value || '#00D4FF';

    // Filter-Kategorie ermitteln
    let filterCategory = filterCategorySelect?.value || 'in_progress';
    if (filterCategory === 'custom') {
      filterCategory = customFilterInput?.value.trim() || 'in_progress';
    }

    if (!name) {
      this.showError('Bitte einen Namen eingeben');
      return;
    }

    try {
      if (mode === 'create') {
        await boardManager.createColumn(name, color, filterCategory);
        this.showSuccess('Statuskarte erstellt');
      } else {
        const data = JSON.parse(modal?.dataset.data || '{}');
        await boardManager.updateColumn(data.id, { name, color, filterCategory });
        this.showSuccess('Statuskarte aktualisiert');
      }

      this.handleModalClose({ modalId: 'column-modal' });
      nameInput.value = '';
      if (customFilterInput) customFilterInput.value = '';
    } catch (error) {
      this.showError('Fehler beim Speichern');
    }
  }

  async handleProjectFormSubmit(e) {
    e.preventDefault();

    const modal = $('#project-modal');
    const mode = modal?.dataset.mode;
    const nameInput = $('#project-name');
    const descInput = $('#project-description');

    const name = nameInput?.value.trim();
    const description = descInput?.value.trim();

    if (!name) {
      this.showError('Bitte einen Namen eingeben');
      return;
    }

    try {
      if (mode === 'create') {
        const project = await api.createProject({ name, description });
        store.addProject(project);
        await this.loadProject(project.id);
        this.populateProjectSelector();
        this.showSuccess('Projekt erstellt');
      } else {
        const data = JSON.parse(modal?.dataset.data || '{}');
        await api.updateProject(data.id, { name, description });
        store.updateProject(data.id, { name, description });
        this.populateProjectSelector();
        this.showSuccess('Projekt aktualisiert');
      }

      this.handleModalClose({ modalId: 'project-modal' });
      nameInput.value = '';
      descInput.value = '';
    } catch (error) {
      this.showError('Fehler beim Speichern');
    }
  }

  async handleLabelFormSubmit(e) {
    e.preventDefault();

    const modal = $('#label-modal');
    const mode = modal?.dataset.mode;
    const nameInput = $('#label-name');
    const colorInput = $('#label-color');

    const name = nameInput?.value.trim();
    const color = colorInput?.value;

    if (!name) {
      this.showError('Bitte einen Namen eingeben');
      return;
    }

    const projectId = store.get('currentProjectId');

    try {
      if (mode === 'create') {
        const label = await api.createLabel(projectId, { name, color });
        store.addLabel(label);
        this.showSuccess('Label erstellt');
      } else {
        const data = JSON.parse(modal?.dataset.data || '{}');
        await api.updateLabel(projectId, data.id, { name, color });
        store.updateLabel(data.id, { name, color });
        this.showSuccess('Label aktualisiert');
      }

      this.handleModalClose({ modalId: 'label-modal' });
      this.populateLabelFilter();
      nameInput.value = '';
    } catch (error) {
      this.showError('Fehler beim Speichern');
    }
  }

  openProjectModal(mode, data = {}) {
    this.handleModalOpen({
      modalId: 'project-modal',
      mode,
      data
    });

    const deleteBtn = $('#btn-delete-project');
    const modalTitle = $('#project-modal-title');

    if (mode === 'edit' && data) {
      $('#project-name').value = data.name || '';
      $('#project-description').value = data.description || '';
      $('#project-id').value = data.id || '';
      if (deleteBtn) deleteBtn.classList.remove('hidden');
      if (modalTitle) modalTitle.textContent = 'Projekt bearbeiten';
    } else {
      $('#project-name').value = '';
      $('#project-description').value = '';
      $('#project-id').value = '';
      if (deleteBtn) deleteBtn.classList.add('hidden');
      if (modalTitle) modalTitle.textContent = 'Neues Projekt';
    }
  }

  async handleDeleteProject() {
    const projectId = parseInt($('#project-id')?.value);
    if (!projectId) return;

    const project = store.get('projects').find(p => p.id === projectId);
    if (!project) return;

    this.showConfirmDialog({
      message: `Möchten Sie das Projekt "${project.name}" und alle zugehörigen Aufgaben wirklich löschen? Diese Aktion kann nicht rückgängig gemacht werden.`,
      confirmText: 'Löschen',
      confirmClass: 'btn-danger',
      onConfirm: async () => {
        try {
          const result = await api.deleteProject(projectId, true);
          store.removeProject(projectId);

          // Falls das aktuelle Projekt gelöscht wurde, zu einem anderen wechseln
          if (store.get('currentProjectId') === projectId) {
            const projects = store.get('projects');
            if (projects.length > 0) {
              await this.loadProject(projects[0].id);
            } else {
              store.setTasks([]);
              store.setColumns([]);
              store.setLabels([]);
            }
          }

          this.populateProjectSelector();
          this.handleModalClose({ modalId: 'project-modal' });
          this.showSuccess(`Projekt "${project.name}" wurde gelöscht`);
        } catch (error) {
          this.showError('Fehler beim Löschen des Projekts: ' + (error.message || 'Unbekannter Fehler'));
        }
      }
    });
  }

  // =====================
  // EXPORT/IMPORT
  // =====================

  async exportProject() {
    const projectId = store.get('currentProjectId');
    if (!projectId) return;

    try {
      const data = await api.exportProject(projectId, 'json');
      const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
      const url = URL.createObjectURL(blob);

      const a = document.createElement('a');
      a.href = url;
      a.download = `project_${projectId}_export.json`;
      a.click();

      URL.revokeObjectURL(url);
      this.showSuccess('Export erfolgreich');
    } catch (error) {
      this.showError('Export fehlgeschlagen');
    }
  }

  async importProject() {
    const input = document.createElement('input');
    input.type = 'file';
    input.accept = '.json';

    input.onchange = async (e) => {
      const file = e.target.files[0];
      if (!file) return;

      try {
        const text = await file.text();
        const data = JSON.parse(text);

        await api.importProject(data);
        await this.loadInitialData();

        this.showSuccess('Import erfolgreich');
      } catch (error) {
        this.showError('Import fehlgeschlagen: ' + error.message);
      }
    };

    input.click();
  }

  // =====================
  // ONLINE/OFFLINE
  // =====================

  handleOnline() {
    store.setOnline(true);
    this.showToast({ message: 'Verbindung wiederhergestellt', type: 'success' });

    // Sync pending operations
    offlineManager.syncPendingOperations();
  }

  handleOffline() {
    store.setOnline(false);
    this.showToast({ message: 'Offline-Modus aktiv', type: 'warning' });
  }

  // =====================
  // REFRESH
  // =====================

  async refresh() {
    const projectId = store.get('currentProjectId');
    if (projectId) {
      await this.loadProject(projectId);
    }
  }

  // =====================
  // SERVICE WORKER
  // =====================

  async registerServiceWorker() {
    if ('serviceWorker' in navigator) {
      try {
        const registration = await navigator.serviceWorker.register('/sw.js');
        console.log('[App] Service Worker registered:', registration.scope);
      } catch (error) {
        console.error('[App] Service Worker registration failed:', error);
      }
    }
  }
}

// Create app instance and initialize
const app = new App();

// Initialize when DOM is ready
if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', () => app.init());
} else {
  app.init();
}

export default app;
