/**
 * TASKMATE - Calendar View Module
 * ================================
 * Calendar view for tasks with week and month views
 */

import store from './store.js';
import {
  $, $$, createElement, clearElement, formatDate,
  getDueDateStatus, filterTasks, createPriorityElement
} from './utils.js';

class CalendarViewManager {
  constructor() {
    this.container = null;
    this.currentDate = new Date();
    this.selectedDate = null;
    this.dayDetailPopup = null;
    this.viewMode = 'month'; // 'month' or 'week'

    // Dynamic filter states - keys are filter category names, values are booleans
    this.enabledFilters = {};
    this.filterMenuOpen = false;

    // Calendar-specific search
    this.highlightedTaskId = null;
    this.searchQuery = '';

    this.init();
  }

  init() {
    this.container = $('#view-calendar');

    // Set initial view mode on calendar grid
    const grid = $('#calendar-grid');
    if (grid) {
      grid.classList.add('calendar-month-view');
    }

    this.bindEvents();

    // Subscribe to store changes
    store.subscribe('tasks', () => this.render());
    store.subscribe('reminders', () => this.render());
    store.subscribe('filters', (filters) => {
      // Calendar-specific search behavior
      if (store.get('currentView') === 'calendar') {
        this.handleCalendarSearch(filters.search || '');
      }
    });
    store.subscribe('searchResultIds', () => this.render());
    store.subscribe('currentView', (view) => {
      if (view === 'calendar') {
        // Re-apply search when switching to calendar view
        const currentSearch = store.get('filters')?.search || '';
        if (currentSearch) {
          this.handleCalendarSearch(currentSearch);
        } else {
          this.render();
        }
      }
    });
  }

  bindEvents() {
    // Navigation buttons
    $('#btn-prev-period')?.addEventListener('click', () => this.navigate(-1));
    $('#btn-next-period')?.addEventListener('click', () => this.navigate(1));
    $('#btn-today')?.addEventListener('click', () => this.goToToday());

    // View toggle buttons
    $$('[data-calendar-view]').forEach(btn => {
      btn.addEventListener('click', (e) => {
        const newView = e.target.dataset.calendarView;
        this.setViewMode(newView);
      });
    });

    // Filter dropdown toggle
    $('#btn-calendar-filter')?.addEventListener('click', (e) => {
      e.stopPropagation();
      this.toggleFilterMenu();
    });

    // Close filter menu when clicking outside
    document.addEventListener('click', (e) => {
      if (this.filterMenuOpen && !e.target.closest('.calendar-filter-dropdown')) {
        this.closeFilterMenu();
      }
    });

    // Subscribe to columns changes to update filters and colors
    store.subscribe('columns', () => {
      this.renderFilterMenu();
      this.render(); // Update task colors when column colors change
    });

    // Calendar day clicks
    $('#calendar-grid')?.addEventListener('click', (e) => this.handleDayClick(e));

    // Close popup on outside click
    document.addEventListener('click', (e) => {
      if (this.dayDetailPopup && !this.dayDetailPopup.contains(e.target) &&
          !e.target.closest('.calendar-day') && !e.target.closest('.calendar-week-day')) {
        this.closeDayDetail();
      }
    });
  }

  // =====================
  // VIEW MODE
  // =====================

  setViewMode(mode) {
    this.viewMode = mode;

    // Update toggle buttons
    $$('[data-calendar-view]').forEach(btn => {
      btn.classList.toggle('active', btn.dataset.calendarView === mode);
    });

    // Update grid class
    const grid = $('#calendar-grid');
    if (grid) {
      grid.classList.remove('calendar-month-view', 'calendar-week-view');
      grid.classList.add(`calendar-${mode}-view`);
    }

    // Show/hide weekday headers based on view mode
    const weekdaysHeader = $('#calendar-weekdays');
    if (weekdaysHeader) {
      weekdaysHeader.style.display = mode === 'month' ? 'grid' : 'none';
    }

    this.render();
  }

  // =====================
  // NAVIGATION
  // =====================

  navigate(delta) {
    if (this.viewMode === 'month') {
      this.currentDate = new Date(
        this.currentDate.getFullYear(),
        this.currentDate.getMonth() + delta,
        1
      );
    } else {
      // Week view - navigate by 7 days
      const newDate = new Date(this.currentDate);
      newDate.setDate(newDate.getDate() + (delta * 7));
      this.currentDate = newDate;
    }
    this.render();
  }

  goToToday() {
    this.currentDate = new Date();
    this.highlightedTaskId = null;
    this.searchQuery = '';
    this.render();
  }

  // =====================
  // CALENDAR SEARCH
  // =====================

  handleCalendarSearch(query) {
    this.searchQuery = query.trim().toLowerCase();

    if (!this.searchQuery) {
      // Clear search - reset highlight and just re-render
      this.highlightedTaskId = null;
      this.render();
      return;
    }

    // Find tasks matching the title
    const tasks = store.get('tasks').filter(t => !t.archived);
    const matchingTasks = tasks.filter(t =>
      t.title && t.title.toLowerCase().includes(this.searchQuery)
    );

    if (matchingTasks.length === 0) {
      // No matches - clear highlight
      this.highlightedTaskId = null;
      this.render();
      return;
    }

    // Find the first task with a start date or due date
    const taskWithDate = matchingTasks.find(t => t.startDate || t.dueDate);

    if (taskWithDate) {
      this.highlightedTaskId = taskWithDate.id;

      // Navigate to the task's start date (or due date if no start)
      const targetDate = taskWithDate.startDate || taskWithDate.dueDate;
      if (targetDate) {
        this.navigateToDate(targetDate);
      }
    } else {
      // Highlight first match even if no date
      this.highlightedTaskId = matchingTasks[0].id;
      this.render();
    }
  }

