/**
 * TASKMATE - Task Modal Module
 * ============================
 * Task creation and editing modal
 */

import store from './store.js';
import api from './api.js';
import syncManager from './sync.js';
import {
  $, $$, createElement, clearElement, formatDate, formatDateTime,
  formatRelativeTime, formatFileSize, getInitials, hexToRgba,
  getContrastColor, isImageFile, debounce, generateTempId
} from './utils.js';

class TaskModalManager {
  constructor() {
    this.modal = $('#task-modal');
    this.form = $('#task-form');
    this.mode = 'create';
    this.taskId = null;
    this.columnId = null;
    this.originalTask = null;

    this.subtasks = [];
    this.links = [];
    this.files = [];
    this.comments = [];
    this.history = [];

    this.init();
  }

  init() {
    this.bindEvents();

    // Listen for modal events
    window.addEventListener('modal:open', (e) => {
      if (e.detail.modalId === 'task-modal') {
        this.open(e.detail.mode, e.detail.data);
      }
    });

    window.addEventListener('modal:close', (e) => {
      if (e.detail.modalId === 'task-modal') {
        this.close();
      }
    });

    window.addEventListener('task:refresh', (e) => {
      if (this.taskId === e.detail.taskId) {
        this.loadTaskData();
      }
    });
  }

  bindEvents() {
    // Form submission
    this.form?.addEventListener('submit', (e) => this.handleSubmit(e));

    // Close buttons
    $$('.modal-close, [data-dismiss="modal"]', this.modal)?.forEach(btn => {
      btn.addEventListener('click', () => this.close());
    });

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

    // Duplicate button
    $('#btn-duplicate-task')?.addEventListener('click', () => this.handleDuplicate());

    // Archive button
    $('#btn-archive-task')?.addEventListener('click', () => this.handleArchive());


    // Restore button
    $('#btn-restore-task')?.addEventListener('click', () => this.handleRestore());

    // Tab navigation
    $$('.tab-btn', this.modal)?.forEach(btn => {
      btn.addEventListener('click', (e) => this.switchTab(e.target.dataset.tab));
    });

    // Subtask handling
    $('#btn-add-subtask')?.addEventListener('click', () => this.addSubtask());
    $('#subtask-input')?.addEventListener('keypress', (e) => {
      if (e.key === 'Enter') {
        e.preventDefault();
        this.addSubtask();
      }
    });

    // Link handling
    $('#btn-add-link')?.addEventListener('click', () => this.addLink());
    $('#link-url')?.addEventListener('keypress', (e) => {
      if (e.key === 'Enter') {
        e.preventDefault();
        this.addLink();
      }
    });

    // File upload
    const fileInput = $('#file-input');
    const fileDropArea = $('.file-upload-area', this.modal);

    fileInput?.addEventListener('change', (e) => this.handleFileSelect(e.target.files));

    fileDropArea?.addEventListener('dragover', (e) => {
      e.preventDefault();
      fileDropArea.classList.add('drag-over');
    });

    fileDropArea?.addEventListener('dragleave', () => {
      fileDropArea.classList.remove('drag-over');
    });

    fileDropArea?.addEventListener('drop', (e) => {
      e.preventDefault();
      fileDropArea.classList.remove('drag-over');
      this.handleFileSelect(e.dataTransfer.files);
    });

    // Comment submission
    $('#btn-add-comment')?.addEventListener('click', () => this.addComment());
    $('#comment-input')?.addEventListener('keypress', (e) => {
      if (e.key === 'Enter' && !e.shiftKey) {
        e.preventDefault();
        this.addComment();
      }
    });

    // Label selection - auto-save
    $$('.label-checkbox input', this.modal)?.forEach(input => {
      input.addEventListener('change', () => {
        this.updateLabels();
        if (this.mode === 'edit' && this.taskId) {
          this.autoSaveTask();
        }
      });
    });

    // Create new label
    $('#btn-add-label')?.addEventListener('click', () => this.openLabelModal());

    // Description auto-save
    const descriptionInput = $('#task-description');
    descriptionInput?.addEventListener('input', debounce(() => {
      if (this.mode === 'edit' && this.taskId) {
        this.autoSaveTask();
      }
    }, 1000));

    // Auto-save for all form fields (assignees handled separately via multi-select)
    const autoSaveFields = ['task-priority', 'task-status', 'task-start', 'task-due', 'task-time-hours', 'task-time-mins'];
    autoSaveFields.forEach(fieldId => {
      const field = $(`#${fieldId}`);
      if (field) {
        field.addEventListener('change', () => {
          if (this.mode === 'edit' && this.taskId) {
            this.autoSaveTask();
          }
        });
      }
    });

    // Initialize assignees multi-select dropdown
    this.initAssigneesDropdown();

    // Debounced auto-save for title (on input, not just blur)
    const titleInput = $('#task-title');
    if (titleInput) {
      titleInput.addEventListener('input', debounce(() => {
        if (this.mode === 'edit' && this.taskId) {
          this.autoSaveTask();
        }
      }, 1000));
    }

    // Zurück button - save and close (edit mode only)
    $('#btn-back-task')?.addEventListener('click', async () => {
      if (this.mode === 'edit' && this.taskId) {
        await this.autoSaveTask();
      }
      this.close();
    });

    // Save button - create new task (create mode only)
    $('#btn-save-task')?.addEventListener('click', async () => {
      if (this.mode === 'create') {
        await this.createTask();
        this.close();
      }
    });

    // Cancel button - close without saving (create mode only)
    $('#btn-cancel-task')?.addEventListener('click', () => {
      this.close();
    });
  }

  // =====================
  // MODAL CONTROL
  // =====================

