{% extends "base.html" %}

{% block title %}{{ _('Calendar') }} - {{ app_name }}{% endblock %}

{% block extra_css %}
<link href="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.15/index.global.min.css" rel="stylesheet">
<link rel="stylesheet" href="{{ url_for('static', filename='calendar.css') }}">
<style>
.event-modal-header { display: flex; justify-content: space-between; align-items: center; flex-wrap: wrap; gap: 0.5rem; }
.event-modal-header h3 { margin: 0; flex: 1; }
.event-modal-header-actions { display: flex; align-items: center; gap: 0.5rem; }
</style>
{% endblock %}

{% block content %}
<div class="container-fluid">
  <div class="row">
    <div class="col-12">
      <div class="card shadow-sm border-0">
        <div class="card-header bg-white">
          <div class="calendar-header">
            <h5 class="mb-0 d-flex align-items-center">
              <i class="fas fa-calendar-alt me-2 text-primary"></i>{{ _('Calendar') }}
            </h5>
            
            <div class="calendar-controls">
              <!-- View Controls -->
              <button class="btn btn-sm btn-outline-secondary" id="todayBtn">
                <i class="fas fa-calendar-day me-1"></i>{{ _('Today') }}
              </button>
              <div class="btn-group">
                <button class="btn btn-sm btn-outline-primary" id="dayBtn">{{ _('Day') }}</button>
                <button class="btn btn-sm btn-outline-primary active" id="weekBtn">{{ _('Week') }}</button>
                <button class="btn btn-sm btn-outline-primary" id="monthBtn">{{ _('Month') }}</button>
                <button class="btn btn-sm btn-outline-primary" id="agendaBtn">{{ _('Agenda') }}</button>
              </div>
              
              <!-- Action Buttons -->
              <button class="btn btn-sm btn-primary" id="newEventBtn">
                <i class="fas fa-plus me-1"></i>{{ _('New Event') }}
              </button>
              <button class="btn btn-sm btn-outline-secondary" id="manageRecurringBtn">
                <i class="fas fa-redo me-1"></i>{{ _('Recurring') }}
              </button>
              
              <!-- Export Dropdown -->
              <div class="dropdown">
                <button class="btn btn-sm btn-outline-secondary dropdown-toggle" type="button" id="exportDropdown" data-bs-toggle="dropdown">
                  <i class="fas fa-download me-1"></i>{{ _('Export') }}
                </button>
                <ul class="dropdown-menu" aria-labelledby="exportDropdown">
                  <li><a class="dropdown-item" href="#" id="exportIcal"><i class="fas fa-calendar me-2"></i>{{ _('iCal Format') }}</a></li>
                  <li><a class="dropdown-item" href="#" id="exportCsv"><i class="fas fa-file-csv me-2"></i>{{ _('CSV Format') }}</a></li>
                </ul>
              </div>
            </div>
          </div>
          
          <!-- Filters Row -->
          <div class="calendar-filters mt-3">
            <select id="filterProject" class="form-select form-select-sm calendar-filter-project">
              <option value="">{{ _('All Projects') }}</option>
              {% for p in projects %}
              <option value="{{ p.id }}">{{ p.name }} ({{ p.client.name if p.client else 'No Client' }})</option>
              {% endfor %}
            </select>
            
            <select id="filterTask" class="form-select form-select-sm calendar-filter-task">
              <option value="">{{ _('All Tasks') }}</option>
            </select>
            
            <input type="text" id="filterTags" class="form-control form-control-sm calendar-filter-tags" placeholder="{{ _('Filter by tags...') }}">
            
            <!-- Quick Filter: Billable Only -->
            <button class="btn btn-sm btn-outline-success" id="filterBillableOnly" title="{{ _('Show billable entries only') }}">
              <i class="fas fa-dollar-sign me-1"></i>{{ _('Billable Only') }}
            </button>
            
            <button class="btn btn-sm btn-outline-danger" id="clearFilters">
              <i class="fas fa-times me-1"></i>{{ _('Clear') }}
            </button>
            
            <select id="assignProject" class="form-select form-select-sm calendar-assign">
              <option value="">{{ _('Assign to project for new events...') }}</option>
              {% for p in projects %}
              <option value="{{ p.id }}">{{ p.name }} ({{ p.client.name if p.client else 'No Client' }})</option>
              {% endfor %}
            </select>
            
            <!-- Total Hours Display -->
            <div class="calendar-hours-summary">
              <span class="text-muted small">{{ _('Total Hours:') }}</span>
              <strong id="totalHoursDisplay" class="ms-1 text-primary">0h</strong>
            </div>
          </div>
        </div>
        
        <div class="card-body position-relative">
          <!-- Loading Indicator -->
          <div class="calendar-loading" id="calendarLoading">
            <div class="calendar-spinner"></div>
          </div>
          
          <!-- Daily Capacity Bar -->
          <div id="dailyCapacityBar" class="daily-capacity-bar" style="display: none;">
            <div class="capacity-bar-header">
              <span id="capacityDateLabel" class="fw-semibold"></span>
              <span id="capacityHoursLabel" class="ms-2"></span>
            </div>
            <div class="capacity-bar-container">
              <div id="capacityBarFill" class="capacity-bar-fill"></div>
            </div>
          </div>
          
          <!-- Calendar View -->
          <div id="calendarView">
            <div id="calendar"></div>
          </div>
          
          <!-- Agenda View -->
          <div id="agendaView" class="agenda-view">
            <div id="agendaContent"></div>
          </div>
          
          <!-- Legend -->
          <div class="calendar-legend" id="calendarLegend">
            <div class="legend-item">
              <i class="fas fa-info-circle me-1 text-muted"></i>
              <span class="text-muted small">{{ _('Colors assigned by project') }}</span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>