  navigateToDate(dateString) {
    const date = new Date(dateString);

    // Set current date to the month/week containing this date
    this.currentDate = new Date(date.getFullYear(), date.getMonth(), 1);

    // For week view, adjust to the week containing the date
    if (this.viewMode === 'week') {
      this.currentDate = this.getWeekStart(date);
    }

    this.render();

    // Scroll the highlighted task into view after render
    setTimeout(() => {
      const highlightedEl = $('.calendar-task.search-highlight, .calendar-week-task.search-highlight');
      if (highlightedEl) {
        highlightedEl.scrollIntoView({ behavior: 'smooth', block: 'center' });
      }
    }, 100);
  }

  clearSearch() {
    this.highlightedTaskId = null;
    this.searchQuery = '';
    this.render();
  }

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

  render() {
    if (store.get('currentView') !== 'calendar') return;

    // Ensure calendar grid exists and has correct class
    const grid = $('#calendar-grid');
    if (!grid) return;

    grid.classList.remove('calendar-month-view', 'calendar-week-view');
    grid.classList.add(`calendar-${this.viewMode}-view`);

    // Ensure weekday headers visibility matches current view mode
    const weekdaysHeader = $('#calendar-weekdays');
    if (weekdaysHeader) {
      weekdaysHeader.style.display = this.viewMode === 'month' ? 'grid' : 'none';
    }

    this.updateHeader();

    // Force a small delay to ensure DOM is ready
    setTimeout(() => {
      if (this.viewMode === 'month') {
        this.renderMonthView();
      } else {
        this.renderWeekView();
      }
    }, 10);
  }

  updateHeader() {
    const titleEl = $('#calendar-title');
    if (!titleEl) return;

    if (this.viewMode === 'month') {
      const options = { month: 'long', year: 'numeric' };
      titleEl.textContent = this.currentDate.toLocaleDateString('de-DE', options);
    } else {
      // Week view - show week range
      const weekStart = this.getWeekStart(this.currentDate);
      const weekEnd = new Date(weekStart);
      weekEnd.setDate(weekEnd.getDate() + 6);

      const startStr = weekStart.toLocaleDateString('de-DE', { day: 'numeric', month: 'short' });
      const endStr = weekEnd.toLocaleDateString('de-DE', { day: 'numeric', month: 'short', year: 'numeric' });
      titleEl.textContent = `${startStr} - ${endStr}`;
    }
  }

  // =====================
  // MONTH VIEW
  // =====================

  renderMonthView() {
    const daysContainer = $('#calendar-grid');
    if (!daysContainer) {
      console.warn('[Calendar] calendar-grid not found for month view');
      return;
    }

    // Ensure correct classes are set
    daysContainer.classList.remove('calendar-week-view');
    daysContainer.classList.add('calendar-month-view');

    clearElement(daysContainer);

    const year = this.currentDate.getFullYear();
    const month = this.currentDate.getMonth();

    // Get first day of month and how many days in month
    const firstDay = new Date(year, month, 1);
    const lastDay = new Date(year, month + 1, 0);
    const daysInMonth = lastDay.getDate();

    // Get the starting day of week (0 = Sunday, adjust for Monday start)
    let startingDay = firstDay.getDay();
    startingDay = startingDay === 0 ? 6 : startingDay - 1; // Monday = 0

    // Get tasks by date
    const tasksByDate = this.getTasksByDate();

    // Today for comparison
    const today = new Date();
    const todayString = this.getDateString(today);

    // Fill in days from previous month
    const prevMonthLastDay = new Date(year, month, 0).getDate();
    for (let i = startingDay - 1; i >= 0; i--) {
      const day = prevMonthLastDay - i;
      const date = new Date(year, month - 1, day);
      daysContainer.appendChild(this.createDayElement(date, day, true, tasksByDate));
    }

    // Fill in days of current month
    for (let day = 1; day <= daysInMonth; day++) {
      const date = new Date(year, month, day);
      const dateString = this.getDateString(date);
      const isToday = dateString === todayString;
      daysContainer.appendChild(this.createDayElement(date, day, false, tasksByDate, isToday));
    }

    // Fill in days from next month
    const totalCells = startingDay + daysInMonth;
    const remainingCells = totalCells % 7 === 0 ? 0 : 7 - (totalCells % 7);
    for (let day = 1; day <= remainingCells; day++) {
      const date = new Date(year, month + 1, day);
      daysContainer.appendChild(this.createDayElement(date, day, true, tasksByDate));
    }
  }

  // =====================
  // WEEK VIEW
  // =====================

  renderWeekView() {
    const daysContainer = $('#calendar-grid');
    if (!daysContainer) return;

    clearElement(daysContainer);

    const weekStart = this.getWeekStart(this.currentDate);
    const tasksByDate = this.getTasksByDate();
    const today = new Date();
    const todayString = this.getDateString(today);

    // Create 7 days for the week
    for (let i = 0; i < 7; i++) {
      const date = new Date(weekStart);
      date.setDate(weekStart.getDate() + i);
      const dateString = this.getDateString(date);
      const isToday = dateString === todayString;

      daysContainer.appendChild(this.createWeekDayElement(date, tasksByDate, isToday, weekStart));
    }
  }