  async open(mode, data = {}) {
    this.mode = mode;
    this.columnId = data.columnId || null;
    this.taskId = data.taskId || null;

    // Reset form
    this.form?.reset();
    this.subtasks = [];
    this.links = [];
    this.files = [];
    this.comments = [];
    this.history = [];

    // Update modal title
    const title = this.modal?.querySelector('.modal-header h2');
    if (title) {
      title.textContent = mode === 'create' ? 'Neue Aufgabe' : 'Aufgabe bearbeiten';
    }

    // Show/hide action buttons based on mode
    const deleteBtn = $('#btn-delete-task');
    const duplicateBtn = $('#btn-duplicate-task');
    const archiveBtn = $('#btn-archive-task');
    const restoreBtn = $('#btn-restore-task');
    const saveBtn = $('#btn-save-task');
    const cancelBtn = $('#btn-cancel-task');
    const backBtn = $('#btn-back-task');

    // Left side buttons (only in edit mode, archive/restore toggled in loadTaskData)
    if (deleteBtn) deleteBtn.classList.toggle('hidden', mode === 'create');
    if (duplicateBtn) duplicateBtn.classList.toggle('hidden', mode === 'create');
    if (archiveBtn) archiveBtn.classList.toggle('hidden', mode === 'create');
    if (restoreBtn) restoreBtn.classList.add('hidden'); // Always hide initially, shown in loadTaskData if archived

    // Right side buttons (create vs edit mode)
    if (saveBtn) saveBtn.classList.toggle('hidden', mode !== 'create');
    if (cancelBtn) cancelBtn.classList.toggle('hidden', mode !== 'create');
    if (backBtn) backBtn.classList.toggle('hidden', mode === 'create');

    // Populate labels
    this.renderLabels();

    // Populate assignees
    this.renderAssignees();

    // Populate columns
    this.renderColumns();

    if (mode === 'edit' && this.taskId) {
      await this.loadTaskData();
    } else {
      // Create mode - clear all UI elements and set defaults
      
      // Clear UI elements (render empty arrays)
      this.renderSubtasks();
      this.renderLinks();
      this.renderFiles();
      this.renderComments();
      this.renderHistory();

      // Set default column
      if (this.columnId) {
        const columnSelect = $('#task-status');
        if (columnSelect) columnSelect.value = this.columnId;
      }

      // Set default assignee to current user
      const currentUser = store.get('currentUser');
      if (currentUser) {
        this.setSelectedAssignees([currentUser.id]);
      } else {
        this.setSelectedAssignees([]);
      }
    }

    // Switch to details tab
    this.switchTab('details');

    // Show modal
    this.showModal();
  }

  async close() {
    // Auto-save before closing (for edit mode)
    if (this.mode === 'edit' && this.taskId) {
      await this.autoSaveTask();
    }

    this.hideModal();
    this.taskId = null;
    this.columnId = null;
    this.originalTask = null;
    store.setEditingTask(null);
    store.closeModal('task-modal');
  }

  showModal() {
    const overlay = $('.modal-overlay');
    if (overlay) {
      overlay.classList.remove('hidden');
      overlay.classList.add('visible');
    }

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

    store.openModal('task-modal');

    // Focus title input
    setTimeout(() => {
      $('#task-title')?.focus();
    }, 100);
  }

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

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

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

  async loadTaskData() {
    const projectId = store.get('currentProjectId');

    try {
      const task = await api.getTask(projectId, this.taskId);
      this.originalTask = { ...task };

      // Populate form fields
      this.populateForm(task);

      // Update archive/restore buttons based on task status
      const archiveBtn = $('#btn-archive-task');
      const restoreBtn = $('#btn-restore-task');
      if (task.archived) {
        if (archiveBtn) archiveBtn.classList.add('hidden');
        if (restoreBtn) restoreBtn.classList.remove('hidden');
      } else {
        if (archiveBtn) archiveBtn.classList.remove('hidden');
        if (restoreBtn) restoreBtn.classList.add('hidden');
      }

      // Load related data
      await Promise.all([
        this.loadSubtasks(),
        this.loadLinks(),
        this.loadFiles(),
        this.loadComments(),
        this.loadHistory()
      ]);
    } catch (error) {
      console.error('Failed to load task:', error);
      this.showError('Fehler beim Laden der Aufgabe');
    }
  }

  populateForm(task) {
    // Convert total minutes back to hours and minutes for display
    const totalMinutes = task.timeEstimateMin || 0;
    const hours = Math.floor(totalMinutes / 60);
    const minutes = totalMinutes % 60;

    // Basic fields - use backend field names (camelCase)
    const fields = {
      'task-title': task.title,
      'task-description': task.description || '',
      'task-priority': task.priority || 'medium',
      'task-status': task.columnId,
      'task-start': task.startDate ? task.startDate.split('T')[0] : '',
      'task-due': task.dueDate ? task.dueDate.split('T')[0] : '',
      'task-time-hours': hours || '',
      'task-time-mins': minutes || ''
    };

    Object.entries(fields).forEach(([id, value]) => {
      const input = $(`#${id}`);
      if (input) input.value = value;
    });

    // Assignees (Mehrfachzuweisung)
    if (task.assignees && Array.isArray(task.assignees)) {
      const assigneeIds = task.assignees.map(a => a.id);
      this.setSelectedAssignees(assigneeIds);
    } else if (task.assignedTo) {
      // Rückwärtskompatibilität
      this.setSelectedAssignees([task.assignedTo]);
    } else {
      this.setSelectedAssignees([]);
    }

    // Labels
    if (task.labels) {
      task.labels.forEach(label => {
        const checkbox = $(`#label-${label.id}`);
        if (checkbox) checkbox.checked = true;
      });
    }
  }

  async loadSubtasks() {
    try {
      const projectId = store.get('currentProjectId');
      this.subtasks = await api.getSubtasks(projectId, this.taskId);
      this.renderSubtasks();
    } catch (error) {
      console.error('Failed to load subtasks:', error);
    }
  }

  async loadLinks() {
    try {
      const projectId = store.get('currentProjectId');
      this.links = await api.getLinks(projectId, this.taskId);
      this.renderLinks();
    } catch (error) {
      console.error('Failed to load links:', error);
    }
  }

  async loadFiles() {
    try {
      const projectId = store.get('currentProjectId');
      this.files = await api.getFiles(projectId, this.taskId);
      this.renderFiles();
    } catch (error) {
      console.error('Failed to load files:', error);
    }
  }

  async loadComments() {
    try {
      const projectId = store.get('currentProjectId');
      this.comments = await api.getComments(projectId, this.taskId);
      this.renderComments();
    } catch (error) {
      console.error('Failed to load comments:', error);
    }
  }