<!-- Event Creation Modal -->
<div class="event-modal" id="eventCreateModal">
  <div class="event-modal-content">
    <div class="event-modal-header">
      <h3><i class="fas fa-plus-circle me-2 text-primary"></i>{{ _('Create Time Entry') }}</h3>
      <button class="event-modal-close" onclick="closeModal('eventCreateModal')">&times;</button>
    </div>
    <form id="eventCreateForm">
      <div class="event-modal-body">
        <div class="mb-3">
          <label class="form-label">{{ _('Project') }} <span class="text-danger">*</span></label>
          <select class="form-select" id="createProject" required>
            <option value="">{{ _('Select a project...') }}</option>
            {% for p in projects %}
            <option value="{{ p.id }}">{{ p.name }} ({{ p.client.name if p.client else 'No Client' }})</option>
            {% endfor %}
          </select>
        </div>
        
        <div class="mb-3">
          <label class="form-label">{{ _('Task') }}</label>
          <select class="form-select" id="createTask">
            <option value="">{{ _('No task') }}</option>
          </select>
        </div>
        
        <div class="row">
          <div class="col-md-6 mb-3">
            <label class="form-label">{{ _('Start Date') }} <span class="text-danger">*</span></label>
            <input type="date" class="form-control" id="createStartDate" required>
          </div>
          <div class="col-md-6 mb-3">
            <label class="form-label">{{ _('Start Time') }} <span class="text-danger">*</span></label>
            <input type="time" class="form-control" id="createStartTime" required>
          </div>
        </div>
        
        <div class="row">
          <div class="col-md-6 mb-3">
            <label class="form-label">{{ _('End Date') }} <span class="text-danger">*</span></label>
            <input type="date" class="form-control" id="createEndDate" required>
          </div>
          <div class="col-md-6 mb-3">
            <label class="form-label">{{ _('End Time') }} <span class="text-danger">*</span></label>
            <input type="time" class="form-control" id="createEndTime" required>
          </div>
        </div>
        
        <div class="mb-3">
          <label class="form-label">{{ _('Notes') }}</label>
          <textarea class="form-control" id="createNotes" rows="3"></textarea>
        </div>
        
        <div class="mb-3">
          <label class="form-label">{{ _('Tags') }}</label>
          <input type="text" class="form-control" id="createTags" placeholder="{{ _('Comma-separated tags') }}">
        </div>
        
        <div class="form-check">
          <input class="form-check-input" type="checkbox" id="createBillable" checked>
          <label class="form-check-label" for="createBillable">
            {{ _('Billable') }}
          </label>
        </div>
      </div>
      <div class="event-modal-footer">
        <button type="button" class="btn btn-secondary" onclick="closeModal('eventCreateModal')">{{ _('Cancel') }}</button>
        <button type="submit" class="btn btn-primary">
          <i class="fas fa-save me-1"></i>{{ _('Create') }}
        </button>
      </div>
    </form>
  </div>
</div>

<!-- Event Detail/Edit Modal -->
<div class="event-modal" id="eventDetailModal">
  <div class="event-modal-content">
    <div class="event-modal-header">
      <h3 id="eventDetailModalTitle"><i class="fas fa-clock me-2 text-primary"></i>{{ _('Time Entry Details') }}</h3>
      <div class="event-modal-header-actions">
        <a href="#" id="eventDetailGoToBtn" class="btn btn-primary btn-sm event-detail-goto-btn" style="display: none;">
          <i class="fas fa-external-link-alt me-1"></i>{{ _('Go to all details') }}
        </a>
        <button class="event-modal-close" onclick="closeModal('eventDetailModal')">&times;</button>
      </div>
    </div>
    <div class="event-modal-body">
      <div class="event-detail" id="eventDetailContent">
        <!-- Content will be populated by JavaScript -->
      </div>
    </div>
    <div class="event-modal-footer">
      <button type="button" class="btn btn-danger" id="deleteEventBtn">
        <i class="fas fa-trash me-1"></i>{{ _('Delete') }}
      </button>
      <button type="button" class="btn btn-secondary" onclick="closeModal('eventDetailModal')">{{ _('Close') }}</button>
      <button type="button" class="btn btn-outline-primary" id="duplicateEventBtn">
        <i class="fas fa-copy me-1"></i>{{ _('Duplicate') }}
      </button>
      <a href="#" class="btn btn-primary" id="editEventBtn">
        <i class="fas fa-edit me-1"></i>{{ _('Edit') }}
      </a>
    </div>
  </div>
</div>

<!-- Recurring Events Modal -->
<div class="event-modal" id="recurringModal">
  <div class="event-modal-content">
    <div class="event-modal-header">
      <h3><i class="fas fa-redo me-2 text-primary"></i>{{ _('Recurring Time Blocks') }}</h3>
      <button class="event-modal-close" onclick="closeModal('recurringModal')">&times;</button>
    </div>
    <div class="event-modal-body">
      <p class="text-muted">{{ _('Manage your recurring time entry templates.') }}</p>
      <div class="recurring-list" id="recurringList">
        <!-- Content will be populated by JavaScript -->
      </div>
    </div>
    <div class="event-modal-footer">
      <button type="button" class="btn btn-secondary" onclick="closeModal('recurringModal')">{{ _('Close') }}</button>
      <button type="button" class="btn btn-primary" id="newRecurringBtn">
        <i class="fas fa-plus me-1"></i>{{ _('New Recurring Block') }}
      </button>
    </div>
  </div>
</div>

<!-- Keyboard Shortcuts Help Modal -->
<div class="event-modal" id="keyboardShortcutsModal">
  <div class="event-modal-content">
    <div class="event-modal-header">
      <h3><i class="fas fa-keyboard me-2 text-primary"></i>{{ _('Keyboard Shortcuts') }}</h3>
      <button class="event-modal-close" onclick="closeModal('keyboardShortcutsModal')">&times;</button>
    </div>
    <div class="event-modal-body">
      <div class="shortcuts-grid">
        <div class="shortcut-section">
          <h5 class="text-muted mb-3">{{ _('Navigation') }}</h5>
          <div class="shortcut-item">
            <kbd>T</kbd>
            <span>{{ _('Jump to Today') }}</span>
          </div>
          <div class="shortcut-item">
            <kbd>N</kbd>
            <span>{{ _('Next Week/Month') }}</span>
          </div>
          <div class="shortcut-item">
            <kbd>P</kbd>
            <span>{{ _('Previous Week/Month') }}</span>
          </div>
          <div class="shortcut-item">
            <kbd>←</kbd><kbd>→</kbd>
            <span>{{ _('Navigate Days') }}</span>
          </div>
        </div>
        
        <div class="shortcut-section">
          <h5 class="text-muted mb-3">{{ _('Views') }}</h5>
          <div class="shortcut-item">
            <kbd>D</kbd>
            <span>{{ _('Day View') }}</span>
          </div>
          <div class="shortcut-item">
            <kbd>W</kbd>
            <span>{{ _('Week View') }}</span>
          </div>
          <div class="shortcut-item">
            <kbd>M</kbd>
            <span>{{ _('Month View') }}</span>
          </div>
          <div class="shortcut-item">
            <kbd>A</kbd>
            <span>{{ _('Agenda View') }}</span>
          </div>
        </div>
        
        <div class="shortcut-section">
          <h5 class="text-muted mb-3">{{ _('Actions') }}</h5>
          <div class="shortcut-item">
            <kbd>C</kbd>
            <span>{{ _('Create New Entry') }}</span>
          </div>
          <div class="shortcut-item">
            <kbd>F</kbd>
            <span>{{ _('Focus Filter') }}</span>
          </div>
          <div class="shortcut-item">
            <kbd>Shift</kbd>+<kbd>C</kbd>
            <span>{{ _('Clear All Filters') }}</span>
          </div>
          <div class="shortcut-item">
            <kbd>Esc</kbd>
            <span>{{ _('Close Modal') }}</span>
          </div>
        </div>
        
        <div class="shortcut-section">
          <h5 class="text-muted mb-3">{{ _('Help') }}</h5>
          <div class="shortcut-item">
            <kbd>?</kbd>
            <span>{{ _('Show This Help') }}</span>
          </div>
        </div>
      </div>
    </div>
    <div class="event-modal-footer">
      <button type="button" class="btn btn-primary" onclick="closeModal('keyboardShortcutsModal')">{{ _('Got it!') }}</button>
    </div>
  </div>