  createWeekDayElement(date, tasksByDate, isToday = false, weekStart = null) {
    const dateString = this.getDateString(date);
    const dayTasks = tasksByDate[dateString] || [];
    const remindersByDate = this.getRemindersByDate();
    const dayReminders = remindersByDate[dateString] || [];
    const hasOverdue = dayTasks.some(t => this.isTaskOverdue(t));

    const classes = ['calendar-week-day'];
    if (isToday) classes.push('today');
    if (dayTasks.length > 0 || dayReminders.length > 0) classes.push('has-tasks');
    if (hasOverdue) classes.push('has-overdue');

    const dayEl = createElement('div', {
      className: classes.join(' '),
      dataset: { date: dateString }
    });

    // Day header with date
    const dayHeader = createElement('div', { className: 'calendar-week-day-header' }, [
      createElement('span', { className: 'calendar-week-day-name' }, [
        date.toLocaleDateString('de-DE', { weekday: 'short' })
      ]),
      createElement('span', { className: `calendar-week-day-number ${isToday ? 'today' : ''}` }, [
        date.getDate().toString()
      ])
    ]);
    dayEl.appendChild(dayHeader);

    // Tasks container
    const tasksContainer = createElement('div', { className: 'calendar-week-day-tasks' });

    // Combined array of reminders and tasks
    const allItems = [];
    
    // Add tasks first (wichtig für kontinuierliche Balken)
    dayTasks.forEach(task => {
      allItems.push({
        type: 'task',
        ...task
      });
    });
    
    // Add reminders after tasks
    dayReminders.forEach(reminder => {
      allItems.push({
        type: 'reminder',
        id: reminder.id,
        title: reminder.title,
        color: reminder.color || '#F59E0B',
        time: reminder.reminder_time
      });
    });

    if (allItems.length === 0) {
      tasksContainer.appendChild(createElement('div', {
        className: 'calendar-week-empty'
      }, ['Keine Aufgaben']));
    } else {
      allItems.forEach(item => {
        if (item.type === 'reminder') {
          // Create reminder element
          const reminderEl = createElement('div', {
            className: 'calendar-week-task calendar-reminder-item',
            dataset: { reminderId: item.id },
            title: `Erinnerung: ${item.title}${item.time ? ' um ' + item.time : ''}`,
            onclick: (e) => {
              e.stopPropagation();
              this.editReminder(item.id);
            }
          });

          // Add title and bell icon
          reminderEl.appendChild(createElement('span', { className: 'calendar-week-task-title' }, [item.title]));
          reminderEl.appendChild(createElement('span', { className: 'calendar-reminder-bell' }, ['🔔']));

          // Apply color
          reminderEl.style.backgroundColor = `${item.color}25`;
          reminderEl.style.borderLeftColor = item.color;

          tasksContainer.appendChild(reminderEl);
        } else {
          // Existing task rendering code
          const task = item;
        // Get column color and user badge info
        const columnColor = this.getColumnColor(task);
        const userBadge = this.getUserBadgeInfo(task);

        // Build class list
        const taskClasses = ['calendar-week-task'];
        if (this.isTaskOverdue(task)) taskClasses.push('overdue');
        if (task.hasRange) {
          taskClasses.push('has-range');
          if (task.isRangeStart) taskClasses.push('range-start');
          if (task.isRangeMiddle) taskClasses.push('range-middle');
          if (task.isRangeEnd) taskClasses.push('range-end');
        }
        // Add search highlight
        if (this.highlightedTaskId === task.id) {
          taskClasses.push('search-highlight');
        }

        // Check if this is the first day of the week or the start of the task
        const isFirstDayOfWeek = weekStart && this.getDateString(date) === this.getDateString(weekStart);
        const showContent = task.isRangeStart || !task.hasRange || isFirstDayOfWeek;

        // Build task element children
        const children = [];

        // Add title (only at start of task or first day of week)
        if (showContent) {
          children.push(createElement('span', { className: 'calendar-week-task-title' }, [task.title]));
        }

        // Add user badges if assigned (only at start of task or first day of week, supports multiple)
        if (userBadge && userBadge.length > 0 && showContent) {
          const badgeContainer = createElement('span', { className: 'calendar-task-badges' });
          userBadge.forEach(badge => {
            const badgeEl = createElement('span', { className: 'calendar-task-user-badge' }, [badge.initials]);
            badgeEl.style.backgroundColor = badge.color;
            badgeContainer.appendChild(badgeEl);
          });
          children.push(badgeContainer);
        }

        const taskEl = createElement('div', {
          className: taskClasses.join(' '),
          dataset: { taskId: task.id },
          title: this.getTaskTooltip(task)
        }, children);

        // Apply column color
        taskEl.style.backgroundColor = `${columnColor}25`;
        if (task.isRangeStart || !task.hasRange) {
          taskEl.style.borderLeftColor = columnColor;
        }

        tasksContainer.appendChild(taskEl);
        }
      });
    }

    dayEl.appendChild(tasksContainer);

    // Add task button
    const addBtn = createElement('button', {
      className: 'calendar-week-add-task',
      onclick: (e) => {
        e.stopPropagation();
        this.createTaskForDate(dateString);
      }
    }, ['Aufgabe hinzufügen']);
    dayEl.appendChild(addBtn);

    // Add reminder button
    const addReminderBtn = createElement('button', {
      className: 'calendar-week-add-reminder',
      onclick: (e) => {
        e.stopPropagation();
        this.createReminderForDate(dateString);
      }
    }, ['Erinnerung hinzufügen']);
    dayEl.appendChild(addReminderBtn);

    return dayEl;
  }

  getWeekStart(date) {
    const d = new Date(date);
    const day = d.getDay();
    const diff = d.getDate() - day + (day === 0 ? -6 : 1); // Adjust for Monday start
    return new Date(d.setDate(diff));
  }