  async loadHistory() {
    try {
      const projectId = store.get('currentProjectId');
      this.history = await api.getTaskHistory(projectId, this.taskId);
      this.renderHistory();
    } catch (error) {
      console.error('Failed to load history:', error);
    }
  }

  // =====================
  // FORM SUBMISSION
  // =====================

  async handleSubmit(e) {
    e.preventDefault();
    // Form submit is handled by auto-save and Zurück button
    // This just prevents default form submission
  }

  getFormData() {
    // Convert hours and minutes to total minutes for backend
    const hours = parseInt($('#task-time-hours')?.value) || 0;
    const minutes = parseInt($('#task-time-mins')?.value) || 0;
    const timeEstimateMin = (hours * 60 + minutes) || null;

    return {
      title: $('#task-title')?.value.trim() || '',
      description: $('#task-description')?.value.trim() || '',
      priority: $('#task-priority')?.value || 'medium',
      columnId: parseInt($('#task-status')?.value) || this.columnId,
      assignees: this.getSelectedAssignees(),
      startDate: $('#task-start')?.value || null,
      dueDate: $('#task-due')?.value || null,
      timeEstimateMin: timeEstimateMin,
      labels: this.getSelectedLabels()
    };
  }

  getSelectedLabels() {
    const checkboxes = $$('.label-checkbox input:checked', this.modal);
    return checkboxes.map(cb => parseInt(cb.value));
  }

  async updateTask(data) {
    const projectId = store.get('currentProjectId');

    const changes = this.getChanges(data);

    const task = await api.updateTask(projectId, this.taskId, data);
    store.updateTask(this.taskId, task);
    syncManager.notifyTaskUpdated(task, changes);

    this.showSuccess('Aufgabe aktualisiert');
  }

  getChanges(newData) {
    const changes = [];
    const original = this.originalTask;

    if (!original) return ['created'];

    if (newData.title !== original.title) changes.push('title');
    if (newData.description !== original.description) changes.push('description');
    if (newData.priority !== original.priority) changes.push('priority');
    if (newData.columnId !== original.columnId) changes.push('status');
    // Assignees vergleichen
    const newAssignees = (newData.assignees || []).sort().join(',');
    const originalAssignees = (original.assignees || []).map(a => a.id).sort().join(',');
    if (newAssignees !== originalAssignees) changes.push('assignees');
    if (newData.startDate !== original.startDate) changes.push('startDate');
    if (newData.dueDate !== original.dueDate) changes.push('dueDate');

    return changes;
  }

  // =====================
  // TASK ACTIONS
  // =====================

  async handleDelete() {
    window.dispatchEvent(new CustomEvent('confirm:show', {
      detail: {
        message: 'Möchten Sie diese Aufgabe wirklich löschen?',
        confirmText: 'Löschen',
        confirmClass: 'btn-danger',
        onConfirm: async () => {
          try {
            const projectId = store.get('currentProjectId');
            await api.deleteTask(projectId, this.taskId);
            store.removeTask(this.taskId);
            syncManager.notifyTaskDeleted(this.taskId, this.originalTask?.title);
            this.close();
            this.showSuccess('Aufgabe gelöscht');
          } catch (error) {
            this.showError('Fehler beim Löschen');
          }
        }
      }
    }));
  }

  async handleDuplicate() {
    try {
      const projectId = store.get('currentProjectId');
      const task = await api.duplicateTask(projectId, this.taskId);
      store.addTask(task);
      syncManager.notifyTaskCreated(task);
      this.close();
      this.showSuccess('Aufgabe dupliziert');
    } catch (error) {
      this.showError('Fehler beim Duplizieren');
    }
  }

  async handleArchive() {
    try {
      const projectId = store.get('currentProjectId');
      await api.archiveTask(projectId, this.taskId);
      store.updateTask(this.taskId, { archived: true });
      this.close();
      this.showSuccess('Aufgabe archiviert');
    } catch (error) {
      this.showError('Fehler beim Archivieren');
    }
  }

  async handleRestore() {
    try {
      const projectId = store.get('currentProjectId');
      const response = await api.restoreTask(projectId, this.taskId);
      this.applyRestoredTask(response?.task);
      this.close();
      window.dispatchEvent(new CustomEvent('modal:close', { detail: { modalId: 'archive-modal' } }));
      this.showSuccess('Aufgabe wiederhergestellt');
    } catch (error) {
      // Prüfen ob Spaltenauswahl erforderlich ist
      if (error.data?.requiresColumn) {
        this.showColumnSelectDialog();
      } else {
        this.showError('Fehler beim Wiederherstellen');
      }
    }
  }

  applyRestoredTask(restoredTask) {
    if (restoredTask) {
      const existing = store.getTaskById ? store.getTaskById(this.taskId) : null;
      if (existing) {
        store.updateTask(this.taskId, { ...restoredTask, archived: false });
      } else {
        store.addTask({ ...restoredTask, archived: false });
      }
    } else {
      store.updateTask(this.taskId, { archived: false });
    }
  }

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