</div>

{% endblock %}

{% block extra_js %}
<script src="https://cdn.jsdelivr.net/npm/fullcalendar@6.1.15/index.global.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
  const calendarEl = document.getElementById('calendar');
  const projectSelect = document.getElementById('assignProject');
  const filterProject = document.getElementById('filterProject');
  const filterTask = document.getElementById('filterTask');
  const filterTags = document.getElementById('filterTags');
  const agendaView = document.getElementById('agendaView');
  const calendarView = document.getElementById('calendarView');
  
  let currentView = 'calendar';
  let currentFilters = {
    project_id: null,
    task_id: null,
    tags: null,
    billable_only: false
  };
  let currentEventForDuplication = null;

  // Initialize FullCalendar
  const calendar = new FullCalendar.Calendar(calendarEl, {
    initialView: 'timeGridWeek',
    headerToolbar: false,
    selectable: true,
    selectMirror: true,
    editable: true,
    nowIndicator: true,
    firstDay: (window.userPrefs && window.userPrefs.weekStartDay !== undefined) ? window.userPrefs.weekStartDay : 1,
    timeZone: 'local',
    slotDuration: '00:30:00',
    slotMinTime: '06:00:00',
    slotMaxTime: '22:00:00',
    height: 'auto',
    eventResizableFromStart: true,
    
    events: async (info, success, failure) => {
      try {
        showLoading(true);
        let url = `/api/calendar/events?start=${encodeURIComponent(info.startStr)}&end=${encodeURIComponent(info.endStr)}`;
        
        if (currentFilters.project_id) url += `&project_id=${currentFilters.project_id}`;
        if (currentFilters.task_id) url += `&task_id=${currentFilters.task_id}`;
        if (currentFilters.tags) url += `&tags=${encodeURIComponent(currentFilters.tags)}`;
        
        const res = await fetch(url);
        const json = await res.json();
        if (!res.ok) throw new Error(json.error || 'Failed');
        
        let events = json.events || [];
        
        // Apply billable-only filter (client-side)
        if (currentFilters.billable_only) {
          events = events.filter(e => e.extendedProps.billable === true);
        }
        
        // Update total hours display
        updateTotalHours(events);
        
        // Update capacity bar for current view
        updateCapacityDisplay(events, info);
        
        // Update legend with actual projects
        updateLegend(events);
        
        success(events);
      } catch(e) {
        console.error('Calendar events error:', e);
        showToast('{{ _("Failed to load events") }}', 'danger');
        failure(e);
      } finally {
        // Clear loading state immediately
        showLoading(false);
        // Reset button states immediately
        resetAllButtonStates();
      }
    },
    
    select: function(selection) {
      // Open create modal with pre-filled dates
      const pid = projectSelect.value;
      if (!pid) {
        showToast('{{ _("Please select a project for new entries") }}', 'warning');
        return;
      }
      
      document.getElementById('createProject').value = pid;
      loadTasksForProject(pid, 'create');
      
      const startDate = new Date(selection.start);
      const endDate = new Date(selection.end);
      
      document.getElementById('createStartDate').value = startDate.toISOString().split('T')[0];
      document.getElementById('createStartTime').value = startDate.toTimeString().slice(0, 5);
      document.getElementById('createEndDate').value = endDate.toISOString().split('T')[0];
      document.getElementById('createEndTime').value = endDate.toTimeString().slice(0, 5);
      
      openModal('eventCreateModal');
      calendar.unselect();
    },
    
    eventClick: function(info) {
      showEventDetails(info.event, info.jsEvent);
    },
    
    eventDrop: async function(info) {
      await updateEventTime(info.event);
      // Clear any loading states immediately after drag
      resetAllButtonStates();
    },
    
    eventResize: async function(info) {
      await updateEventTime(info.event);
      // Clear any loading states immediately after resize
      resetAllButtonStates();
    }
  });
  
  calendar.render();
  
  // Clear any stuck loading states on initialization
  setTimeout(() => {
    showLoading(false);
    // Reset ALL buttons that might be stuck in loading state
    resetAllButtonStates();
  }, 100);
  
  // Function to reset all button states
  function resetAllButtonStates() {
    const buttons = document.querySelectorAll('.btn');
    buttons.forEach(btn => {
      // Remove any processing classes
      btn.classList.remove('processing', 'loading', 'disabled');
      
      // Restore original text if it was saved
      const originalText = btn.getAttribute('data-original-text');
      if (originalText) {
        btn.innerHTML = originalText;
        btn.removeAttribute('data-original-text');
      }
      
      // Re-enable button if it was disabled
      btn.disabled = false;
      
      // Remove any spinner icons
      const spinner = btn.querySelector('.fa-spinner, .fa-spin');
      if (spinner) {
        spinner.remove();
      }
    });
  }

  // View Controls
  document.getElementById('todayBtn').addEventListener('click', () => calendar.today());
  document.getElementById('dayBtn').addEventListener('click', () => {
    calendar.changeView('timeGridDay', calendar.getDate());
    setActiveView('calendar');
  });
  document.getElementById('weekBtn').addEventListener('click', () => {
    calendar.changeView('timeGridWeek', calendar.getDate());
    setActiveView('calendar');
  });
  document.getElementById('monthBtn').addEventListener('click', () => {
    calendar.changeView('dayGridMonth', calendar.getDate());
    setActiveView('calendar');
  });
  document.getElementById('agendaBtn').addEventListener('click', () => {
    setActiveView('agenda');
    renderAgendaView();
  });

  // New Event Button
  document.getElementById('newEventBtn').addEventListener('click', () => {
    const pid = projectSelect.value;
    if (!pid) {
      showToast('{{ _("Please select a project first") }}', 'warning');
      return;
    }
    
    // Set default times to now and 1 hour from now
    const now = new Date();
    const later = new Date(now.getTime() + 60 * 60 * 1000);
    
    document.getElementById('createProject').value = pid;
    loadTasksForProject(pid, 'create');
    document.getElementById('createStartDate').value = now.toISOString().split('T')[0];
    document.getElementById('createStartTime').value = now.toTimeString().slice(0, 5);
    document.getElementById('createEndDate').value = later.toISOString().split('T')[0];
    document.getElementById('createEndTime').value = later.toTimeString().slice(0, 5);
    
    openModal('eventCreateModal');
    
    // Ensure loading state is cleared
    showLoading(false);
  });

  // Event Create Form
  document.getElementById('eventCreateForm').addEventListener('submit', async (e) => {
    e.preventDefault();
    await createEvent();
  });

  document.getElementById('createProject').addEventListener('change', (e) => {
    loadTasksForProject(e.target.value, 'create');
  });

  // Filter Project Change
  filterProject.addEventListener('change', () => {
    currentFilters.project_id = filterProject.value || null;
    currentFilters.task_id = null; // Reset task filter
    filterTask.value = '';
    
    if (filterProject.value) {
      loadTasksForProject(filterProject.value, 'filter');
    } else {
      filterTask.innerHTML = '<option value="">{{ _("All Tasks") }}</option>';
      filterTask.disabled = true;
    }
    
    calendar.refetchEvents();
  });

  // Filter Task Change
  filterTask.addEventListener('change', () => {
    currentFilters.task_id = filterTask.value || null;
    calendar.refetchEvents();
  });

  // Filter Tags
  let tagsTimeout;
  filterTags.addEventListener('input', () => {
    clearTimeout(tagsTimeout);
    tagsTimeout = setTimeout(() => {
      currentFilters.tags = filterTags.value.trim() || null;
      calendar.refetchEvents();
    }, 500);
  });

  // Billable Only Filter
  document.getElementById('filterBillableOnly').addEventListener('click', function() {
    currentFilters.billable_only = !currentFilters.billable_only;
    
    if (currentFilters.billable_only) {
      this.classList.remove('btn-outline-success');
      this.classList.add('btn-success');
      showToast('{{ _("Showing billable entries only") }}', 'info');
    } else {
      this.classList.remove('btn-success');
      this.classList.add('btn-outline-success');
    }
    
    calendar.refetchEvents();
  });

  // Clear Filters
  document.getElementById('clearFilters').addEventListener('click', () => {
    filterProject.value = '';
    filterTask.value = '';
    filterTask.disabled = true;
    filterTags.value = '';
    currentFilters = { project_id: null, task_id: null, tags: null, billable_only: false };
    
    // Reset billable button
    const billableBtn = document.getElementById('filterBillableOnly');
    billableBtn.classList.remove('btn-success');
    billableBtn.classList.add('btn-outline-success');
    
    calendar.refetchEvents();
  });

  // Export Functions
  document.getElementById('exportIcal').addEventListener('click', async (e) => {
    e.preventDefault();
    await exportCalendar('ical');
  });

  document.getElementById('exportCsv').addEventListener('click', async (e) => {
    e.preventDefault();
    await exportCalendar('csv');
  });

  // Recurring Events
  document.getElementById('manageRecurringBtn').addEventListener('click', async () => {
    await loadRecurringBlocks();
    openModal('recurringModal');
  });

  document.getElementById('newRecurringBtn').addEventListener('click', () => {
    // Redirect to recurring block creation page or open form
    window.location.href = '/timer/recurring/new';
  });

  // Helper Functions
  function showLoading(show) {
    const loader = document.getElementById('calendarLoading');
    if (loader) {
      if (show) {
        loader.classList.add('show');
      } else {
        loader.classList.remove('show');
      }
    }
  }

  function setActiveView(view) {
    currentView = view;
    if (view === 'agenda') {
      calendarView.style.display = 'none';
      agendaView.classList.add('active');
      document.getElementById('agendaBtn').classList.add('active');
      document.getElementById('dayBtn').classList.remove('active');
      document.getElementById('weekBtn').classList.remove('active');
      document.getElementById('monthBtn').classList.remove('active');
    } else {
      calendarView.style.display = 'block';
      agendaView.classList.remove('active');
      document.getElementById('agendaBtn').classList.remove('active');
    }
  }

  async function loadTasksForProject(projectId, prefix) {
    const taskSelect = document.getElementById(prefix + 'Task');
    if (!taskSelect) return;
    
    taskSelect.innerHTML = '<option value="">{{ _("Loading...") }}</option>';
    
    if (!projectId) {
      taskSelect.innerHTML = '<option value="">{{ _("No task") }}</option>';
      taskSelect.disabled = true;
      return;
    }
    
    try {
      const res = await fetch(`/api/projects/${projectId}/tasks`);
      const json = await res.json();
      
      if (res.ok && json.tasks) {
        taskSelect.innerHTML = '<option value="">{{ _("No task") }}</option>';
        json.tasks.forEach(task => {
          const option = document.createElement('option');
          option.value = task.id;
          option.textContent = task.name;
          taskSelect.appendChild(option);
        });
        taskSelect.disabled = false;
      } else {
        taskSelect.innerHTML = '<option value="">{{ _("No task") }}</option>';
        taskSelect.disabled = true;
      }
    } catch(e) {
      console.error('Error loading tasks:', e);
      taskSelect.innerHTML = '<option value="">{{ _("No task") }}</option>';
      taskSelect.disabled = true;
    }
  }

  async function createEvent() {
    const data = {
      project_id: parseInt(document.getElementById('createProject').value),
      task_id: document.getElementById('createTask').value ? parseInt(document.getElementById('createTask').value) : null,
      start_time: `${document.getElementById('createStartDate').value}T${document.getElementById('createStartTime').value}`,
      end_time: `${document.getElementById('createEndDate').value}T${document.getElementById('createEndTime').value}`,
      notes: document.getElementById('createNotes').value.trim() || null,
      tags: document.getElementById('createTags').value.trim() || null,
      billable: document.getElementById('createBillable').checked
    };
    
    try {
      const res = await fetch('/api/entries', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data)
      });
      
      const json = await res.json();
      
      if (!res.ok || !json.success) {
        throw new Error(json.error || 'Create failed');
      }
      
      showToast('{{ _("Entry created successfully") }}', 'success');
      closeModal('eventCreateModal');
      calendar.refetchEvents();
      
      // Reset form
      document.getElementById('eventCreateForm').reset();
      
      // Clear loading states immediately
      resetAllButtonStates();
    } catch(e) {
      showToast(e.message || '{{ _("Failed to create entry") }}', 'danger');
      // Clear loading states even on error
      resetAllButtonStates();
    }
  }

  async function updateEventTime(event) {
    try {
      const res = await fetch(`/api/entry/${event.id}`, {
        method: 'PUT',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
          start_time: event.start.toISOString(),
          end_time: event.end.toISOString()
        })
      });
      
      const json = await res.json();
      
      if (!res.ok || !json.success) {
        throw new Error(json.error || 'Update failed');
      }
      
      showToast('{{ _("Entry updated") }}', 'success');
      // Clear loading states immediately
      resetAllButtonStates();
    } catch(e) {
      showToast(e.message || '{{ _("Failed to update entry") }}', 'danger');
      calendar.refetchEvents();
      // Clear loading states even on error
      resetAllButtonStates();
    }
  }

  function showEventDetails(event, clickEvent) {
    const props = event.extendedProps || {};
    // Prefer item_type; backend also sends "type" (time_entry/event/task). If missing, infer from props (duration_hours/source = time entry).
    let itemType = props.item_type || props.type || null;
    if (!itemType && (props.duration_hours != null || props.source != null || (props.projectId != null && !event.allDay))) {
      itemType = 'time_entry';
    }
    if (!itemType) itemType = 'time_entry';
    // Force time_entry link when event has time-entry-only props (registered time must go to /timer/edit/)
    if (itemType === 'event' && (props.duration_hours != null || props.source != null || (props.projectId != null && !event.allDay))) {
      itemType = 'time_entry';
    }
    const content = document.getElementById('eventDetailContent');
    const goToBtn = document.getElementById('eventDetailGoToBtn');
    const modalTitle = document.getElementById('eventDetailModalTitle');
    const editEventBtn = document.getElementById('editEventBtn');
    const deleteEventBtn = document.getElementById('deleteEventBtn');
    const duplicateEventBtn = document.getElementById('duplicateEventBtn');

    // Set detail URL and "Go to all details" by type
    let detailUrl = '#';
    let titleLabel = '{{ _("Time Entry Details") }}';
    let titleIcon = 'fa-clock';
    if (itemType === 'time_entry') {
      detailUrl = `/timer/edit/${event.id}`;
      titleLabel = '{{ _("Time Entry Details") }}';
      titleIcon = 'fa-clock';
    } else if (itemType === 'event') {
      detailUrl = `/calendar/event/${event.id}`;
      titleLabel = '{{ _("Event Details") }}';
      titleIcon = 'fa-calendar';
    } else if (itemType === 'task') {
      detailUrl = `/tasks/${event.id}`;
      titleLabel = '{{ _("Task") }}';
      titleIcon = 'fa-tasks';
    }
    goToBtn.href = detailUrl;
    goToBtn.style.display = '';
    modalTitle.innerHTML = `<i class="fas ${titleIcon} me-2 text-primary"></i>${titleLabel}`;
    editEventBtn.href = detailUrl;
    editEventBtn.innerHTML = itemType === 'time_entry' ? '<i class="fas fa-edit me-1"></i>{{ _("Edit") }}' : '<i class="fas fa-external-link-alt me-1"></i>{{ _("Go to all details") }}';

    // Show/hide time-entry-only actions
    const isTimeEntry = itemType === 'time_entry';
    deleteEventBtn.style.display = isTimeEntry ? '' : 'none';
    duplicateEventBtn.style.display = isTimeEntry ? '' : 'none';
    if (isTimeEntry) {
      currentEventForDuplication = event;
      deleteEventBtn.onclick = async () => {
        const confirmed = await showConfirm(
          '{{ _("Are you sure you want to delete this entry?") }}',
          { title: '{{ _("Delete Entry") }}', confirmText: '{{ _("Delete") }}', cancelText: '{{ _("Cancel") }}', variant: 'danger' }
        );
        if (confirmed) await deleteEvent(event.id);
      };
      duplicateEventBtn.onclick = async () => { await duplicateEvent(event); };
    }

    const formatDate = (date) => {
      return new Date(date).toLocaleString('{{ current_user.preferred_language or "en" }}', {
        year: 'numeric',
        month: 'short',
        day: 'numeric',
        hour: '2-digit',
        minute: '2-digit'
      });
    };

    if (itemType === 'task') {
      const dueStr = event.start ? formatDate(event.start) : (props.dueDate || '{{ _("N/A") }}');
      content.innerHTML = `
        <div class="event-detail-row">
          <div class="event-detail-label">{{ _("Title") }}</div>
          <div class="event-detail-value">${event.title || props.title || '{{ _("N/A") }}'}</div>
        </div>
        <div class="event-detail-row">
          <div class="event-detail-label">{{ _("Due") }}</div>
          <div class="event-detail-value">${dueStr}</div>
        </div>
        ${props.status ? `<div class="event-detail-row"><div class="event-detail-label">{{ _("Status") }}</div><div class="event-detail-value">${props.status}</div></div>` : ''}
        ${props.project_name ? `<div class="event-detail-row"><div class="event-detail-label">{{ _("Project") }}</div><div class="event-detail-value">${props.project_name}</div></div>` : ''}
      `;
    } else {
      content.innerHTML = `
        <div class="event-detail-row">
          <div class="event-detail-label">{{ _("Project") }}</div>
          <div class="event-detail-value">${props.project_name || '{{ _("N/A") }}'}</div>
        </div>
        ${props.task_name ? `<div class="event-detail-row"><div class="event-detail-label">{{ _("Task") }}</div><div class="event-detail-value">${props.task_name}</div></div>` : ''}
        <div class="event-detail-row">
          <div class="event-detail-label">{{ _("Start") }}</div>
          <div class="event-detail-value">${formatDate(event.start)}</div>
        </div>
        <div class="event-detail-row">
          <div class="event-detail-label">{{ _("End") }}</div>
          <div class="event-detail-value">${formatDate(event.end)}</div>
        </div>
        <div class="event-detail-row">
          <div class="event-detail-label">{{ _("Duration") }}</div>
          <div class="event-detail-value">${(props.duration_hours != null ? props.duration_hours : 0).toFixed(2)} {{ _("hours") }}</div>
        </div>
        ${props.notes ? `<div class="event-detail-row"><div class="event-detail-label">{{ _("Notes") }}</div><div class="event-detail-value">${props.notes}</div></div>` : ''}
        ${props.tags ? `<div class="event-detail-row"><div class="event-detail-label">{{ _("Tags") }}</div><div class="event-detail-value">${props.tags}</div></div>` : ''}
        ${itemType === 'time_entry' ? `
        <div class="event-detail-row">
          <div class="event-detail-label">{{ _("Billable") }}</div>
          <div class="event-detail-value">
            <span class="event-detail-badge ${props.billable ? 'billable' : 'non-billable'}">${props.billable ? '{{ _("Yes") }}' : '{{ _("No") }}'}</span>
          </div>
        </div>
        <div class="event-detail-row">
          <div class="event-detail-label">{{ _("Source") }}</div>
          <div class="event-detail-value">${props.source === 'auto' ? '{{ _("Automatic Timer") }}' : '{{ _("Manual Entry") }}'}</div>
        </div>
        ` : ''}
      `;
    }

    openModal('eventDetailModal');
    const modalEl = document.getElementById('eventDetailModal');
    const contentEl = modalEl && modalEl.querySelector('.event-modal-content');
    if (clickEvent && contentEl) {
      const pad = 16;
      const x = clickEvent.clientX;
      const y = clickEvent.clientY;
      contentEl.style.position = 'fixed';
      requestAnimationFrame(function() {
        const rect = contentEl.getBoundingClientRect();
        let left = x + pad;
        let top = y + pad;
        if (left + rect.width > window.innerWidth - pad) left = window.innerWidth - rect.width - pad;
        if (top + rect.height > window.innerHeight - pad) top = window.innerHeight - rect.height - pad;
        if (left < pad) left = pad;
        if (top < pad) top = pad;
        contentEl.style.left = left + 'px';
        contentEl.style.top = top + 'px';
      });
    } else if (contentEl) {
      contentEl.style.position = '';
      contentEl.style.left = '';
      contentEl.style.top = '';
    }
  }

  async function deleteEvent(eventId) {
    try {
      const res = await fetch(`/api/entry/${eventId}`, { method: 'DELETE' });
      const json = await res.json();
      
      if (!res.ok || !json.success) {
        throw new Error(json.error || 'Delete failed');
      }
      
      showToast('{{ _("Entry deleted") }}', 'success');
      closeModal('eventDetailModal');
      calendar.refetchEvents();
      // Clear loading states immediately
      resetAllButtonStates();
    } catch(e) {
      showToast(e.message || '{{ _("Failed to delete entry") }}', 'danger');
      // Clear loading states even on error
      resetAllButtonStates();
    }
  }

  async function exportCalendar(format) {
    const view = calendar.view;
    const start = view.activeStart.toISOString();
    const end = view.activeEnd.toISOString();
    
    let url = `/api/calendar/export?start=${encodeURIComponent(start)}&end=${encodeURIComponent(end)}&format=${format}`;
    
    if (currentFilters.project_id) {
      url += `&project_id=${currentFilters.project_id}`;
    }
    
    window.location.href = url;
    showToast('{{ _("Export started") }}', 'info');
  }

  async function loadRecurringBlocks() {
    try {
      const res = await fetch('/api/recurring-blocks');
      const json = await res.json();
      
      const listEl = document.getElementById('recurringList');
      
      if (!json.blocks || json.blocks.length === 0) {
        listEl.innerHTML = '<p class="text-muted text-center py-4">{{ _("No recurring blocks yet") }}</p>';
        return;
      }
      
      listEl.innerHTML = json.blocks.map(block => `
        <div class="recurring-item">
          <div class="recurring-item-header">
            <div class="recurring-item-title">${block.name}</div>
            <span class="recurring-item-status ${block.is_active ? 'active' : 'inactive'}">
              ${block.is_active ? '{{ _("Active") }}' : '{{ _("Inactive") }}'}
            </span>
          </div>
          <div class="recurring-item-details">
            <i class="fas fa-project-diagram me-1"></i>${block.project_name || '{{ _("Unknown Project") }}'}
            <span class="mx-2">•</span>
            <i class="fas fa-redo me-1"></i>${block.recurrence}
            ${block.weekdays ? ` (${block.weekdays})` : ''}
            <span class="mx-2">•</span>
            <i class="fas fa-clock me-1"></i>${block.start_time_local} - ${block.end_time_local}
          </div>
          <div class="recurring-item-actions">
            <button class="btn btn-sm btn-outline-primary" onclick="editRecurring(${block.id})">
              <i class="fas fa-edit"></i> {{ _("Edit") }}
            </button>
            <button class="btn btn-sm btn-outline-danger" onclick="deleteRecurring(${block.id})">
              <i class="fas fa-trash"></i> {{ _("Delete") }}
            </button>
          </div>
        </div>
      `).join('');
    } catch(e) {
      showToast('{{ _("Failed to load recurring blocks") }}', 'danger');
    }
  }

  async function renderAgendaView() {
    showLoading(true);
    
    try {
      const view = calendar.view;
      const start = view.activeStart.toISOString();
      const end = view.activeEnd.toISOString();
      
      let url = `/api/calendar/events?start=${encodeURIComponent(start)}&end=${encodeURIComponent(end)}`;
      
      if (currentFilters.project_id) url += `&project_id=${currentFilters.project_id}`;
      if (currentFilters.task_id) url += `&task_id=${currentFilters.task_id}`;
      if (currentFilters.tags) url += `&tags=${encodeURIComponent(currentFilters.tags)}`;
      
      const res = await fetch(url);
      const json = await res.json();
      
      if (!res.ok) throw new Error(json.error || 'Failed');
      
      const events = json.events || [];
      
      // Group events by date
      const grouped = {};
      events.forEach(event => {
        const date = new Date(event.start).toLocaleDateString('{{ current_user.preferred_language or "en" }}', {
          weekday: 'long',
          year: 'numeric',
          month: 'long',
          day: 'numeric'
        });
        
        if (!grouped[date]) grouped[date] = [];
        grouped[date].push(event);
      });
      
      const content = document.getElementById('agendaContent');
      
      if (Object.keys(grouped).length === 0) {
        content.innerHTML = '<p class="text-muted text-center py-4">{{ _("No events in this period") }}</p>';
        return;
      }
      
      content.innerHTML = Object.entries(grouped).map(([date, dateEvents]) => `
        <div class="agenda-date-group">
          <div class="agenda-date-header">${date}</div>
          ${dateEvents.map(event => {
            const start = new Date(event.start).toLocaleTimeString('{{ current_user.preferred_language or "en" }}', {
              hour: '2-digit',
              minute: '2-digit'
            });
            const end = new Date(event.end).toLocaleTimeString('{{ current_user.preferred_language or "en" }}', {
              hour: '2-digit',
              minute: '2-digit'
            });
            
            return `
              <div class="agenda-event" style="border-left-color: ${event.backgroundColor};" onclick="showAgendaEvent(${event.id})">
                <div class="agenda-event-time">${start} - ${end}</div>
                <div class="agenda-event-details">
                  <div class="agenda-event-title">${event.title}</div>
                  <div class="agenda-event-meta">
                    ${event.extendedProps.duration_hours ? `${event.extendedProps.duration_hours.toFixed(2)} hours` : ''}
                    ${event.extendedProps.billable ? '<span class="badge bg-success ms-2">Billable</span>' : '<span class="badge bg-secondary ms-2">Non-billable</span>'}
                  </div>
                </div>
              </div>
            `;
          }).join('')}
        </div>
      `).join('');
    } catch(e) {
      showToast('{{ _("Failed to load agenda view") }}', 'danger');
    } finally {
      showLoading(false);
    }
  }

  // Global functions for agenda view
  window.showAgendaEvent = async function(eventId) {
    try {
      const res = await fetch(`/api/entry/${eventId}`);
      const json = await res.json();
      
      if (!res.ok) throw new Error('Failed to load event');
      
      // Create a FullCalendar event-like object for consistency
      const event = {
        id: json.id,
        start: json.start_time,
        end: json.end_time,
        extendedProps: {
          project_name: json.project_name,
          task_name: json.task_name,
          notes: json.notes,
          tags: json.tags,
          billable: json.billable,
          duration_hours: json.duration_hours,
          source: json.source
        }
      };
      
      showEventDetails(event);
    } catch(e) {
      showToast('{{ _("Failed to load event details") }}', 'danger');
    }
  };

  // Global functions for recurring management
  window.editRecurring = function(blockId) {
    window.location.href = `/timer/recurring/edit/${blockId}`;
  };

  window.deleteRecurring = async function(blockId) {
    const confirmed = await showConfirm(
      '{{ _("Are you sure you want to delete this recurring block?") }}',
      {
        title: '{{ _("Delete Recurring Block") }}',
        confirmText: '{{ _("Delete") }}',
        cancelText: '{{ _("Cancel") }}',
        variant: 'danger'
      }
    );
    if (!confirmed) return;
    
    try {
      const res = await fetch(`/api/recurring-blocks/${blockId}`, { method: 'DELETE' });
      const json = await res.json();
      
      if (!res.ok || !json.success) {
        throw new Error(json.error || 'Delete failed');
      }
      
      showToast('{{ _("Recurring block deleted") }}', 'success');
      await loadRecurringBlocks();
    } catch(e) {
      showToast(e.message || '{{ _("Failed to delete recurring block") }}', 'danger');
    }
  };
  
  // Quick Win: Duplicate Event
  async function duplicateEvent(event) {
    try {
      const props = event.extendedProps;
      const duration = (new Date(event.end) - new Date(event.start)) / (1000 * 60 * 60); // hours
      
      // Ask for new date/time
      const newStartStr = prompt('{{ _("Enter new start time (YYYY-MM-DD HH:MM):") }}', '');
      if (!newStartStr) return;
      
      const newStart = new Date(newStartStr);
      if (isNaN(newStart.getTime())) {
        showToast('{{ _("Invalid date format") }}', 'danger');
        return;
      }
      
      const newEnd = new Date(newStart.getTime() + (duration * 60 * 60 * 1000));
      
      const data = {
        project_id: props.project_id,
        task_id: props.task_id,
        start_time: newStart.toISOString().slice(0, 16),
        end_time: newEnd.toISOString().slice(0, 16),
        notes: props.notes,
        tags: props.tags,
        billable: props.billable
      };
      
      const res = await fetch('/api/entries', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(data)
      });
      
      const json = await res.json();
      
      if (!res.ok || !json.success) {
        throw new Error(json.error || 'Duplication failed');
      }
      
      showToast('{{ _("Entry duplicated successfully") }}', 'success');
      closeModal('eventDetailModal');
      calendar.refetchEvents();
      // Clear loading states immediately
      resetAllButtonStates();
    } catch(e) {
      showToast(e.message || '{{ _("Failed to duplicate entry") }}', 'danger');
      // Clear loading states even on error
      resetAllButtonStates();
    }
  }
  
  // Quick Win: Update Total Hours Display
  function updateTotalHours(events) {
    const totalHours = events.reduce((sum, event) => {
      return sum + (event.extendedProps.duration_hours || 0);
    }, 0);
    
    const displayEl = document.getElementById('totalHoursDisplay');
    if (displayEl) {
      displayEl.textContent = `${totalHours.toFixed(1)}h`;
    }
  }
  
  // Quick Win: Update Legend with Actual Projects
  function updateLegend(events) {
    const legendEl = document.getElementById('calendarLegend');
    if (!legendEl) return;
    
    // Get unique projects from events
    const projectMap = new Map();
    events.forEach(event => {
      const projectId = event.extendedProps.project_id;
      const projectName = event.extendedProps.project_name;
      const color = event.backgroundColor;
      
      if (projectId && projectName && color) {
        projectMap.set(projectId, {
          name: projectName,
          color: color
        });
      }
    });
    
    // Create legend items
    const legendItems = Array.from(projectMap.values())
      .sort((a, b) => a.name.localeCompare(b.name)) // Sort alphabetically
      .slice(0, 8) // Limit to 8 projects to avoid clutter
      .map(project => `
        <div class="legend-item">
          <div class="legend-color" style="background: ${project.color};"></div>
          <span>${project.name}</span>
        </div>
      `).join('');
    
    // Update legend content
    const infoItem = `
      <div class="legend-item">
        <i class="fas fa-info-circle me-1 text-muted"></i>
        <span class="text-muted small">{{ _('Colors assigned by project') }}</span>
      </div>
    `;
    
    legendEl.innerHTML = legendItems + infoItem;
    
    // Show/hide legend based on whether we have projects
    if (projectMap.size === 0) {
      legendEl.style.display = 'none';
    } else {
      legendEl.style.display = 'flex';
    }
  }
  
  // Quick Win: Update Capacity Display
  function updateCapacityDisplay(events, info) {
    const view = calendar.view;
    
    // Only show for day view for now
    if (view.type !== 'timeGridDay') {
      document.getElementById('dailyCapacityBar').style.display = 'none';
      return;
    }
    
    // Calculate hours for the visible day
    const dayStart = new Date(view.currentStart);
    const dayEnd = new Date(view.currentEnd);
    
    const dayEvents = events.filter(e => {
      const eventStart = new Date(e.start);
      return eventStart >= dayStart && eventStart < dayEnd;
    });
    
    const dayHours = dayEvents.reduce((sum, event) => {
      return sum + (event.extendedProps.duration_hours || 0);
    }, 0);
    
    const capacity = 8.0; // Default capacity, can be made dynamic later
    const percentage = Math.min((dayHours / capacity) * 100, 100);
    
    // Update display
    const barEl = document.getElementById('dailyCapacityBar');
    const fillEl = document.getElementById('capacityBarFill');
    const dateLabel = document.getElementById('capacityDateLabel');
    const hoursLabel = document.getElementById('capacityHoursLabel');
    
    if (barEl && fillEl && dateLabel && hoursLabel) {
      barEl.style.display = 'block';
      fillEl.style.width = `${percentage}%`;
      
      // Color based on capacity
      if (percentage < 90) {
        fillEl.className = 'capacity-bar-fill capacity-ok';
      } else if (percentage < 100) {
        fillEl.className = 'capacity-bar-fill capacity-warning';
      } else {
        fillEl.className = 'capacity-bar-fill capacity-over';
      }
      
      dateLabel.textContent = dayStart.toLocaleDateString('{{ current_user.preferred_language or "en" }}', {
        weekday: 'long',
        year: 'numeric',
        month: 'long',
        day: 'numeric'
      });
      
      hoursLabel.textContent = `${dayHours.toFixed(1)}h / ${capacity.toFixed(0)}h (${percentage.toFixed(0)}%)`;
    }
  }
  
  // Quick Win: Keyboard Shortcuts
  document.addEventListener('keydown', function(e) {
    // Don't trigger shortcuts when typing in input fields
    if (e.target.matches('input, textarea, select')) {
      // Allow Escape to work in modals even from inputs
      if (e.key === 'Escape') {
        const activeModal = document.querySelector('.event-modal.show');
        if (activeModal) {
          closeModal(activeModal.id);
        }
      }
      return;
    }
    
    const key = e.key.toLowerCase();
    
    switch(key) {
      // Navigation
      case 't':
        calendar.today();
        showToast('{{ _("Jumped to today") }}', 'info');
        break;
        
      case 'n':
        calendar.next();
        break;
        
      case 'p':
        calendar.prev();
        break;
        
      case 'arrowleft':
        calendar.prev();
        e.preventDefault();
        break;
        
      case 'arrowright':
        calendar.next();
        e.preventDefault();
        break;
      
      // Views
      case 'd':
        calendar.changeView('timeGridDay', calendar.getDate());
        setActiveView('calendar');
        document.getElementById('dayBtn').classList.add('active');
        document.getElementById('weekBtn').classList.remove('active');
        document.getElementById('monthBtn').classList.remove('active');
        break;
        
      case 'w':
        calendar.changeView('timeGridWeek', calendar.getDate());
        setActiveView('calendar');
        document.getElementById('weekBtn').classList.add('active');
        document.getElementById('dayBtn').classList.remove('active');
        document.getElementById('monthBtn').classList.remove('active');
        break;
        
      case 'm':
        calendar.changeView('dayGridMonth', calendar.getDate());
        setActiveView('calendar');
        document.getElementById('monthBtn').classList.add('active');
        document.getElementById('dayBtn').classList.remove('active');
        document.getElementById('weekBtn').classList.remove('active');
        break;
        
      case 'a':
        setActiveView('agenda');
        renderAgendaView();
        break;
      
      // Actions
      case 'c':
        if (e.shiftKey) {
          // Shift+C: Clear filters
          document.getElementById('clearFilters').click();
        } else {
          // C: Create new entry
          document.getElementById('newEventBtn').click();
        }
        break;
        
      case 'f':
        // Focus filter input
        document.getElementById('filterProject').focus();
        break;
        
      case '?':
        // Show keyboard shortcuts help
        openModal('keyboardShortcutsModal');
        break;
        
      case 'escape':
        // Close active modal
        const activeModal = document.querySelector('.event-modal.show');
        if (activeModal) {
          closeModal(activeModal.id);
        }
        break;
    }
  });
  
  // Show toast message on page load to inform about shortcuts
  setTimeout(() => {
    showToast('{{ _("💡 Press ? to see keyboard shortcuts") }}', 'info');
  }, 1000);
  
  // Global function to reset all button states (can be called from console if needed)
  window.resetCalendarButtons = resetAllButtonStates;
});

// Modal helpers
function openModal(modalId) {
  document.getElementById(modalId).classList.add('show');
  document.body.style.overflow = 'hidden';
}

function closeModal(modalId) {
  document.getElementById(modalId).classList.remove('show');
  document.body.style.overflow = '';
}

// Note: showToast is provided by the global toast-notifications.js
// No need to define it here - it's already available as window.showToast
</script>
{% endblock %}