  // =====================
  // MONTH VIEW DAY ELEMENT
  // =====================

  createDayElement(date, dayNumber, isOtherMonth, tasksByDate, isToday = false) {
    const dateString = this.getDateString(date);
    const dayTasks = tasksByDate[dateString] || [];
    const remindersByDate = this.getRemindersByDate();
    const dayReminders = remindersByDate[dateString] || [];
    const hasOverdue = dayTasks.some(t => this.isTaskOverdue(t));

    const classes = ['calendar-day'];
    if (isOtherMonth) classes.push('other-month');
    if (isToday) classes.push('today');
    if (dayTasks.length > 0 || dayReminders.length > 0) classes.push('has-tasks');
    if (hasOverdue) classes.push('has-overdue');

    const dayEl = createElement('div', {
      className: classes.join(' '),
      dataset: { date: dateString }
    });

    // Day number
    dayEl.appendChild(createElement('span', {
      className: 'calendar-day-number'
    }, [dayNumber.toString()]));

    // Combined container for reminders and tasks
    const allItems = [];
    
    // Add tasks first (wichtig für kontinuierliche Balken)
    dayTasks.forEach(task => {
      allItems.push({
        type: 'task',
        ...task
      });
    });
    
    // Add reminders after tasks
    dayReminders.forEach(reminder => {
      allItems.push({
        type: 'reminder',
        id: reminder.id,
        title: reminder.title,
        color: reminder.color || '#F59E0B',
        time: reminder.reminder_time
      });
    });

    // Show max 3 items
    if (allItems.length > 0) {
      const tasksContainer = createElement('div', { className: 'calendar-day-tasks' });

      allItems.slice(0, 3).forEach(item => {
        if (item.type === 'reminder') {
          // Create reminder element
          const reminderEl = createElement('div', {
            className: 'calendar-task calendar-reminder-item',
            dataset: { reminderId: item.id },
            title: `Erinnerung: ${item.title}${item.time ? ' um ' + item.time : ''}`,
            onclick: (e) => {
              e.stopPropagation();
              this.editReminder(item.id);
            }
          });

          // Add title and bell icon
          reminderEl.appendChild(createElement('span', { className: 'calendar-task-title' }, [item.title]));
          reminderEl.appendChild(createElement('span', { className: 'calendar-reminder-bell' }, ['🔔']));

          // Apply color
          reminderEl.style.backgroundColor = `${item.color}40`;
          reminderEl.style.borderLeftColor = item.color;

          tasksContainer.appendChild(reminderEl);
        } else {
          // Existing task rendering code
          const task = item;
        // Get column color and user badge info
        const columnColor = this.getColumnColor(task);
        const userBadge = this.getUserBadgeInfo(task);

        // Build class list
        const taskClasses = ['calendar-task'];
        if (this.isTaskOverdue(task)) taskClasses.push('overdue');
        if (task.hasRange) {
          taskClasses.push('has-range');
          if (task.isRangeStart) taskClasses.push('range-start');
          if (task.isRangeMiddle) taskClasses.push('range-middle');
          if (task.isRangeEnd) taskClasses.push('range-end');
        }
        // Add search highlight
        if (this.highlightedTaskId === task.id) {
          taskClasses.push('search-highlight');
        }

        // Build content - show title and optional user badge
        const taskEl = createElement('div', {
          className: taskClasses.join(' '),
          dataset: { taskId: task.id },
          title: this.getTaskTooltip(task)
        });

        // Add title (not for middle parts of range)
        if (!task.isRangeMiddle) {
          taskEl.appendChild(createElement('span', { className: 'calendar-task-title' }, [task.title]));
        }

        // Add user badges if assigned (only on start or single-day tasks, supports multiple)
        if (userBadge && userBadge.length > 0 && (task.isRangeStart || !task.hasRange)) {
          const badgeContainer = createElement('span', { className: 'calendar-task-badges' });
          userBadge.forEach(badge => {
            const badgeEl = createElement('span', { className: 'calendar-task-user-badge' }, [badge.initials]);
            badgeEl.style.backgroundColor = badge.color;
            badgeContainer.appendChild(badgeEl);
          });
          taskEl.appendChild(badgeContainer);
        }

        // Apply column color
        taskEl.style.backgroundColor = `${columnColor}40`;
        if (task.isRangeStart || !task.hasRange) {
          taskEl.style.borderLeftColor = columnColor;
        }

        tasksContainer.appendChild(taskEl);
        }
      });

      if (allItems.length > 3) {
        tasksContainer.appendChild(createElement('div', {
          className: 'calendar-more'
        }, [`+${allItems.length - 3} weitere`]));
      }

      dayEl.appendChild(tasksContainer);
    }

    return dayEl;
  }

  // =====================
  // DATA
  // =====================