    // Modal für Spaltenauswahl erstellen
    window.dispatchEvent(new CustomEvent('column-select:show', {
      detail: {
        message: 'Die ursprüngliche Spalte existiert nicht mehr. Bitte wählen Sie eine Spalte:',
        columns: columns,
        onSelect: async (columnId) => {
          try {
            const projectId = store.get('currentProjectId');
            const response = await api.restoreTask(projectId, this.taskId, columnId);
            this.applyRestoredTask(response?.task);
            this.close();
            window.dispatchEvent(new CustomEvent('modal:close', { detail: { modalId: 'archive-modal' } }));
            this.showSuccess('Aufgabe wiederhergestellt');
          } catch (error) {
            this.showError('Fehler beim Wiederherstellen');
          }
        }
      }
    }));
  }

  async autoSaveDescription() {
    // Deprecated - use autoSaveTask instead
    await this.autoSaveTask();
  }

  async autoSaveTask() {
    if (!this.taskId || this.mode !== 'edit') return;

    const formData = this.getFormData();

    // Don't save if title is empty
    if (!formData.title.trim()) return;

    // Check if there are actual changes
    if (!this.hasChanges(formData)) return;

    this.showSaveStatus('saving');

    try {
      const projectId = store.get('currentProjectId');
      const task = await api.updateTask(projectId, this.taskId, formData);
      store.updateTask(this.taskId, task);

      // Update original task to track changes
      this.originalTask = { ...this.originalTask, ...formData };

      this.showSaveStatus('saved');
    } catch (error) {
      console.error('Auto-save failed:', error);
      this.showSaveStatus('error');
    }
  }

  hasChanges(formData) {
    if (!this.originalTask) return true;

    return (
      formData.title !== this.originalTask.title ||
      formData.description !== (this.originalTask.description || '') ||
      formData.priority !== this.originalTask.priority ||
      formData.columnId !== this.originalTask.columnId ||
      formData.assignedTo !== this.originalTask.assignedTo ||
      formData.startDate !== this.originalTask.startDate ||
      formData.dueDate !== this.originalTask.dueDate ||
      formData.timeEstimateMin !== this.originalTask.timeEstimateMin
    );
  }

  showSaveStatus(status) {
    const indicator = $('#save-status-indicator');
    if (!indicator) return;

    indicator.className = 'save-status-indicator';

    switch (status) {
      case 'saving':
        indicator.textContent = 'Speichert...';
        indicator.classList.add('saving');
        break;
      case 'saved':
        indicator.textContent = 'Gespeichert';
        indicator.classList.add('saved');
        // Hide after 2 seconds
        setTimeout(() => {
          indicator.classList.remove('saved');
          indicator.textContent = '';
        }, 2000);
        break;
      case 'error':
        indicator.textContent = 'Fehler beim Speichern';
        indicator.classList.add('error');
        break;
    }
  }

  async createTask(data = null) {
    const formData = data || this.getFormData();

    // Validation
    if (!formData.title.trim()) {
      this.showError('Bitte einen Titel eingeben');
      $('#task-title')?.focus();
      return false;
    }

    try {
      const projectId = store.get('currentProjectId');
      const task = await api.createTask(projectId, formData);
      store.addTask(task);
      syncManager.notifyTaskCreated(task);
      this.showSuccess('Aufgabe erstellt');
      return true;
    } catch (error) {
      console.error('Failed to create task:', error);
      this.showError('Fehler beim Erstellen');
      return false;
    }
  }

  // =====================
  // TABS
  // =====================

  switchTab(tabId) {
    // Update tab buttons
    $$('.tab-btn', this.modal)?.forEach(btn => {
      btn.classList.toggle('active', btn.dataset.tab === tabId);
    });

    // Update tab panels
    $$('.tab-panel', this.modal)?.forEach(panel => {
      panel.classList.toggle('active', panel.id === `tab-${tabId}`);
    });
  }

  // =====================
  // RENDERING
  // =====================

  renderLabels() {
    const container = $('#task-labels');
    if (!container) return;

    const labels = store.get('labels');
    clearElement(container);

    labels.forEach(label => {
      const checkbox = createElement('label', {
        className: 'label-checkbox'
      }, [
        createElement('input', {
          type: 'checkbox',
          id: `label-${label.id}`,
          value: label.id
        }),
        createElement('span', {
          className: 'checkmark'
        }),
        createElement('span', {
          className: 'label-color-dot',
          style: { backgroundColor: label.color }
        }),
        createElement('span', {}, [label.name])
      ]);

      container.appendChild(checkbox);
    });

    // Add "create label" button
    const addBtn = createElement('button', {
      type: 'button',
      className: 'btn-add-label',
      id: 'btn-add-label'
    }, ['+ Neues Label']);

    addBtn.addEventListener('click', () => this.openLabelModal());
    container.appendChild(addBtn);
  }

  // Multi-Select Dropdown für Mitarbeiter initialisieren
  initAssigneesDropdown() {
    const dropdown = $('#assignees-dropdown');
    const trigger = $('#assignees-trigger');
    const options = $('#assignees-options');

    if (!dropdown || !trigger || !options) return;

    // Position dropdown options below trigger (links ausgerichtet wie Startdatum)
    const positionDropdown = () => {
      const triggerRect = trigger.getBoundingClientRect();
      // Startdatum-Feld finden und dessen linke Position verwenden
      const startDateInput = document.getElementById('task-start');
      const leftPos = startDateInput ? startDateInput.getBoundingClientRect().left : triggerRect.left;

      options.style.top = `${triggerRect.bottom + 2}px`;
      options.style.left = `${leftPos}px`;
      options.style.width = 'auto';
      options.style.minWidth = '200px';
    };

    // Toggle dropdown
    trigger.addEventListener('click', (e) => {
      e.stopPropagation();
      const isOpen = dropdown.classList.toggle('open');
      options.classList.toggle('hidden');
      if (isOpen) {
        positionDropdown();
      }
    });

    // Close when clicking outside
    document.addEventListener('click', (e) => {
      if (!dropdown.contains(e.target) && !options.contains(e.target)) {
        dropdown.classList.remove('open');
        options.classList.add('hidden');
      }
    });

    // Close on scroll in modal body
    const modalBody = dropdown.closest('.modal-body');
    if (modalBody) {
      modalBody.addEventListener('scroll', () => {
        if (dropdown.classList.contains('open')) {
          dropdown.classList.remove('open');
          options.classList.add('hidden');
        }
      });
    }
  }

  renderAssignees() {
    const optionsContainer = $('#assignees-options');
    if (!optionsContainer) return;

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

    users.forEach(user => {
      // DEBUG: User-Objekt anschauen
      console.log('[DEBUG] User in Dropdown:', user);
      const option = createElement('div', { class: 'multi-select-option' });

      const checkbox = createElement('input', {
        type: 'checkbox',
        value: user.id,
        id: `assignee-${user.id}`
      });

      checkbox.addEventListener('change', () => {
        this.updateAssigneesDisplay();
        if (this.mode === 'edit' && this.taskId) {
          this.autoSaveTask();
        }
      });

      const avatar = createElement('div', {
        class: 'multi-select-option-avatar',
        style: `background-color: ${user.color || '#6366F1'}`
      }, [user.initials || getInitials(user.display_name || user.email || 'XX')]);

      // Probiere verschiedene Felder für den Namen
      const displayName = user.displayName || user.display_name || user.name || user.username || 'Benutzer';
      console.log('[DEBUG] Display name für user', user.id, ':', displayName);
      const name = createElement('span', { class: 'multi-select-option-name' }, [displayName]);

      option.appendChild(checkbox);
      option.appendChild(avatar);
      option.appendChild(name);

      // Click on option also toggles checkbox
      option.addEventListener('click', (e) => {
        if (e.target !== checkbox) {
          checkbox.checked = !checkbox.checked;
          checkbox.dispatchEvent(new Event('change'));
        }
      });

      optionsContainer.appendChild(option);
    });
  }

  getSelectedAssignees() {
    const checkboxes = $$('#assignees-options input[type="checkbox"]:checked');
    return checkboxes.map(cb => parseInt(cb.value));
  }

  setSelectedAssignees(assigneeIds) {
    // Alle Checkboxen zurücksetzen
    $$('#assignees-options input[type="checkbox"]').forEach(cb => {
      cb.checked = false;
    });

    // Ausgewählte Mitarbeiter setzen
    if (assigneeIds && Array.isArray(assigneeIds)) {
      assigneeIds.forEach(id => {
        const checkbox = $(`#assignee-${id}`);
        if (checkbox) checkbox.checked = true;
      });
    }

    this.updateAssigneesDisplay();
  }

  updateAssigneesDisplay() {
    const trigger = $('#assignees-trigger');
    if (!trigger) return;

    const selectedIds = this.getSelectedAssignees();
    const users = store.get('users');
    const selectedUsers = users.filter(u => selectedIds.includes(u.id));

    if (selectedUsers.length === 0) {
      trigger.innerHTML = `
        <span class="multi-select-placeholder">Mitarbeitende auswählen...</span>
        <span class="multi-select-arrow">▼</span>
      `;
    } else {
      const tags = selectedUsers.map(user => `
        <span class="multi-select-tag">
          <span class="multi-select-tag-avatar" style="background-color: ${user.color || '#6366F1'}" title="${user.display_name || user.email}">
            ${user.initials || getInitials(user.display_name || user.email || 'XX')}
          </span>
        </span>
      `).join('');

      trigger.innerHTML = `
        <div class="multi-select-selected">${tags}</div>
        <span class="multi-select-arrow">▼</span>
      `;
    }
  }

  renderColumns() {
    const select = $('#task-status');
    if (!select) return;

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

    columns.forEach(column => {
      const option = createElement('option', { value: column.id }, [column.name]);
      select.appendChild(option);
    });
  }

  renderSubtasks() {
    const container = $('#subtasks-container');
    if (!container) return;

    clearElement(container);

    this.subtasks.forEach((subtask, index) => {
      const item = createElement('div', {
        className: `subtask-item ${subtask.completed ? 'completed' : ''}`,
        dataset: { subtaskId: subtask.id, position: index },
        draggable: 'true'
      }, [
        // Drag Handle
        createElement('span', {
          className: 'subtask-drag-handle',
          title: 'Ziehen zum Verschieben'
        }, ['⋮⋮']),
        // Checkbox
        createElement('input', {
          type: 'checkbox',
          checked: subtask.completed,
          onchange: () => this.toggleSubtask(subtask.id)
        }),
        // Titel (Doppelklick zum Bearbeiten)
        createElement('span', {
          className: 'subtask-title',
          ondblclick: (e) => this.startEditSubtask(subtask.id, e.target)
        }, [subtask.title]),
        // Aktionen
        createElement('div', {
          className: 'subtask-actions'
        }, [
          createElement('button', {
            type: 'button',
            className: 'subtask-edit',
            title: 'Bearbeiten',
            onclick: (e) => this.startEditSubtask(subtask.id, e.target.closest('.subtask-item').querySelector('.subtask-title'))
          }, ['✎']),
          createElement('button', {
            type: 'button',
            className: 'subtask-delete',
            title: 'Löschen',
            onclick: () => this.deleteSubtask(subtask.id)
          }, ['×'])
        ])
      ]);

      // Drag & Drop Events
      item.addEventListener('dragstart', (e) => this.handleSubtaskDragStart(e, subtask.id, index));
      item.addEventListener('dragover', (e) => this.handleSubtaskDragOver(e));
      item.addEventListener('dragleave', (e) => this.handleSubtaskDragLeave(e));
      item.addEventListener('drop', (e) => this.handleSubtaskDrop(e, subtask.id, index));
      item.addEventListener('dragend', (e) => this.handleSubtaskDragEnd(e));

      container.appendChild(item);
    });

    // Update progress display
    this.updateSubtaskProgress();
  }

  // Subtask Drag & Drop
  handleSubtaskDragStart(e, subtaskId, position) {
    e.dataTransfer.effectAllowed = 'move';
    e.dataTransfer.setData('text/plain', JSON.stringify({ subtaskId, position }));
    e.target.classList.add('dragging');
    this.draggedSubtaskId = subtaskId;
  }

  handleSubtaskDragOver(e) {
    e.preventDefault();
    e.dataTransfer.dropEffect = 'move';
    const item = e.target.closest('.subtask-item');
    if (item && !item.classList.contains('dragging')) {
      const rect = item.getBoundingClientRect();
      const midpoint = rect.top + rect.height / 2;
      item.classList.remove('drag-over-top', 'drag-over-bottom');
      if (e.clientY < midpoint) {
        item.classList.add('drag-over-top');
      } else {
        item.classList.add('drag-over-bottom');
      }
    }
  }

  handleSubtaskDragLeave(e) {
    const item = e.target.closest('.subtask-item');
    if (item) {
      item.classList.remove('drag-over-top', 'drag-over-bottom');
    }
  }

  handleSubtaskDragEnd(e) {
    e.target.classList.remove('dragging');
    $$('.subtask-item').forEach(item => {
      item.classList.remove('drag-over-top', 'drag-over-bottom');
    });
    this.draggedSubtaskId = null;
  }

  async handleSubtaskDrop(e, targetSubtaskId, targetPosition) {
    e.preventDefault();
    const item = e.target.closest('.subtask-item');
    if (item) {
      item.classList.remove('drag-over-top', 'drag-over-bottom');
    }

    if (!this.draggedSubtaskId || this.draggedSubtaskId === targetSubtaskId) return;

    const draggedIndex = this.subtasks.findIndex(s => s.id === this.draggedSubtaskId);
    if (draggedIndex === -1) return;

    // Berechne neue Position basierend auf Drop-Position
    const rect = item.getBoundingClientRect();
    const midpoint = rect.top + rect.height / 2;
    let newPosition = targetPosition;
    if (e.clientY > midpoint && draggedIndex < targetPosition) {
      // Nach unten, hinter das Ziel
      newPosition = targetPosition;
    } else if (e.clientY > midpoint && draggedIndex > targetPosition) {
      newPosition = targetPosition + 1;
    } else if (e.clientY <= midpoint && draggedIndex > targetPosition) {
      newPosition = targetPosition;
    } else if (e.clientY <= midpoint && draggedIndex < targetPosition) {
      newPosition = targetPosition - 1;
    }

    if (newPosition === draggedIndex) return;

    // Lokale Reihenfolge aktualisieren
    const [moved] = this.subtasks.splice(draggedIndex, 1);
    this.subtasks.splice(newPosition, 0, moved);
    this.renderSubtasks();

    // API-Call
    if (this.mode === 'edit' && this.taskId) {
      const projectId = store.get('currentProjectId');
      try {
        await api.reorderSubtasks(projectId, this.taskId, this.draggedSubtaskId, newPosition);
      } catch (error) {
        console.error('Fehler beim Neuordnen der Subtask:', error);
      }
    }
  }

  // Subtask bearbeiten
  startEditSubtask(subtaskId, titleElement) {
    const subtask = this.subtasks.find(s => s.id === subtaskId);
    if (!subtask) return;

    const currentTitle = subtask.title;
    const input = createElement('input', {
      type: 'text',
      className: 'subtask-edit-input',
      value: currentTitle
    });

    // Titel durch Input ersetzen
    titleElement.replaceWith(input);
    input.focus();
    input.select();

    const saveEdit = async () => {
      const newTitle = input.value.trim();
      if (newTitle && newTitle !== currentTitle) {
        subtask.title = newTitle;
        if (this.mode === 'edit' && this.taskId) {
          const projectId = store.get('currentProjectId');
          try {
            await api.updateSubtask(projectId, this.taskId, subtaskId, { title: newTitle });
          } catch (error) {
            console.error('Fehler beim Aktualisieren der Subtask:', error);
            subtask.title = currentTitle; // Rollback
          }
        }
      }
      this.renderSubtasks();
    };

    input.addEventListener('blur', saveEdit);
    input.addEventListener('keydown', (e) => {
      if (e.key === 'Enter') {
        e.preventDefault();
        input.blur();
      } else if (e.key === 'Escape') {
        subtask.title = currentTitle; // Keine Änderung
        this.renderSubtasks();
      }
    });
  }

  updateSubtaskProgress() {
    const progressContainer = $('#subtask-progress');
    if (!progressContainer) return;

    if (this.subtasks.length === 0) {
      progressContainer.classList.add('hidden');
      return;
    }

    const completed = this.subtasks.filter(s => s.completed).length;
    const total = this.subtasks.length;
    const percentage = Math.round((completed / total) * 100);

    progressContainer.classList.remove('hidden');
    $('#subtask-progress-text').textContent = `${completed}/${total}`;
    $('#subtask-progress-bar').style.width = `${percentage}%`;
  }

  renderLinks() {
    const container = $('#links-container');
    if (!container) return;

    clearElement(container);

    this.links.forEach(link => {
      const item = createElement('div', {
        className: 'link-item',
        dataset: { linkId: link.id }
      }, [
        createElement('span', {
          className: 'link-icon'
        }, [this.getLinkIcon(link.icon)]),
        createElement('div', {
          className: 'link-info'
        }, [
          createElement('div', { className: 'link-title' }, [link.title || link.url]),
          createElement('div', { className: 'link-url' }, [link.url])
        ]),
        createElement('div', {
          className: 'link-actions'
        }, [
          createElement('a', {
            href: link.url,
            target: '_blank',
            rel: 'noopener',
            className: 'btn btn-icon btn-ghost',
            title: 'Öffnen'
          }, ['↗']),
          createElement('button', {
            type: 'button',
            className: 'btn btn-icon btn-ghost',
            title: 'Löschen',
            onclick: () => this.deleteLink(link.id)
          }, ['×'])
        ])
      ]);

      container.appendChild(item);
    });
  }

  getLinkIcon(iconType) {
    const icons = {
      youtube: '▶',
      github: '⌘',
      docs: '📄',
      default: '🔗'
    };
    return icons[iconType] || icons.default;
  }

  renderFiles() {
    const container = $('#attachments-container');
    if (!container) return;

    clearElement(container);

    if (!this.files || this.files.length === 0) {
      container.appendChild(createElement('div', {
        className: 'no-files-message',
        style: { color: 'var(--text-muted)', fontSize: 'var(--text-sm)', padding: 'var(--spacing-2)' }
      }, ['Keine Anhänge']));
      return;
    }

    this.files.forEach(file => {
      const projectId = store.get('currentProjectId');

      // Support both camelCase (from backend) and snake_case (legacy)
      const originalName = file.originalName || file.original_name || 'Unbekannt';
      const fileSize = file.sizeFormatted || formatFileSize(file.sizeBytes || file.size || 0);
      const fileIsImage = file.isImage !== undefined ? file.isImage : isImageFile(originalName);

      const previewContent = fileIsImage
        ? createElement('img', {
            src: api.getFilePreviewUrl(projectId, this.taskId, file.id),
            alt: originalName,
            onclick: () => this.openLightbox(file)
          })
        : createElement('span', { className: 'icon' }, ['📎']);

      const item = createElement('div', {
        className: 'attachment-item',
        dataset: { fileId: file.id }
      }, [
        createElement('div', {
          className: 'attachment-preview'
        }, [previewContent]),
        createElement('div', {
          className: 'attachment-info'
        }, [
          createElement('div', { className: 'attachment-name' }, [originalName]),
          createElement('div', { className: 'attachment-size' }, [fileSize])
        ]),
        createElement('div', {
          className: 'attachment-actions'
        }, [
          createElement('button', {
            type: 'button',
            className: 'btn btn-icon btn-ghost',
            title: 'Herunterladen',
            onclick: () => this.downloadFile(file)
          }, ['↓']),
          createElement('button', {
            type: 'button',
            className: 'btn btn-icon btn-ghost',
            title: 'Löschen',
            onclick: () => this.deleteFile(file.id)
          }, ['×'])
        ])
      ]);

      container.appendChild(item);
    });
  }

  renderComments() {
    const container = $('#comments-container');
    if (!container) return;

    clearElement(container);

    this.comments.forEach(comment => {
      const item = createElement('div', {
        className: 'comment-item',
        dataset: { commentId: comment.id }
      }, [
        createElement('div', { className: 'comment-avatar' }, [
          createElement('span', {
            className: 'avatar',
            style: { backgroundColor: comment.user?.color || '#888' }
          }, [getInitials(comment.user?.username || 'User')])
        ]),
        createElement('div', { className: 'comment-content' }, [
          createElement('div', { className: 'comment-header' }, [
            createElement('span', { className: 'comment-author' }, [comment.user?.username || 'Unbekannt']),
            createElement('span', { className: 'comment-time' }, [formatRelativeTime(comment.created_at)])
          ]),
          createElement('div', {
            className: 'comment-text'
          }, [this.formatCommentContent(comment.content)])
        ])
      ]);

      container.appendChild(item);
    });
  }

  formatCommentContent(content) {
    // Convert @mentions to highlighted spans
    return content.replace(/@(\w+)/g, '<span class="mention">@$1</span>');
  }

  renderHistory() {
    const container = $('#history-container');
    if (!container) return;

    clearElement(container);

    this.history.forEach(entry => {
      const item = createElement('div', { className: 'history-item' }, [
        createElement('span', {
          className: 'history-dot',
          style: { backgroundColor: entry.user?.color || '#888' }
        }),
        createElement('span', { className: 'history-text' }, [
          createElement('strong', {}, [entry.user?.username || 'System']),
          ` ${this.formatHistoryAction(entry)}`
        ]),
        createElement('span', { className: 'history-time' }, [
          formatRelativeTime(entry.created_at)
        ])
      ]);

      container.appendChild(item);
    });
  }

  formatHistoryAction(entry) {
    const actions = {
      created: 'hat die Aufgabe erstellt',
      updated: `hat ${entry.field} geändert`,
      moved: `hat die Aufgabe nach "${entry.new_value}" verschoben`,
      assigned: `hat die Aufgabe ${entry.new_value} zugewiesen`,
      unassigned: 'hat die Zuweisung entfernt',
      priority_changed: `hat die Priorität auf "${entry.new_value}" geändert`,
      due_date_changed: `hat das Fälligkeitsdatum auf ${formatDate(entry.new_value)} gesetzt`,
      completed: 'hat die Aufgabe abgeschlossen'
    };

    return actions[entry.action] || entry.action;
  }

  // =====================
  // SUBTASKS
  // =====================

  async addSubtask() {
    const input = $('#subtask-input');
    const title = input?.value.trim();

    if (!title) return;

    if (this.mode === 'edit' && this.taskId) {
      try {
        const projectId = store.get('currentProjectId');
        const subtask = await api.createSubtask(projectId, this.taskId, { title });
        // Neue Subtask an erster Stelle einfügen
        this.subtasks.unshift(subtask);
        this.renderSubtasks();
        input.value = '';

        // Update subtask progress in store for immediate board update
        this.updateSubtaskProgressInStore();
      } catch (error) {
        this.showError('Fehler beim Hinzufügen');
      }
    } else {
      // For new tasks, store locally - an erster Stelle
      this.subtasks.unshift({
        id: generateTempId(),
        title,
        completed: false
      });
      this.renderSubtasks();
      input.value = '';
    }
  }

  async toggleSubtask(subtaskId) {
    const subtask = this.subtasks.find(s => s.id === subtaskId);
    if (!subtask) return;

    const wasCompleted = subtask.completed;
    subtask.completed = !subtask.completed;

    if (this.mode === 'edit' && this.taskId) {
      try {
        const projectId = store.get('currentProjectId');
        await api.updateSubtask(projectId, this.taskId, subtaskId, {
          completed: subtask.completed
        });

        // Wenn abgehakt: ans Ende der Liste verschieben
        if (subtask.completed && !wasCompleted) {
          const currentIndex = this.subtasks.findIndex(s => s.id === subtaskId);
          const lastPosition = this.subtasks.length - 1;

          if (currentIndex < lastPosition) {
            // Aus aktueller Position entfernen
            const [moved] = this.subtasks.splice(currentIndex, 1);
            // Ans Ende anfügen
            this.subtasks.push(moved);

            // API-Call für neue Position
            await api.reorderSubtasks(projectId, this.taskId, subtaskId, lastPosition);
          }
        }

        // Update subtask progress in store for immediate board update
        this.updateSubtaskProgressInStore();
      } catch (error) {
        subtask.completed = wasCompleted;
        this.showError('Fehler beim Aktualisieren');
      }
    }

    this.renderSubtasks();
  }

  async deleteSubtask(subtaskId) {
    if (this.mode === 'edit' && this.taskId) {
      try {
        const projectId = store.get('currentProjectId');
        await api.deleteSubtask(projectId, this.taskId, subtaskId);
      } catch (error) {
        this.showError('Fehler beim Löschen');
        return;
      }
    }

    this.subtasks = this.subtasks.filter(s => s.id !== subtaskId);
    this.renderSubtasks();

    // Update subtask progress in store for immediate board update
    if (this.mode === 'edit' && this.taskId) {
      this.updateSubtaskProgressInStore();
    }
  }

  updateSubtaskProgressInStore() {
    const total = this.subtasks.length;
    const completed = this.subtasks.filter(s => s.completed).length;
    store.updateTask(this.taskId, {
      subtasks: this.subtasks,
      subtaskProgress: { total, completed }
    });
  }

  // =====================
  // LINKS
  // =====================

  // Normalize URL - add https:// if no protocol specified
  normalizeUrl(url) {
    if (!url) return url;
    const trimmed = url.trim();
    // Check if URL already has a protocol
    if (/^https?:\/\//i.test(trimmed)) {
      return trimmed;
    }
    // Add https:// prefix
    return 'https://' + trimmed;
  }

  async addLink() {
    const urlInput = $('#link-url');
    const titleInput = $('#link-title');

    let url = urlInput?.value.trim();
    const title = titleInput?.value.trim();

    if (!url) return;

    // Normalize URL (add https:// if missing)
    url = this.normalizeUrl(url);

    if (this.mode === 'edit' && this.taskId) {
      try {
        const projectId = store.get('currentProjectId');
        const link = await api.createLink(projectId, this.taskId, { url, title });
        this.links.push(link);
        this.renderLinks();
        urlInput.value = '';
        titleInput.value = '';

        // Update link count in store for immediate board update
        store.updateTask(this.taskId, { linkCount: this.links.length });
      } catch (error) {
        this.showError('Fehler beim Hinzufügen');
      }
    }
  }

  async deleteLink(linkId) {
    if (this.mode === 'edit' && this.taskId) {
      try {
        const projectId = store.get('currentProjectId');
        await api.deleteLink(projectId, this.taskId, linkId);
      } catch (error) {
        this.showError('Fehler beim Löschen');
        return;
      }
    }

    this.links = this.links.filter(l => l.id !== linkId);
    this.renderLinks();

    // Update link count in store for immediate board update
    if (this.mode === 'edit' && this.taskId) {
      store.updateTask(this.taskId, { linkCount: this.links.length });
    }
  }

  // =====================
  // FILES
  // =====================

  async handleFileSelect(files) {
    if (!files || files.length === 0) return;

    for (const file of files) {
      if (file.size > 15 * 1024 * 1024) {
        this.showError(`${file.name} ist zu groß (max. 15 MB)`);
        continue;
      }

      if (this.mode === 'edit' && this.taskId) {
        await this.uploadFile(file);
      }
    }

    // Reset file input
    $('#file-input').value = '';
  }

  async uploadFile(file) {
    const projectId = store.get('currentProjectId');

    try {
      const result = await api.uploadTaskFile(projectId, this.taskId, file, (progress) => {
        // Could show upload progress here
        console.log(`Upload progress: ${progress}%`);
      });

      // Backend returns { attachments: [...] }
      if (result.attachments && result.attachments.length > 0) {
        this.files.push(...result.attachments);
      }
      this.renderFiles();

      // Update attachment count in store for immediate board update
      store.updateTask(this.taskId, { attachmentCount: this.files.length });

      this.showSuccess('Datei hochgeladen');
    } catch (error) {
      console.error('Upload error:', error);
      this.showError('Fehler beim Hochladen');
    }
  }

  async downloadFile(file) {
    const projectId = store.get('currentProjectId');
    const fileName = file.originalName || file.original_name;

    try {
      await api.downloadTaskFile(projectId, this.taskId, file.id, fileName);
    } catch (error) {
      this.showError('Fehler beim Herunterladen');
    }
  }

  async deleteFile(fileId) {
    window.dispatchEvent(new CustomEvent('confirm:show', {
      detail: {
        message: 'Möchten Sie diese Datei wirklich löschen?',
        confirmText: 'Löschen',
        confirmClass: 'btn-danger',
        onConfirm: async () => {
          try {
            const projectId = store.get('currentProjectId');
            await api.deleteFile(projectId, this.taskId, fileId);
            this.files = this.files.filter(f => f.id !== fileId);
            this.renderFiles();

            // Update attachment count in store for immediate board update
            store.updateTask(this.taskId, { attachmentCount: this.files.length });
          } catch (error) {
            this.showError('Fehler beim Löschen');
          }
        }
      }
    }));
  }

  openLightbox(file) {
    const projectId = store.get('currentProjectId');
    const imageUrl = api.getFilePreviewUrl(projectId, this.taskId, file.id);

    window.dispatchEvent(new CustomEvent('lightbox:open', {
      detail: { imageUrl, filename: file.original_name }
    }));
  }

  // =====================
  // COMMENTS
  // =====================

  async addComment() {
    const input = $('#comment-input');
    const content = input?.value.trim();

    if (!content || !this.taskId) return;

    try {
      const projectId = store.get('currentProjectId');
      const comment = await api.createComment(projectId, this.taskId, { content });
      this.comments.push(comment);
      this.renderComments();
      input.value = '';

      // Update comment count in store for immediate board update
      store.updateTask(this.taskId, { commentCount: this.comments.length });

      // Notify typing stopped
      syncManager.notifyTyping(this.taskId, false);
    } catch (error) {
      this.showError('Fehler beim Hinzufügen');
    }
  }

  // =====================
  // LABELS
  // =====================

  openLabelModal() {
    window.dispatchEvent(new CustomEvent('modal:open', {
      detail: { modalId: 'label-modal', mode: 'create' }
    }));
  }

  async updateLabels() {
    if (this.mode !== 'edit' || !this.taskId) return;

    const labelIds = this.getSelectedLabels();

    try {
      const projectId = store.get('currentProjectId');
      await api.updateTask(projectId, this.taskId, { label_ids: labelIds });
    } catch (error) {
      this.showError('Fehler beim Aktualisieren der Labels');
    }
  }

  // =====================
  // HELPERS
  // =====================

  showError(message) {
    window.dispatchEvent(new CustomEvent('toast:show', {
      detail: { message, type: 'error' }
    }));
  }

  showSuccess(message) {
    window.dispatchEvent(new CustomEvent('toast:show', {
      detail: { message, type: 'success' }
    }));
  }
}

// Create and export singleton
const taskModalManager = new TaskModalManager();

export default taskModalManager;