  getTasksByDate() {
    const tasks = store.get('tasks').filter(t => !t.archived && (t.dueDate || t.startDate));
    const filters = store.get('filters');
    const columns = store.get('columns');
    // Calendar uses its own search logic, so ignore the general search filter
    const filtersWithoutSearch = { ...filters, search: '', dueDate: 'all' };
    let filteredTasks = filterTasks(tasks, filtersWithoutSearch, [], columns); // Ignore search and due date filter for calendar

    // Filter tasks based on filter category checkboxes
    // EXCEPTION: During active search, show all tasks (ignore checkbox filters)
    const isSearchActive = this.searchQuery && this.searchQuery.length > 0;
    if (columns.length > 0 && !isSearchActive) {
      // Build a map of columnId -> filterCategory
      const columnFilterMap = {};
      columns.forEach(col => {
        columnFilterMap[col.id] = col.filterCategory || 'in_progress';
      });

      filteredTasks = filteredTasks.filter(task => {
        const filterCategory = columnFilterMap[task.columnId];
        // If column has 'in_progress' filter category, check if 'in_progress' filter is enabled
        if (filterCategory === 'in_progress') {
          return this.enabledFilters['in_progress'] !== false;
        }
        // For other categories, check their specific filter state
        if (this.enabledFilters[filterCategory] === undefined) {
          // Default: show in_progress, hide open and completed
          return filterCategory === 'in_progress';
        }
        return this.enabledFilters[filterCategory];
      });
    }

    // Sort tasks: Range tasks first (to ensure continuous bars), then single-day tasks
    filteredTasks.sort((a, b) => {
      const startA = a.startDate || a.dueDate || '';
      const startB = b.startDate || b.dueDate || '';
      const endA = a.dueDate || '';
      const endB = b.dueDate || '';
      
      // Check if task has range (both start and end date, and they're different)
      const hasRangeA = a.startDate && a.dueDate && a.startDate !== a.dueDate;
      const hasRangeB = b.startDate && b.dueDate && b.startDate !== b.dueDate;
      
      // Range tasks come first
      if (hasRangeA && !hasRangeB) return -1;
      if (!hasRangeA && hasRangeB) return 1;
      
      // If both have ranges or both are single-day, sort by start date
      if (startA !== startB) {
        return startA.localeCompare(startB);
      }
      
      // Same start date: sort by end date (longer ranges first)
      if (endA !== endB) {
        return endB.localeCompare(endA); // Descending to put longer ranges first
      }

      // Same dates: sort alphabetically by title
      return (a.title || '').localeCompare(b.title || '', 'de');
    });

    const tasksByDate = {};

    // Process tasks in sorted order to maintain consistent positioning across all days
    filteredTasks.forEach(task => {
      const startDateStr = task.startDate ? task.startDate.split('T')[0] : null;
      const endDateStr = task.dueDate ? task.dueDate.split('T')[0] : null;

      // If task has both start and end date, add to all days in range
      if (startDateStr && endDateStr) {
        const start = new Date(startDateStr);
        const end = new Date(endDateStr);
        const current = new Date(start);

        while (current <= end) {
          const dateKey = this.getDateString(current);
          if (!tasksByDate[dateKey]) {
            tasksByDate[dateKey] = [];
          }
          // Add task with position info for multi-day display
          const taskWithRange = {
            ...task,
            isRangeStart: dateKey === startDateStr,
            isRangeEnd: dateKey === endDateStr,
            isRangeMiddle: dateKey !== startDateStr && dateKey !== endDateStr,
            hasRange: true
          };
          tasksByDate[dateKey].push(taskWithRange);
          current.setDate(current.getDate() + 1);
        }
      } else {
        // Single date task (either start or end)
        const dateKey = endDateStr || startDateStr;
        if (dateKey) {
          if (!tasksByDate[dateKey]) {
            tasksByDate[dateKey] = [];
          }
          tasksByDate[dateKey].push({ ...task, hasRange: false });
        }
      }
    });

    return tasksByDate;
  }

  getRemindersByDate() {
    const reminders = store.get('reminders') || [];
    if (!Array.isArray(reminders)) {
      console.warn('[Calendar] Reminders not available or not an array');
      return {};
    }
    
    const activeReminders = reminders.filter(r => r.is_active);
    const remindersByDate = {};

    activeReminders.forEach(reminder => {
      const date = reminder.reminder_date;
      if (!remindersByDate[date]) {
        remindersByDate[date] = [];
      }
      remindersByDate[date].push(reminder);
    });

    // Sort reminders by time within each date
    Object.keys(remindersByDate).forEach(date => {
      remindersByDate[date].sort((a, b) => (a.reminder_time || '09:00').localeCompare(b.reminder_time || '09:00'));
    });

    return remindersByDate;
  }

  getDateString(date) {
    // Use local date components instead of toISOString() which converts to UTC
    // This fixes the issue where the date is off by one day due to timezone differences
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    return `${year}-${month}-${day}`;
  }

  // =====================
  // DAY DETAIL POPUP
  // =====================

  handleDayClick(e) {
    console.log('[Calendar] Day click event:', e.target, 'View mode:', this.viewMode);
    
    // Check if clicked on a specific task
    const taskEl = e.target.closest('.calendar-task, .calendar-week-task');
    if (taskEl) {
      console.log('[Calendar] Task clicked:', taskEl.dataset.taskId);
      const taskId = parseInt(taskEl.dataset.taskId);
      this.openTaskModal(taskId);
      return;
    }

    // Check if clicked on add button (week view)
    if (e.target.closest('.calendar-week-add-task')) {
      console.log('[Calendar] Add task button clicked');
      return; // Already handled by onclick
    }

    // Show day detail popup for both month and week view
    if (this.viewMode === 'month') {
      const dayEl = e.target.closest('.calendar-day');
      if (!dayEl) return;

      console.log('[Calendar] Month day clicked:', dayEl.dataset.date);
      const dateString = dayEl.dataset.date;
      this.showDayDetail(dateString, dayEl);
    } else if (this.viewMode === 'week') {
      const dayEl = e.target.closest('.calendar-week-day');
      console.log('[Calendar] Week day element found:', !!dayEl);
      if (!dayEl) return;

      console.log('[Calendar] Week day clicked:', dayEl.dataset.date);
      const dateString = dayEl.dataset.date;
      this.showDayDetail(dateString, dayEl);
    }
  }

  showDayDetail(dateString, anchorEl) {
    console.log('[Calendar] showDayDetail called:', dateString, anchorEl);
    this.closeDayDetail();

    const tasksByDate = this.getTasksByDate();
    const dayTasks = tasksByDate[dateString] || [];
    console.log('[Calendar] Tasks for date:', dayTasks.length);

    const date = new Date(dateString);
    const dateDisplay = date.toLocaleDateString('de-DE', {
      weekday: 'long',
      day: 'numeric',
      month: 'long',
      year: 'numeric'
    });

    const popup = createElement('div', {
      className: 'calendar-day-detail'
    });

    // Header
    const header = createElement('div', { className: 'calendar-day-detail-header' }, [
      createElement('span', { className: 'calendar-day-detail-date' }, [dateDisplay]),
      createElement('button', {
        className: 'btn btn-icon btn-ghost',
        onclick: () => this.closeDayDetail()
      }, ['×'])
    ]);
    popup.appendChild(header);

    // Tasks list
    const tasksList = createElement('div', { className: 'calendar-day-detail-tasks' });

    if (dayTasks.length === 0) {
      tasksList.appendChild(createElement('p', {
        className: 'text-secondary',
        style: { textAlign: 'center', padding: 'var(--spacing-md)' }
      }, ['Keine Aufgaben']));
    } else {
      dayTasks.forEach(task => {
        const taskItem = createElement('div', {
          className: 'calendar-detail-task',
          dataset: { taskId: task.id },
          onclick: () => this.openTaskModal(task.id)
        }, [
          createPriorityElement(task.priority),
          createElement('span', { className: 'calendar-detail-title' }, [task.title])
        ]);

        tasksList.appendChild(taskItem);
      });
    }

    popup.appendChild(tasksList);

    // Add task button
    popup.appendChild(createElement('button', {
      className: 'btn btn-primary btn-block',
      style: { marginTop: 'var(--spacing-md)' },
      onclick: () => this.createTaskForDate(dateString)
    }, ['Aufgabe hinzufügen']));

    // Add reminder button
    popup.appendChild(createElement('button', {
      className: 'btn btn-reminder-secondary btn-block',
      style: { marginTop: 'var(--spacing-sm)' },
      onclick: () => this.createReminderForDate(dateString)
    }));

    // Add HTML content with SVG icon
    const button = popup.lastElementChild;
    button.innerHTML = '<svg class="icon" viewBox="0 0 24 24" width="18" height="18" style="margin-right: 6px; flex-shrink: 0;"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9M13.73 21a2 2 0 0 1-3.46 0" stroke="white" stroke-width="2" fill="none"></path></svg> Erinnerung hinzufügen';

    // Position popup - different logic for week vs month view
    const rect = anchorEl.getBoundingClientRect();
    const popupHeight = 400; // Estimated max height
    const popupWidth = 350;
    const padding = 8;
    
    let popupTop, popupLeft;
    
    if (this.viewMode === 'week') {
      // For week view, position at the top of the day element
      popupTop = Math.max(150, rect.top + 50); // Ensure it's visible, minimum 150px from top
    } else {
      // For month view, position below the day element
      popupTop = rect.bottom + padding;
      
      // Check if popup would go below viewport
      if (popupTop + popupHeight > window.innerHeight - padding) {
        // Position above the element instead
        popupTop = rect.top - popupHeight - padding;
        
        // If still not enough space above, position at bottom of viewport
        if (popupTop < padding) {
          popupTop = window.innerHeight - popupHeight - padding;
        }
      }
    }
    
    // Horizontal positioning
    popupLeft = rect.left;
    
    // Check if popup would go beyond right edge
    if (popupLeft + popupWidth > window.innerWidth - padding) {
      popupLeft = window.innerWidth - popupWidth - padding;
    }
    
    // Check if popup would go beyond left edge
    if (popupLeft < padding) {
      popupLeft = padding;
    }
    
    popup.style.top = `${popupTop}px`;
    popup.style.left = `${popupLeft}px`;
    console.log('[Calendar] Popup positioning for', this.viewMode, '- Top:', popup.style.top, 'Left:', popup.style.left);

    document.body.appendChild(popup);
    this.dayDetailPopup = popup;
    console.log('[Calendar] Popup created and appended to body');
  }

  closeDayDetail() {
    if (this.dayDetailPopup) {
      this.dayDetailPopup.remove();
      this.dayDetailPopup = null;
    }
  }

  // =====================
  // ACTIONS
  // =====================

  openTaskModal(taskId) {
    this.closeDayDetail();

    window.dispatchEvent(new CustomEvent('modal:open', {
      detail: {
        modalId: 'task-modal',
        mode: 'edit',
        data: { taskId }
      }
    }));
  }

  createTaskForDate(dateString) {
    this.closeDayDetail();

    const columns = store.get('columns');
    const firstColumn = columns[0];

    window.dispatchEvent(new CustomEvent('modal:open', {
      detail: {
        modalId: 'task-modal',
        mode: 'create',
        data: {
          columnId: firstColumn?.id,
          prefill: {
            dueDate: dateString
          }
        }
      }
    }));
  }

  createReminderForDate(dateString) {
    this.closeDayDetail();

    window.dispatchEvent(new CustomEvent('modal:open', {
      detail: {
        modalId: 'reminder-modal',
        mode: 'create',
        data: {
          prefill: {
            date: dateString
          }
        }
      }
    }));
  }

  showRemindersForDate(dateString, anchorEl) {
    const reminders = this.getRemindersByDate();
    const dayReminders = reminders[dateString] || [];
    
    if (dayReminders.length === 0) return;

    // Close existing popup
    this.closeDayDetail();

    // Create popup
    const popup = createElement('div', {
      className: 'calendar-day-detail calendar-reminder-detail',
      onclick: (e) => e.stopPropagation()
    });
    
    this.dayDetailPopup = popup;

    // Header
    const header = createElement('h3', {}, [`Erinnerungen für ${formatDate(dateString)}`]);
    popup.appendChild(header);

    // Reminders list
    const remindersList = createElement('div', { className: 'calendar-detail-reminders' });
    
    dayReminders.forEach(reminder => {
      // Create reminder content (clickable for edit)
      const reminderContent = createElement('div', {
        className: 'reminder-content',
        onclick: () => this.editReminder(reminder.id)
      }, [
        createElement('div', { 
          className: 'reminder-time',
          style: { color: reminder.color || '#F59E0B' }
        }, [reminder.reminder_time || '09:00']),
        createElement('div', { className: 'reminder-title' }, [reminder.title]),
        reminder.description ? createElement('div', { className: 'reminder-description' }, [reminder.description]) : null
      ].filter(Boolean));

      // Create delete button
      const deleteBtn = createElement('button', {
        className: 'reminder-delete-btn',
        title: 'Erinnerung löschen',
        onclick: (e) => {
          e.stopPropagation();
          this.deleteReminder(reminder.id, reminder.title);
        }
      }, [
        createElement('svg', {
          viewBox: '0 0 24 24',
          width: '16',
          height: '16'
        }, [
          createElement('path', {
            d: 'M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16',
            stroke: 'currentColor',
            'stroke-width': '2',
            fill: 'none',
            'stroke-linecap': 'round',
            'stroke-linejoin': 'round'
          })
        ])
      ]);

      // Container with content and delete button
      const reminderItem = createElement('div', {
        className: 'calendar-detail-reminder'
      }, [reminderContent, deleteBtn]);

      remindersList.appendChild(reminderItem);
    });

    popup.appendChild(remindersList);

    // Add reminder button
    popup.appendChild(createElement('button', {
      className: 'btn btn-reminder-secondary btn-block',
      style: { marginTop: 'var(--spacing-md)' },
      onclick: () => this.createReminderForDate(dateString)
    }, ['Weitere Erinnerung']));

    // Position popup
    const rect = anchorEl.getBoundingClientRect();
    const popupHeight = 400; // Estimated max height
    const popupWidth = 350;
    const padding = 8;
    
    let popupTop = rect.bottom + padding;
    let popupLeft = rect.left;
    
    // Check if popup would go below viewport
    if (popupTop + popupHeight > window.innerHeight - padding) {
      // Position above the element instead
      popupTop = rect.top - popupHeight - padding;
      
      // If still not enough space above, position at bottom of viewport
      if (popupTop < padding) {
        popupTop = window.innerHeight - popupHeight - padding;
      }
    }
    
    // Horizontal positioning
    if (popupLeft + popupWidth > window.innerWidth - padding) {
      popupLeft = window.innerWidth - popupWidth - padding;
    }
    
    if (popupLeft < padding) {
      popupLeft = padding;
    }
    
    popup.style.top = `${popupTop}px`;
    popup.style.left = `${popupLeft}px`;

    document.body.appendChild(popup);
  }

  editReminder(reminderId) {
    this.closeDayDetail();

    window.dispatchEvent(new CustomEvent('modal:open', {
      detail: {
        modalId: 'reminder-modal',
        mode: 'edit',
        data: { reminderId }
      }
    }));
  }

  async deleteReminder(reminderId, reminderTitle) {
    if (!confirm(`Erinnerung "${reminderTitle}" wirklich löschen?`)) {
      return;
    }

    try {
      // Import reminder manager if needed
      if (typeof reminderManager !== 'undefined') {
        await reminderManager.deleteReminder(reminderId);
      } else {
        // Fallback direct API call
        await api.request(`/reminders/${reminderId}`, { method: 'DELETE' });
        
        // Update store
        const reminders = store.get('reminders') || [];
        const updatedReminders = reminders.filter(r => r.id !== reminderId);
        store.setReminders(updatedReminders);
      }

      // Close popup and refresh calendar
      this.closeDayDetail();
      this.render();
      
      console.log(`[Calendar] Reminder ${reminderId} deleted`);
    } catch (error) {
      console.error('[Calendar] Failed to delete reminder:', error);
      alert('Fehler beim Löschen der Erinnerung. Bitte versuche es erneut.');
    }
  }

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

  getTaskTooltip(task) {
    const formatDateGerman = (dateStr) => {
      if (!dateStr) return null;
      const date = new Date(dateStr);
      return date.toLocaleDateString('de-DE', { day: '2-digit', month: '2-digit', year: 'numeric' });
    };

    const startDate = formatDateGerman(task.startDate);
    const endDate = formatDateGerman(task.dueDate);

    // Get assigned user names
    const users = store.get('users');
    let assignedNames = [];

    // Neue Mehrfachzuweisung
    if (task.assignees && task.assignees.length > 0) {
      task.assignees.forEach(assignee => {
        const currentUser = users.find(u => u.id === assignee.id);
        const name = currentUser?.display_name || assignee.display_name || assignee.username || '??';
        assignedNames.push(name);
      });
    } else if (task.assignedTo) {
      // Fallback: Alte Einzelzuweisung
      const user = users.find(u => u.id === task.assignedTo);
      if (user) {
        assignedNames.push(user.display_name || user.username);
      }
    }

    let tooltip = task.title;

    if (startDate && endDate) {
      tooltip += `\n(${startDate} - ${endDate})`;
    } else if (endDate) {
      tooltip += `\n(Fällig: ${endDate})`;
    } else if (startDate) {
      tooltip += `\n(Start: ${startDate})`;
    }

    if (assignedNames.length > 0) {
      tooltip += `\nZugewiesen: ${assignedNames.join(', ')}`;
    }

    return tooltip;
  }

  getPriorityColor(priority) {
    const colors = {
      high: 'var(--priority-high)',
      medium: 'var(--priority-medium)',
      low: 'var(--priority-low)'
    };
    return colors[priority] || colors.medium;
  }

  getTaskUserColor(task) {
    const users = store.get('users');
    const hgUser = users.find(u => u.username === 'HG');
    const mhUser = users.find(u => u.username === 'MH');

    // Check if task is assigned to a user
    if (task.assignedTo) {
      const assignedUser = users.find(u => u.id === task.assignedTo);
      if (assignedUser) {
        return assignedUser.color;
      }
    }

    // Default: no specific color (use neutral)
    return null;
  }

  getColumnColor(task) {
    const columns = store.get('columns');
    const column = columns.find(c => c.id === task.columnId);
    return column?.color || '#6B7280'; // Default gray if no color set
  }

  getUserBadgeInfo(task) {
    const users = store.get('users');
    const badges = [];

    // Neue Mehrfachzuweisung: task.assignees Array
    if (task.assignees && task.assignees.length > 0) {
      task.assignees.forEach(assignee => {
        const currentUser = users.find(u => u.id === assignee.id);
        const initials = currentUser?.initials || assignee.initials || '??';
        const color = currentUser?.color || assignee.color || '#6B7280';
        badges.push({ initials, color });
      });
      return badges.length > 0 ? badges : null;
    }

    // Fallback: Alte Einzelzuweisung
    if (task.assignedTo) {
      const user = users.find(u => u.id === task.assignedTo);
      if (user) {
        const initials = user.initials || '??';
        badges.push({ initials, color: user.color || '#6B7280' });
        return badges;
      }
    }

    return null;
  }

  // Check if task is in the last column (completed)
  isTaskCompleted(task) {
    const columns = store.get('columns');
    if (!columns || columns.length === 0) return false;
    const lastColumnId = columns[columns.length - 1].id;
    return task.columnId === lastColumnId;
  }

  // Check if task should show overdue status (not completed and overdue)
  isTaskOverdue(task) {
    if (this.isTaskCompleted(task)) return false;
    return getDueDateStatus(task.dueDate) === 'overdue';
  }

  // =====================
  // FILTER MENU
  // =====================

  toggleFilterMenu() {
    if (this.filterMenuOpen) {
      this.closeFilterMenu();
    } else {
      this.openFilterMenu();
    }
  }

  openFilterMenu() {
    this.filterMenuOpen = true;
    this.renderFilterMenu();
    $('#calendar-filter-menu')?.classList.remove('hidden');
  }

  closeFilterMenu() {
    this.filterMenuOpen = false;
    $('#calendar-filter-menu')?.classList.add('hidden');
  }

  getUniqueFilterCategories() {
    const columns = store.get('columns') || [];
    const categories = new Map();

    // Standard-Kategorien mit deutschen Labels
    const defaultLabels = {
      'open': 'Offen',
      'in_progress': 'In Arbeit',
      'completed': 'Erledigt'
    };

    columns.forEach(col => {
      const category = col.filterCategory || 'in_progress';
      if (!categories.has(category)) {
        // Für Standard-Kategorien deutschen Label verwenden, sonst den Kategorienamen selbst
        const label = defaultLabels[category] || category;
        categories.set(category, label);
      }
    });

    // Stelle sicher, dass die Standard-Kategorien immer vorhanden sind (in der richtigen Reihenfolge)
    const result = [];
    if (categories.has('open')) {
      result.push({ key: 'open', label: categories.get('open') });
      categories.delete('open');
    }
    if (categories.has('in_progress')) {
      result.push({ key: 'in_progress', label: categories.get('in_progress') });
      categories.delete('in_progress');
    }
    if (categories.has('completed')) {
      result.push({ key: 'completed', label: categories.get('completed') });
      categories.delete('completed');
    }
    // Benutzerdefinierte Kategorien hinzufügen
    categories.forEach((label, key) => {
      result.push({ key, label });
    });

    return result;
  }

  renderFilterMenu() {
    const menu = $('#calendar-filter-menu');
    if (!menu) return;

    const categories = this.getUniqueFilterCategories();

    // Default: in_progress aktiviert, wenn noch keine Filter gesetzt
    if (Object.keys(this.enabledFilters).length === 0) {
      this.enabledFilters['in_progress'] = true;
    }

    menu.innerHTML = categories.map(cat => {
      const isChecked = this.enabledFilters[cat.key] === true;
      return `
        <label class="calendar-filter-item ${isChecked ? 'checked' : ''}">
          <input type="checkbox" data-filter-category="${cat.key}" ${isChecked ? 'checked' : ''}>
          <span>${cat.label}</span>
        </label>
      `;
    }).join('');

    // Event-Listener für Checkboxen
    menu.querySelectorAll('input[type="checkbox"]').forEach(checkbox => {
      checkbox.addEventListener('change', (e) => {
        const category = e.target.dataset.filterCategory;
        this.enabledFilters[category] = e.target.checked;
        e.target.closest('.calendar-filter-item').classList.toggle('checked', e.target.checked);
        this.render();
      });
    });
  }
}

// Create and export singleton
const calendarViewManager = new CalendarViewManager();

export default calendarViewManager;
