// ui.js - UI функции и рендеринг

function showSection(sectionName) {
    document.querySelectorAll('.section').forEach(section => {
        section.classList.remove('active');
    });
    
    document.getElementById(sectionName + '-section').classList.add('active');
    
    if (sectionName === 'tasks') {
        loadTasks();
    } else if (sectionName === 'logs') {
        loadActivityLogs();
    } else if (sectionName === 'kanban') {
        loadKanbanTasks();
    } else if (sectionName === 'mytasks') {
        console.log('загружаю loadMyTasks');
        loadTasks();
    } else if (sectionName === 'runtasks') {
        console.log('загружаю loadRunTasks');
        loadTasks();
    }
    
    // Загрузка профиля при переходе в личный кабинет
    if (sectionName === 'profile') {
        loadUserProfile();
        loadNotificationSettings();
    }
}

function renderTasks() {
    const container = document.getElementById('tasks-list');
    const showDeleted = document.getElementById('show-deleted')?.checked || false;
    
    let filteredTasks = tasks;
    if (!showDeleted) {
        filteredTasks = tasks.filter(task => task.status === 'active');
    }
    
    if (filteredTasks.length === 0) {
        container.innerHTML = '<div class="loading">Задачи не найдены</div>';
        return;
    }

    container.innerHTML = filteredTasks.map(task => {
        const isExpanded = expandedTasks.has(task.id);
        const overallStatus = getTaskOverallStatus(task);
        const statusClass = getStatusClass(overallStatus);
        const isDeleted = task.status === 'deleted';
        const isClosed = task.closed_at !== null;
        const userRole = getUserRoleInTask(task);
        const canEdit = canUserEditTask(task);
        const isCopy = task.original_task_id !== null;
        
        const timeLeftInfo = getTimeLeftInfo(task);
        
        return `
            <div class="task-card ${isDeleted ? 'deleted' : ''} ${isClosed ? 'closed' : ''}" data-task-id="${task.id}">
                <div class="task-header">
                    <div class="task-title" onclick="toggleTask(${task.id})" style="cursor: pointer; display: flex; justify-content: space-between; align-items: center;">
                        <div style="flex: 1;">
                            <!--
                            ${task.task_type ? `<span class="task-type-badge ${task.task_type}">${getTaskTypeDisplayName(task.task_type)}</span>` : ''}
                            -->
                            <span class="task-number">Задача №${task.id}</span>
                            <strong>${task.title}</strong>
                            ${isDeleted ? '<span class="deleted-badge">Удалена</span>' : ''}
                            ${isClosed ? '<span class="closed-badge">Закрыта</span>' : ''}
                            ${isCopy ? '<span class="copy-badge">Копия</span>' : ''}
                            ${timeLeftInfo ? `<span class="deadline-badge ${timeLeftInfo.class}">${timeLeftInfo.text}</span>` : ''}
                            <span class="role-badge ${getRoleBadgeClass(userRole)}">${userRole}</span>
    ${task.assignments && task.assignments.length > 0 ? `<span class="task-number">${task.assignments.map(a => a.user_login || a.user_name).join(', ')}</span>` : ''}
                        </div>
                        <!--
                        <div class="task-status ${statusClass}">
                        ${getStatusText(overallStatus)}
                        </div>
                        -->
                        <span class="task-status ${statusClass}">
                        Выполнить до: ${formatDateTime(task.due_date || task.created_at)}
                        </span>
                        <div class="expand-icon" style="margin-left: 10px; transition: transform 0.3s; transform: rotate(${isExpanded ? '180deg' : '0deg'});">
                            ▼
                        </div>
                    </div>
                </div>
                
                <div class="task-content ${isExpanded ? 'expanded' : ''}">
                    ${isExpanded ? `
                    <div class="task-actions">
                        ${!isDeleted && !isClosed ? `
                            <button class="copy-btn" onclick="openTaskChat(${task.id})" title="Открыть чат">💬</button>
                            <button class="add-file-btn" onclick="openAddFileModal(${task.id})" title="Добавить файл">📎</button>
${currentUser && currentUser.login === 'minicrm' ? `<button class="edit-btn" onclick="openEditModal(${task.id})" title="Редактировать">✏️</button>` : ''}
${currentUser && currentUser.login === 'kalugin.o' ? `<button class="manage-assignees-btn" onclick="openManageAssigneesModal(${task.id})" title="Управление исполнителями">👥</button>` : ''}
${currentUser && currentUser.role === 'tasks' && canEdit || currentUser.role === 'admin' ? `<button class="manage-assignees-btn" onclick="assignAdd_openModal(${task.id})" title="Управление исполнителями">🧑‍💼➕Добавить</button>` : ''}
${currentUser && currentUser.role === 'tasks' && canEdit || currentUser.role === 'admin' ? `<button class="manage-assignees-btn" onclick="assignRemove_openModal(${task.id})" title="Управление исполнителями">🧑‍💼❌Удалить</button>` : ''}
                            <button class="copy-btn" onclick="openCopyModal(${task.id})" title="Создать копию">📋</button>
    ${currentUser && currentUser.login === 'minicrm' ? `<button class="rework-btn" onclick="openReworkModal(${task.id})" title="Вернуть на доработку">🔄</button>` : ''}
    ${currentUser && currentUser.login === 'minicrm' ? `<button class="close-btn" onclick="closeTask(${task.id})" title="Закрыть задачу">🔒</button>` : ''}
                            ${canEdit ? `<button class="delete-btn" onclick="deleteTask(${task.id})" title="Удалить">🗑️</button>` : ''}
                        ` : ''}
                        ${isClosed && canEdit ? `
                            <button class="reopen-btn" onclick="reopenTask(${task.id})" title="Открыть задачу">🔓</button>
                        ` : ''}
                        ${isDeleted && currentUser.role === 'admin' ? `
                            <button class="restore-btn" onclick="restoreTask(${task.id})" title="Восстановить">↶</button>
                        ` : ''}
                    </div>
                    ` : ''}
                    
                    ${isCopy && task.original_task_title ? `
                        <div class="task-original">
                            <small>Оригинал: "${task.original_task_title}" (создал: ${task.original_creator_name})</small>
                        </div>
                    ` : ''}
                    
                    <div class="task-description">${task.description || 'Нет описания'}</div>
                    
                    ${task.rework_comment ? `
                        <div class="rework-comment">
                            <strong>Комментарий к доработке:</strong> ${task.rework_comment}
                        </div>
                    ` : ''}
                    
                    
<div class="file-list" id="files-${task.id}">
    <strong>Файлы:</strong> 
    ${task.files && task.files.length > 0 ? renderGroupedFilesWithDelete(task) : '<span class="no-files">нет файлов</span>'}
</div>
                    
                    
                    <div class="task-assignments">
                        <strong>Исполнители:</strong>
${task.assignments && task.assignments.length > 0 ? 
    renderAssignmentList(task.assignments, task.id, canEdit) : 
    '<div>Не назначены</div>'
}
                    </div> 
                    </div>
                    
                    <div class="task-meta">
                        <small>
                        Создана: ${formatDateTime(task.start_date || task.created_at)} 
                        | Выполнить до: ${formatDateTime(task.due_date || task.created_at)} 
                        | Автор: ${task.creator_name} 
                        | Тип: ${task.task_type ? `<span class="task-type-badge ${task.task_type}">${getTaskTypeDisplayName(task.task_type)}</span>` : ''}
                        </small>
                        ${task.deleted_at ? `<br><small>Удалена: ${formatDateTime(task.deleted_at)}</small>` : ''}
                        ${task.closed_at ? `<br><small>Закрыта: ${formatDateTime(task.closed_at)}</small>` : ''}
                    </div>
            </div>
        `;
    }).join('');
}
// Функция для рендеринга списка исполнителей с фильтрацией
function renderAssignmentList(assignments, taskId, canEdit) {
    if (!assignments || assignments.length === 0) {
        return '<div>Не назначены</div>';
    }

    // Создаем контейнер с возможностью фильтрации
    return `
        <div class="assignments-container">
            <div class="assignments-filter">
                <input type="text" 
                       class="assignment-filter-input" 
                       placeholder="Поиск исполнителя..." 
                       data-task-id="${taskId}"
                       oninput="filterAssignments(${taskId})">
                <span class="filter-count" id="filter-count-${taskId}">${assignments.length} исполнителей</span>
            </div>
            <div class="assignments-scroll-container" id="assignments-${taskId}">
                ${assignments.map(assignment => renderAssignment(assignment, taskId, canEdit)).join('')}
            </div>
        </div>
    `;
}

// Функция для открытия модального окна доработки для конкретного исполнителя
function openReworkAssignmentModal(taskId, userId, userName) {
    const task = tasks.find(t => t.id === taskId);
    if (!task) {
        alert('Задача не найдена');
        return;
    }

    // Проверяем права (только автор задачи или администратор)
    if (parseInt(task.created_by) !== currentUser.id && currentUser.role !== 'admin') {
        alert('Только автор задачи может отправлять на доработку');
        return;
    }

    // Удаляем предыдущее модальное окно, если оно есть
    const existingModal = document.getElementById('rework-assignment-modal');
    if (existingModal) {
        existingModal.remove();
    }

    // Создаем модальное окно
    const modal = document.createElement('div');
    modal.className = 'modal';
    modal.id = 'rework-assignment-modal';
    modal.style.display = 'block';
    
    modal.innerHTML = `
        <div class="modal-content">
            <div class="modal-header">
                <h3>Отправить на доработку</h3>
                <span class="close" onclick="closeReworkAssignmentModal()">&times;</span>
            </div>
            <div class="modal-body">
                <p><strong>Задача:</strong> ${escapeHtml(task.title)}</p>
                <p><strong>Исполнитель:</strong> ${escapeHtml(userName)}</p>
                <div class="form-group">
                    <label for="rework-comment-${taskId}-${userId}"><strong>Комментарий к доработке:</strong></label>
                    <textarea id="rework-comment-${taskId}-${userId}" 
                              class="form-control" 
                              rows="5" 
                              placeholder="Опишите, что нужно доработать..."></textarea>
                </div>
                <div class="modal-footer" style="margin-top: 20px; text-align: right;">
                    <button type="button" class="btn-rework-cancel" onclick="closeReworkAssignmentModal()">Отмена</button>
                    <button type="button" class="btn-rework-primary" onclick="submitReworkAssignment('${taskId}', '${userId}')">🔄 Отправить на доработку</button>
                </div>
            </div>
        </div>
    `;
    
    document.body.appendChild(modal);
    
    // Фокусируемся на textarea
    const textarea = document.getElementById(`rework-comment-${taskId}-${userId}`);
    if (textarea) {
        setTimeout(() => textarea.focus(), 100);
    }
}
// Функция для принудительного завершения задачи исполнителя
async function forceCompleteAssignment(taskId, userId, userName) {
    if (!confirm(`Вы уверены, что хотите отметить задачу как выполненную для сотрудника ${userName}?\nЭто действие нельзя отменить.`)) {
        return;
    }

    try {
        const response = await fetch(`/api/tasks/${taskId}/force-complete/${userId}`, {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json',
            }
        });

        if (response.ok) {
            alert(`✅ Задача отмечена как выполненная для сотрудника ${userName}`);
            loadTasks(); // Перезагружаем задачи
        } else {
            const error = await response.json();
            alert(`❌ Ошибка: ${error.error || 'Неизвестная ошибка'}`);
        }
    } catch (error) {
        console.error('❌ Ошибка:', error);
        alert('Сетевая ошибка при выполнении операции');
    }
}
// Вспомогательная функция для экранирования HTML
function escapeHtml(text) {
    if (!text) return '';
    return String(text)
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#039;');
}

// Функция для отправки на доработку конкретного исполнителя
async function submitReworkAssignment(taskId, userId) {
    // Получаем textarea по уникальному ID
    const textarea = document.getElementById(`rework-comment-${taskId}-${userId}`);
    
    if (!textarea) {
        alert('Ошибка: поле комментария не найдено');
        return;
    }
    
    const comment = textarea.value.trim();
    
    // Детальная отладка
    console.log('=== ОТПРАВКА НА ДОРАБОТКУ ===');
    console.log('Task ID:', taskId);
    console.log('User ID:', userId);
    console.log('Comment length:', comment.length);
    console.log('Comment text:', comment);
    console.log('============================');
    
    if (!comment) {
        alert('Пожалуйста, укажите комментарий к доработке');
        textarea.style.border = '2px solid red';
        textarea.focus();
        return;
    }

    // Блокируем кнопку отправки
    const submitBtn = document.querySelector(`#rework-assignment-modal .btn-warning`);
    if (submitBtn) {
        submitBtn.disabled = true;
        submitBtn.innerHTML = '⏳ Отправка...';
    }

    try {
        const response = await fetch(`/api/tasks/${taskId}/rework-assignment/${userId}`, {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ 
                comment: comment  // Отправляем явно
            })
        });

        const data = await response.json();

        if (response.ok) {
            alert('✅ Исполнитель отправлен на доработку');
            closeReworkAssignmentModal();
            // Перезагружаем задачи
            if (typeof loadTasks === 'function') {
                loadTasks();
            } else {
                location.reload();
            }
        } else {
            alert(`❌ Ошибка: ${data.error || 'Неизвестная ошибка'}`);
        }
    } catch (error) {
        console.error('❌ Ошибка:', error);
        alert('Сетевая ошибка при отправке на доработку: ' + error.message);
    } finally {
        // Разблокируем кнопку
        if (submitBtn) {
            submitBtn.disabled = false;
            submitBtn.innerHTML = '🔄 Отправить на доработку';
        }
    }
}
// Функция для закрытия модального окна доработки
function closeReworkAssignmentModal() {
    const modal = document.getElementById('rework-assignment-modal');
    if (modal) {
        modal.style.display = 'none';
        setTimeout(() => {
            modal.remove();
        }, 300);
    }
}

// Функция для фильтрации исполнителей в конкретной задаче
function filterAssignments(taskId) {
    const filterInput = document.querySelector(`.assignment-filter-input[data-task-id="${taskId}"]`);
    const scrollContainer = document.getElementById(`assignments-${taskId}`);
    const filterCount = document.getElementById(`filter-count-${taskId}`);
    
    if (!filterInput || !scrollContainer) return;
    
    const searchTerm = filterInput.value.toLowerCase();
    const assignments = scrollContainer.querySelectorAll('.assignment');
    
    let visibleCount = 0;
    
    assignments.forEach(assignment => {
        const userName = assignment.querySelector('strong')?.textContent?.toLowerCase() || '';
        const userLogin = assignment.querySelector('small')?.textContent?.toLowerCase() || '';
        
        const isVisible = userName.includes(searchTerm) || 
                         userLogin.includes(searchTerm) ||
                         searchTerm === '';
        
        assignment.style.display = isVisible ? '' : 'none';
        
        if (isVisible) {
            visibleCount++;
        }
    });
    
    if (filterCount) {
        filterCount.textContent = `${visibleCount} из ${assignments.length} исполнителей`;
    }
}
// поддержка новых контейнеров
function toggleTask(taskId) {
    if (expandedTasks.has(taskId)) {
        expandedTasks.delete(taskId);
    } else {
        expandedTasks.add(taskId);
        loadTaskFiles(taskId);
    }
    
    // Определяем, какой контейнер сейчас активен
    const activeSection = document.querySelector('.section.active');
    if (activeSection) {
        const sectionId = activeSection.id;
        if (sectionId === 'mytasks-section') {
            renderTasksInContainer('mytasks-list');
        } else if (sectionId === 'runtasks-section') {
            renderTasksInContainer('runtasks-list');
        } else if (sectionId === 'tasks-section') {
            renderTasks();
        }
    } else {
        renderTasks();
    }
}

function getTimeLeftInfo(task) {
    if (!task.due_date || task.closed_at) return null;
    
    const dueDate = new Date(task.due_date);
    const now = new Date();
    const timeLeft = dueDate.getTime() - now.getTime();
    const hoursLeft = Math.floor(timeLeft / (60 * 60 * 1000));
    
    if (hoursLeft <= 0) return null;
    
    if (hoursLeft <= 24) {
        return {
            text: `Менее 24ч`,
            class: 'deadline-24h'
        };
    } else if (hoursLeft <= 48) {
        return {
            text: `Менее 48ч`,
            class: 'deadline-48h'
        };
    }
    
    return null;
}

// Функция для рендеринга одного исполнителя
function renderAssignment(assignment, taskId, canEdit) {
    const statusClass = getStatusClass(assignment.status);
    const isCurrentUser = assignment.user_id === currentUser.id;
    const isOverdue = assignment.status === 'overdue';
    const isRework = assignment.status === 'rework';
    
    const timeLeftInfo = getAssignmentTimeLeftInfo(assignment);
    
    // Проверяем, является ли текущий пользователь автором задачи
    const task = tasks.find(t => t.id === taskId);
    const isTaskCreator = task && parseInt(task.created_by) === currentUser.id;
    
    return `
        <div class="assignment ${isOverdue ? 'overdue' : ''} ${isRework ? 'rework' : ''}">
            <span class="assignment-status ${statusClass}"></span>
            <div style="flex: 1;">
                <strong>${assignment.user_name}</strong>
                ${isCurrentUser ? '<small>(Вы)</small>' : ''}
                ${timeLeftInfo ? `<span class="deadline-indicator ${timeLeftInfo.class}">${timeLeftInfo.text}</span>` : ''}
                ${assignment.start_date || assignment.due_date ? `
                    <div class="assignment-dates">
                        ${assignment.start_date ? `<small>Начало: ${formatDateTime(assignment.start_date)}</small>` : ''}
                        ${assignment.due_date ? `<small>Выполнить до: ${formatDateTime(assignment.due_date)}</small>` : ''}
                    </div>
                ` : ''}
                ${assignment.rework_comment ? `
                    <div class="assignment-rework-comment">
                        <small><strong>Комментарий:</strong> ${assignment.rework_comment}</small>
                    </div>
                ` : ''}
            </div>
            <div class="action-buttons">
${isCurrentUser && assignment.status === 'assigned' ? 
`<button onclick="updateStatus(${taskId}, ${assignment.user_id}, 'in_progress')">Приступить</button>` : ''}
${isCurrentUser && (assignment.status === 'in_progress' || assignment.status === 'overdue' || assignment.status === 'rework') ? 
`<button onclick="updateStatus(${taskId}, ${assignment.user_id}, 'completed')">Выполнено</button>` : ''}
${isTaskCreator && assignment.status !== 'assigned' ? 
`<button class="rework-btn" onclick="openReworkAssignmentModal(${taskId}, ${assignment.user_id}, '${assignment.user_name}')" title="Отправить на доработку">🔄Переделать</button>` : ''}
${isTaskCreator && assignment.status !== 'completed' ? 
`<button class="force-complete-btn" onclick="forceCompleteAssignment(${taskId}, ${assignment.user_id}, '${assignment.user_name}')" title="Принудительно отметить как выполненное">✅ Завершить</button>` : ''}
${canEdit ? 
`<button class="edit-date-btn" onclick="openEditAssignmentModal(${taskId}, ${assignment.user_id})" title="Редактировать сроки">📅 </button>` : ''}
            </div>
        </div>
    `;
}

function getAssignmentTimeLeftInfo(assignment) {
    if (!assignment.due_date || assignment.status === 'completed') return null;
    
    const dueDate = new Date(assignment.due_date);
    const now = new Date();
    const timeLeft = dueDate.getTime() - now.getTime();
    const hoursLeft = Math.floor(timeLeft / (60 * 60 * 1000));
    
    if (hoursLeft <= 0) return null;
    
    if (hoursLeft <= 24) {
        return {
            text: `Осталось ${hoursLeft}ч`,
            class: 'deadline-24h'
        };
    } else if (hoursLeft <= 48) {
        return {
            text: `Осталось ${hoursLeft}ч`,
            class: 'deadline-48h'
        };
    }
    
    return null;
}

function getTaskOverallStatus(task) {
    if (task.status === 'deleted') return 'deleted';
    if (task.closed_at) return 'closed';
    if (!task.assignments || task.assignments.length === 0) return 'unassigned';

    const assignments = task.assignments;
    let hasAssigned = false;
    let hasInProgress = false;
    let hasOverdue = false;
    let hasRework = false;
    let allCompleted = true;

    for (let assignment of assignments) {
        if (assignment.status === 'assigned') {
            hasAssigned = true;
            allCompleted = false;
        } else if (assignment.status === 'in_progress') {
            hasInProgress = true;
            allCompleted = false;
        } else if (assignment.status === 'overdue') {
            hasOverdue = true;
            allCompleted = false;
        } else if (assignment.status === 'rework') {
            hasRework = true;
            allCompleted = false;
        } else if (assignment.status !== 'completed') {
            allCompleted = false;
        }
    }

    if (allCompleted) return 'completed';
    if (hasRework) return 'rework';
    if (hasOverdue) return 'overdue';
    if (hasInProgress) return 'in_progress';
    if (hasAssigned) return 'assigned';
    return 'unassigned';
}

function getStatusClass(status) {
    switch (status) {
        case 'deleted': return 'status-gray';
        case 'closed': return 'status-gray';
        case 'unassigned': return 'status-purple';
        case 'assigned': return 'status-red';
        case 'in_progress': return 'status-orange';
        case 'rework': return 'status-yellow';
        case 'overdue': return 'status-darkred';
        case 'completed': return 'status-green';
        default: return 'status-purple';
    }
}

function getStatusText(status) {
    switch (status) {
        case 'deleted': return 'Удалена';
        case 'closed': return 'Закрыта';
        case 'unassigned': return 'Не назначена';
        case 'assigned': return 'Назначена';
        case 'in_progress': return 'В работе';
        case 'rework': return 'На доработке';
        case 'overdue': return 'Просрочена';
        case 'completed': return 'Выполнена';
        default: return 'Неизвестно';
    }
}

function getUserRoleInTask(task) {
    if (!currentUser) return 'Нет доступа';
    
    if (currentUser.role === 'admin') return 'Администратор';
    
    // Создатель задачи всегда должен иметь право редактировать свою задачу
    if (parseInt(task.created_by) === currentUser.id) {
        return 'Создатель';
    }
    
    if (task.assignments) {
        const isExecutor = task.assignments.some(assignment => 
            parseInt(assignment.user_id) === currentUser.id
        );
        if (isExecutor) return 'Исполнитель';
    }
    
    return 'Наблюдатель';
}

function getRoleBadgeClass(role) {
    switch (role) {
        case 'Администратор': return 'role-admin';
        case 'Заказчик': return 'role-creator';
        case 'Исполнитель': return 'role-executor';
        default: return '';
    }
}

function formatDateTime(dateTimeString) {
    if (!dateTimeString) return '';
    const date = new Date(dateTimeString);
    return date.toLocaleString('ru-RU');
}

function formatDateTimeForInput(dateTimeString) {
    if (!dateTimeString) return '';
    const date = new Date(dateTimeString);
    return date.toISOString().slice(0, 16);
}

// Логи активности
async function loadActivityLogs() {
    try {
        const response = await fetch('/api/activity-logs');
        const logs = await response.json();
        renderLogs(logs);
    } catch (error) {
        console.error('Ошибка загрузки логов:', error);
    }
}

function renderLogs(logs) {
    const container = document.getElementById('logs-list');
    
    if (logs.length === 0) {
        container.innerHTML = '<div class="loading">Логи не найдены</div>';
        return;
    }

    container.innerHTML = logs.map(log => `
        <div class="log-entry">
            <div class="log-time">${formatDateTime(log.created_at)}</div>
            <div><strong>${log.user_name}</strong> - ${getActionText(log.action)}</div>
            <div>Задача: "${log.task_title}"</div>
            ${log.details ? `<div>Детали: ${log.details}</div>` : ''}
        </div>
    `).join('');
}

function getActionText(action) {
    const actions = {
        'TASK_CREATED': 'создал задачу',
        'TASK_COPIED': 'создал копию задачи',
        'TASK_UPDATED': 'обновил задачу',
        'TASK_DELETED': 'удалил задачу',
        'TASK_RESTORED': 'восстановил задачу',
        'TASK_ASSIGNED': 'назначил задачу',
        'TASK_ASSIGNMENTS_UPDATED': 'обновил назначения',
        'ASSIGNMENT_UPDATED': 'обновил сроки исполнителя',
        'STATUS_CHANGED': 'изменил статус задачи',
        'FILE_UPLOADED': 'загрузил файл',
        'FILE_COPIED': 'скопировал файл',
        'TASK_SENT_FOR_REWORK': 'вернул задачу на доработку',
        'TASK_CLOSED': 'закрыл задачу',
        'TASK_REOPENED': 'открыл задачу'
    };
    
    return actions[action] || action;
}

// Функция для просмотра деталей задачи
async function viewTaskDetails(taskId) {
    try {
        const response = await fetch(`/api/tasks/${taskId}`);
        const task = await response.json();
        
        // Можно открыть модальное окно с подробной информацией
        // Или показать в отдельной секции
        alert(`Задача: ${task.title}\n\nОписание: ${task.description || 'Нет описания'}\n\nСоздатель: ${task.creator_name}\nСрок: ${task.due_date ? new Date(task.due_date).toLocaleString('ru-RU') : 'Не установлен'}`);
    } catch (error) {
        console.error('Ошибка загрузки деталей задачи:', error);
    }
}

// Функция для открытия модального окна добавления файла
function openAddFileModal(taskId) {
    // Находим задачу
    const task = tasks.find(t => t.id === taskId);
    if (!task) {
        alert('Задача не найдена');
        return;
    }

    // Проверяем права
    if (!canUserAddFilesToTask(task)) {
        alert('У вас нет прав для добавления файлов к этой задаче');
        return;
    }

    // Создаем модальное окно
    const modalHtml = `
        <div class="modal" id="add-file-modal">
            <div class="modal-content">
                <div class="modal-header">
                    <h3>Добавить файл к задаче: "${task.title}"</h3>
                    <span class="close" onclick="closeAddFileModal()">&times;</span>
                </div>
                <div class="modal-body">
                    <form id="add-file-form">
                        <input type="hidden" name="task_id" value="${taskId}">
                        
                        <div class="form-group">
                            <label for="file-input">Выберите файл:</label>
                            <input type="file" id="file-input" name="files" multiple>
                            <small>Максимальный размер: 10MB</small>
                        </div>
                        
                        <div class="form-group">
                            <label for="file-description">Описание файла (необязательно):</label>
                            <textarea id="file-description" name="description" rows="3" 
                                      placeholder="Описание файла..."></textarea>
                        </div>
                        
                        <div class="modal-footer">
                            <button type="button" class="btn-cancel" onclick="closeAddFileModal()">Отмена</button>
                            <button type="submit" class="btn-primary">Добавить файл</button>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    `;

    // Добавляем модальное окно в DOM
    const modalContainer = document.createElement('div');
    modalContainer.innerHTML = modalHtml;
    document.body.appendChild(modalContainer);

    // Обработчик отправки формы
    document.getElementById('add-file-form').addEventListener('submit', async function(e) {
        e.preventDefault();
        
        const fileInput = document.getElementById('file-input');
        const description = document.getElementById('file-description').value;
        
        if (fileInput.files.length === 0) {
            alert('Выберите файл для загрузки');
            return;
        }
        
        const file = fileInput.files[0];
        const formData = new FormData();
        
        // Пробуем сначала 'files', затем 'file'
        formData.append('files', file); // Или 'file' в зависимости от сервера
        formData.append('task_id', taskId);
        if (description) {
            formData.append('description', description);
        }
        
        try {
            // Попробуем с полем 'files' (скорее всего это правильное имя)
            let response = await fetch(`/api/tasks/${taskId}/files`, {
                method: 'POST',
                body: formData
            });
            console.log('Попытка 1');
            
            if (!response.ok) {
                // Попробуем с полем 'file'
                console.log('Попытка 2 с именем поля "file"...');
                formData.delete('files');
                formData.append('file', file);
                
                response = await fetch(`/api/tasks/${taskId}/files`, {
                    method: 'POST',
                    body: formData
                });
            }

            if (response.ok) {
                alert('Файл успешно добавлен');
                await loadTaskFiles(taskId);
                closeAddFileModal();
                
                // Обновляем задачу, если она развернута
                if (expandedTasks.has(taskId)) {
                    renderTasks();
                }
            } else {
                const errorText = await response.text();
                console.error('Ошибка сервера:', errorText);
                alert(`Ошибка при добавлении файла: ${response.status} ${response.statusText}`);
            }
        } catch (error) {
            console.error('Ошибка:', error);
            alert('Сетевая ошибка при добавлении файла: ' + error.message);
        }
    });

    // Показываем модальное окно
    setTimeout(() => {
        document.getElementById('add-file-modal').style.display = 'block';
    }, 10);
}

// Функция для закрытия модального окна добавления файла
function closeAddFileModal() {
    const modal = document.getElementById('add-file-modal');
    if (modal) {
        modal.style.display = 'none';
        // Удаляем модальное окно из DOM через некоторое время
        setTimeout(() => {
            modal.parentElement.remove();
        }, 300);
    }
}

// Функция для закрытия модального окна добавления файла
function closeAddFileModal() {
    const modal = document.getElementById('add-file-modal');
    if (modal) {
        modal.style.display = 'none';
        // Удаляем модальное окно из DOM через некоторое время
        setTimeout(() => {
            modal.parentElement.remove();
        }, 300);
    }
}

// Обновленная функция для загрузки файлов задачи
async function loadTaskFiles(taskId) {
    try {
        const response = await fetch(`/api/tasks/${taskId}/files`);
        const allFiles = await response.json();
        
        const taskIndex = tasks.findIndex(t => t.id === taskId);
        if (taskIndex === -1) {
            console.error('Задача не найдена:', taskId);
            return;
        }
        
        tasks[taskIndex].files = allFiles;
        
        const fileContainer = document.getElementById(`files-${taskId}`);
        if (fileContainer) {
            fileContainer.innerHTML = `
                <strong>Файлы:</strong> 
                ${allFiles.length > 0 ? 
                    (typeof renderGroupedFilesWithDelete === 'function' ? 
                        renderGroupedFilesWithDelete(tasks[taskIndex]) : 
                        renderGroupedFiles(tasks[taskIndex])) : 
                    '<span class="no-files">нет файлов</span>'}
            `;
        }
    } catch (error) {
        console.error('Ошибка загрузки файлов:', error);
    }
}

// Функция для выбора типа задачи
async function selectTaskType_old(type) {
    // Убираем активный класс со всех кнопок
    document.querySelectorAll('.task-type-btn').forEach(btn => {
        btn.classList.remove('active');
    });
    
    // Добавляем активный класс выбранной кнопке
    document.querySelector(`.task-type-btn[data-type="${type}"]`).classList.add('active');
    
    // Устанавливаем значение в скрытое поле
    document.getElementById('task-type').value = type;
    
    // Можем добавить дополнительную логику в зависимости от типа
    updateTaskFormBasedOnType(type);
    // Предлагаем заголовок по умолчанию
    suggestDefaultTitle(type);
    
    // Для типа "document" перезагружаем пользователей с фильтрацией
    if (type === 'document') {
        await reloadUsersForDocumentType();
    } else if (type === 'it') {
    await reloadUsersForType('ИТ специалист');
    } else if (type === 'ahch') {
    await reloadUsersForType('АХЧ');
    } else if (type === 'psychologist') {
    await reloadUsersForType('психолог');
    } else if (type === 'speech_therapist') {
    await reloadUsersForType('логопед');
    } else if (type === 'hr') {
    await reloadUsersForType('Диспетчер');
    } else if (type === 'certificate') {
    await reloadUsersForType('Администрация');
    } else if (type === 'e_journal') {
    await reloadUsersForType('Админ ЭЖ');
    } else {
        // Для других типов перезагружаем обычных пользователей
        await loadUsers();
    }
}
// ui.js - обновить функцию selectTaskType
async function selectTaskType(type) {
    // Убираем активный класс со всех кнопок
    document.querySelectorAll('.task-type-btn').forEach(btn => {
        btn.classList.remove('active');
    });
    
    // Добавляем активный класс выбранной кнопке
    const selectedBtn = document.querySelector(`.task-type-btn[data-type="${type}"]`);
    if (selectedBtn) {
        selectedBtn.classList.add('active');
    }
    
    // Устанавливаем значение в скрытое поле
    document.getElementById('task-type').value = type;
    
    // Обновляем форму
    updateTaskFormBasedOnType(type);
    suggestDefaultTitle(type);
    
    // Очищаем выбранных пользователей при смене типа
    selectedUsers = [];
    
    // Показываем загрузку
    const checklist = document.getElementById('users-checklist');
    if (checklist) {
        checklist.innerHTML = '<div class="loading-spinner">⏳ Загрузка доступных пользователей...</div>';
    }
    
    // Загружаем пользователей для выбранного типа
    try {
        if (type === 'document') {
            await reloadUsersForDocumentType();
        } else if (['it', 'ahch', 'psychologist', 'speech_therapist', 'hr', 'certificate', 'e_journal'].includes(type)) {
            const groupNames = {
                'it': 'ИТ специалист',
                'ahch': 'АХЧ',
                'psychologist': 'психолог',
                'speech_therapist': 'логопед',
                'hr': 'Диспетчер',
                'certificate': 'Администрация',
                'e_journal': 'Админ ЭЖ'
            };
            await reloadUsersForType(groupNames[type]);
        } else {
            await loadUsers();
        }
    } catch (error) {
        console.error('Ошибка загрузки пользователей:', error);
        if (checklist) {
            checklist.innerHTML = '<div class="error">Ошибка загрузки пользователей</div>';
        }
    }
}
// функция для перезагрузки пользователей для типа "document"
async function reloadUsersForDocumentType() {
    try {
        const response = await fetch('/api/users');
        const allUsersData = await response.json();
        
        // Фильтруем только пользователей из группы "Секретарь"
        const secretaries = [];
        for (const user of allUsersData) {
            if (user.id === currentUser.id) continue;
            
            const groups = await getUserGroups(user.id);
            const hasSecretaryGroup = groups.some(group => 
                group.name === 'Секретарь' || 
                (typeof group === 'string' && group.includes('Секретарь'))
            );
            
            if (hasSecretaryGroup) {
                secretaries.push(user);
            }
        }
        
        users = secretaries;
        filteredUsers = [...users];
        renderUsersChecklist();
        
    } catch (error) {
        console.error('Ошибка загрузки секретарей:', error);
    }
}
// функция для перезагрузки пользователей для типа "в переменной"
async function reloadUsersForType(TypegroupName) {
    try {
        const response = await fetch('/api/users');
        const allUsersData = await response.json();
        
        const TypegroupUsers = [];
        for (const user of allUsersData) {
            if (user.id === currentUser.id) continue;
            
            const groups = await getUserGroups(user.id);
            const hasTargetGroup = groups.some(group => 
                group.name === TypegroupName || 
                (typeof group === 'string' && group.includes(TypegroupName))
            );
            
            if (hasTargetGroup) {
                TypegroupUsers.push(user);
            }
        }
        
        users = TypegroupUsers;
        filteredUsers = [...users];
        renderUsersChecklist();
        
        return filteredUsers;
        
    } catch (error) {
        console.error(`Ошибка загрузки пользователей группы "${TypegroupName}":`, error);
        throw error;
    }
}
// Используем кэширование, чтобы не делать лишние запросы
async function getUserGroups(userId) {
    // Используем кэширование, чтобы не делать лишние запросы
    if (!window.userGroupsCache) window.userGroupsCache = {};
    
    if (window.userGroupsCache[userId]) {
        return window.userGroupsCache[userId];
    }
    
    try {
        const response = await fetch(`/api2/idusers/user/${userId}/groups`);
        if (!response.ok) return [];
        
        const groups = await response.json();
        window.userGroupsCache[userId] = groups || [];
        return window.userGroupsCache[userId];
    } catch (error) {
        console.error('Ошибка получения групп пользователя:', error);
        return [];
    }
}
// Функция для предложения заголовка по умолчанию
function suggestDefaultTitle(type) {
    const titleField = document.getElementById('title');
    if (!titleField) return;
    
    // Если поле уже заполнено, не меняем
    if (titleField.value.trim() !== '') return;
    
    const defaultTitles = {
        'regular': '',
        'document': 'Согласование документа: ',
        'it': 'Заявка в ИТ отдел: ',
        'ahch': 'Заявка в АХЧ: ',
        'psychologist': 'Заявка к психологу: ',
        'speech_therapist': 'Заявка к логопеду: ',
        'hr': 'Заявка диспетчеру расписания: ',
        'certificate': 'Заявка на получение справки: ',
        'e_journal': 'Заявка на доступ в электронный журнал: '
    };
    
    const defaultTitle = defaultTitles[type] || '';
    titleField.placeholder = `${defaultTitle}укажите детали...`;
}

// Функция для обновления формы в зависимости от типа задачи
function updateTaskFormBasedOnType(type) {
    const userSearchField = document.getElementById('user-search');
    const taskTypeInfo = document.getElementById('task-type-info');
    
    // Устанавливаем заголовки placeholder для поиска исполнителей
    const defaultPlaceholders = {
        'regular': 'Поиск исполнителей...',
        'document': 'Поиск секретарей/администрации...',
        'it': 'Поиск ИТ специалистов...',
        'ahch': 'Поиск АХЧ сотрудников...',
        'psychologist': 'Поиск психологов...',
        'speech_therapist': 'Поиск логопедов...',
        'hr': 'Поиск сотрудников кадровой службы...',
        'certificate': 'Поиск секретаря/завуча...',
        'e_journal': 'Поиск администратора электронного журнала...'
    };
    
    // Обновляем placeholder поля поиска исполнителей
    if (userSearchField) {
        userSearchField.placeholder = defaultPlaceholders[type] || 'Поиск исполнителей...';
    }
    // Показываем информацию о типе задачи
    if (taskTypeInfo) {
        const typeInfo = {
            'regular': 'Доступны все пользователи в зависимости от ваших прав',
            'document': 'Доступны только пользователи из группы "Секретарь"',
            'it': 'Доступны ИТ специалисты',
            'ahch': 'Доступны сотрудники АХЧ',
            'psychologist': 'Доступны психологи',
            'speech_therapist': 'Доступны логопеды',
            'hr': 'Доступны сотрудники кадровой службы',
            'certificate': 'Доступны секретари и завучи',
            'e_journal': 'Доступны администраторы электронного журнала'
        };
        
        taskTypeInfo.textContent = typeInfo[type] || '';
    }
    // Показываем/скрываем дополнительные поля в зависимости от типа
    showAdditionalFieldsForType(type);
}
// Функция для показа дополнительных полей
function showAdditionalFieldsForType(type) {
    // Пока скрываем все дополнительные поля (если они есть)
    hideAllAdditionalFields();
    
    // Показываем поля в зависимости от типа
    switch(type) {
        case 'certificate':
            showCertificateFields();
            break;
        case 'e_journal':
            showEJournalFields();
            break;
        case 'psychologist':
        case 'speech_therapist':
            showSpecialistFields(type);
            break;
        // Можно добавить другие типы
    }
}
// Функции для управления дополнительными полями
function hideAllAdditionalFields() {
    // Если есть дополнительные поля, скрываем их
    // Пока оставляем пустым, можно добавить позже
}

function showCertificateFields() {
    // Можно добавить поля для справок
    // Например: тип справки, для кого, срок действия
}

function showEJournalFields() {
    // Можно добавить поля для доступа к электронному журналу
    // Например: логин, класс, предметы
}

function showSpecialistFields(type) {
    // Можно добавить поля для специалистов
    // Например: ученик, класс, причина обращения
}
// Вспомогательная функция для получения названия типа задачи
function getTaskTypeName(type) {
    const typeNames = {
        'regular': 'задачу',
        'document': 'название документа',
        'it': 'описание проблемы',
        'ahch': 'описание заявки',
        'psychologist': 'повод для обращения к психологу',
        'speech_therapist': 'повод для обращения к логопеду',
        'hr': 'вопрос к кадровой службе',
        'certificate': 'тип необходимой справки',
        'e_journal': 'информацию для доступа к журналу'
    };
    return typeNames[type] || 'задачу';
}
// Функция для получения отображаемого имени типа задачи
function getTaskTypeDisplayName(type) {
    const typeNames = {
        'regular': 'Задача',
        'document': 'Документ',
        'it': 'ИТ',
        'ahch': 'АХЧ',
        'psychologist': 'Психолог',
        'speech_therapist': 'Логопед',
        'hr': 'Кадры',
        'certificate': 'Справка',
        'e_journal': 'Эл. журнал'
    };
    return typeNames[type] || type;
}

// Функция для получения иконки типа задачи
function getTaskTypeIcon(type) {
    const icons = {
        'regular': 'fas fa-tasks',
        'document': 'fas fa-file-signature',
        'it': 'fas fa-desktop',
        'ahch': 'fas fa-tools',
        'psychologist': 'fas fa-brain',
        'speech_therapist': 'fas fa-comment-medical',
        'hr': 'fas fa-users',
        'certificate': 'fas fa-file-certificate',
        'e_journal': 'fas fa-book'
    };
    return icons[type] || 'fas fa-tasks';
}

// Функция для открытия модального окна управления исполнителями
async function openManageAssigneesModal(taskId) {
    // Находим задачу
    const task = tasks.find(t => t.id === taskId);
    if (!task) {
        alert('Задача не найдена');
        return;
    }

    // Проверяем права
    if (!canUserEditTask(task)) {
        alert('У вас нет прав для управления исполнителями этой задачи');
        return;
    }

    // Получаем текущих исполнителей
    const currentAssignees = task.assignments || [];
    
    // Получаем доступных для добавления исполнителей
    try {
        const response = await fetch(`/api/tasks/${taskId}/available-assignees`);
        const availableUsers = await response.json();
        
        // Получаем всех пользователей для выбора замены
        const allUsersResponse = await fetch('/api/users');
        const allUsers = await allUsersResponse.json();
        
        // Создаем модальное окно
        const modalHtml = `
            <div class="modal" id="manage-assignees-modal">
                <div class="modal-content" style="max-width: 800px;">
                    <div class="modal-header">
                        <h3>Управление исполнителями задачи: "${task.title}"</h3>
                        <span class="close" onclick="closeManageAssigneesModal()">&times;</span>
                    </div>
                    <div class="modal-body">
                        <div class="tabs">
                            <button class="tab-btn active" onclick="switchManageTab('add')">➕ Добавить</button>
                            <button class="tab-btn" onclick="switchManageTab('remove')">➖ Удалить</button>
                            <button class="tab-btn" onclick="switchManageTab('replace-one')">🔄 Заменить одного</button>
                            <button class="tab-btn" onclick="switchManageTab('replace-all')">🔄 Заменить всех</button>
                            <button class="tab-btn" onclick="switchManageTab('assign-to-user')">👤 Назначить всем</button>
                        </div>
                        
                        <div id="add-assignee-tab" class="tab-content active">
                            <h4>Добавить исполнителей</h4>
                            <p>Текущие исполнители: ${currentAssignees.map(a => a.user_name).join(', ') || 'нет'}</p>
                            
                            <div class="user-search-box">
                                <input type="text" id="available-users-search" placeholder="Поиск пользователей..." 
                                       oninput="filterAvailableUsers()">
                            </div>
                            
                            <div class="users-checklist" id="available-users-list" style="max-height: 200px; overflow-y: auto;">
                                ${availableUsers.map(user => `
                                    <div class="checkbox-item">
                                        <label>
                                            <input type="checkbox" class="available-user-checkbox" value="${user.id}">
                                            ${user.name}
                                        </label>
                                    </div>
                                `).join('')}
                            </div>
                            
                            <div class="modal-footer">
                                <button type="button" class="btn-cancel" onclick="closeManageAssigneesModal()">Отмена</button>
                                <button type="button" class="btn-primary" onclick="addAssignees(${taskId})">Добавить выбранных</button>
                            </div>
                        </div>
                        
                        <div id="remove-assignee-tab" class="tab-content">
                            <h4>Удалить исполнителей</h4>
                            ${currentAssignees.length > 0 ? `
                                <div class="users-checklist" style="max-height: 200px; overflow-y: auto;">
                                    ${currentAssignees.map(assignee => `
                                        <div class="checkbox-item">
                                            <label>
                                                <input type="checkbox" class="remove-user-checkbox" value="${assignee.user_id}">
                                                ${assignee.user_name} (${assignee.user_login})
                                                <small>Статус: ${getStatusText(assignee.status)}</small>
                                            </label>
                                        </div>
                                    `).join('')}
                                </div>
                                <div class="modal-footer">
                                    <button type="button" class="btn-cancel" onclick="closeManageAssigneesModal()">Отмена</button>
                                    <button type="button" class="btn-danger" onclick="removeAssignees(${taskId})">Удалить выбранных</button>
                                </div>
                            ` : '<p>Нет исполнителей для удаления</p>'}
                        </div>
                        
                        <div id="replace-one-assignee-tab" class="tab-content">
                            <h4>Заменить одного исполнителя</h4>
                            ${currentAssignees.length > 0 ? `
                                <div class="form-group">
                                    <label>Выберите исполнителя для замены:</label>
                                    <select id="old-assignee-select" class="form-control">
                                        ${currentAssignees.map(assignee => `
                                            <option value="${assignee.user_id}">${assignee.user_name} (${assignee.user_login})</option>
                                        `).join('')}
                                    </select>
                                </div>
                                
                                <div class="form-group">
                                    <label>Выберите нового исполнителя:</label>
                                    <select id="new-assignee-select" class="form-control">
                                        <option value="">-- Выберите пользователя --</option>
                                        ${allUsers
                                            .filter(user => !currentAssignees.some(a => a.user_id === user.id))
                                            .map(user => `
                                                <option value="${user.id}">${user.name} (${user.email})</option>
                                            `).join('')}
                                    </select>
                                </div>
                                
                                <div class="modal-footer">
                                    <button type="button" class="btn-cancel" onclick="closeManageAssigneesModal()">Отмена</button>
                                    <button type="button" class="btn-warning" onclick="replaceAssignee(${taskId})">Заменить</button>
                                </div>
                            ` : '<p>Нет исполнителей для замены</p>'}
                        </div>
                        
                        <div id="replace-all-assignee-tab" class="tab-content">
                            <h4>Заменить всех исполнителей</h4>
                            <p>Текущие исполнители будут удалены, будут назначены новые.</p>
                            
                            <div class="user-search-box">
                                <input type="text" id="replace-all-users-search" placeholder="Поиск пользователей..." 
                                       oninput="filterReplaceAllUsers()">
                            </div>
                            
                            <div class="users-checklist" id="replace-all-users-list" style="max-height: 200px; overflow-y: auto;">
                                ${allUsers.map(user => `
                                    <div class="checkbox-item">
                                        <label>
                                            <input type="checkbox" class="replace-all-user-checkbox" value="${user.id}">
                                            ${user.name}
                                        </label>
                                    </div>
                                `).join('')}
                            </div>
                            
                            <div class="modal-footer">
                                <button type="button" class="btn-cancel" onclick="closeManageAssigneesModal()">Отмена</button>
                                <button type="button" class="btn-warning" onclick="replaceAllAssignees(${taskId})">Заменить всех</button>
                            </div>
                        </div>
                        
                        <div id="assign-to-user-tab" class="tab-content">
                            <h4>Назначить всем выбранному пользователю</h4>
                            <p>Все текущие исполнители будут удалены, задача будет назначена только выбранному пользователю.</p>
                            
                            <div class="form-group">
                                <label>Выберите пользователя:</label>
                                <select id="target-user-select" class="form-control">
                                    <option value="">-- Выберите пользователя --</option>
                                    ${allUsers.map(user => `
                                        <option value="${user.id}" ${user.login === 'kalugin.o' ? 'selected' : ''}>
                                            ${user.name} (${user.email})
                                        </option>
                                    `).join('')}
                                </select>
                            </div>
                            
                            <div class="modal-footer">
                                <button type="button" class="btn-cancel" onclick="closeManageAssigneesModal()">Отмена</button>
                                <button type="button" class="btn-primary" onclick="assignAllToUser(${taskId})">Назначить всем</button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        `;

        // Добавляем модальное окно в DOM
        const modalContainer = document.createElement('div');
        modalContainer.innerHTML = modalHtml;
        document.body.appendChild(modalContainer);

        // Показываем модальное окно
        setTimeout(() => {
            document.getElementById('manage-assignees-modal').style.display = 'block';
        }, 10);
        
    } catch (error) {
        console.error('Ошибка загрузки данных:', error);
        alert('Ошибка загрузки данных пользователей');
    }
}
// ========== ДОБАВЛЕНИЯ ИСПОЛНИТЕЛЕЙ ==========
async function assignAdd_openModal(taskId) {
    // Находим задачу
    const task = tasks.find(t => t.id === taskId);
    if (!task) {
        alert('Задача не найдена');
        return;
    }

    // Проверяем права
    if (!canUserEditTask(task)) {
        alert('У вас нет прав для управления исполнителями этой задачи');
        return;
    }

    // Получаем текущих исполнителей
    const currentAssignees = task.assignments || [];
    
    // Получаем доступных для добавления исполнителей
    try {
        const response = await fetch(`/api/tasks/${taskId}/available-assignees`);
        //const availableUsers = await response.json();
        let availableUsers = await response.json();
        
        // 👇 ИСКЛЮЧАЕМ АВТОРА ЗАДАЧИ ИЗ СПИСКА 👇
        const taskCreatorId = task.created_by;
        availableUsers = availableUsers.filter(user => 
            parseInt(user.id) !== parseInt(taskCreatorId)
        );

        // Создаем модальное окно
        const modalHtml = `
            <div class="modal" id="manage-assignees-modal">
                <div class="modal-content" style="max-width: 800px;">
                    <div class="modal-header">
                        <h3>Управление исполнителями задачи: "${task.title}"</h3>
                        <span class="close" onclick="closeManageAssigneesModal()">&times;</span>
                    </div>
                    <div class="modal-body">
                        <div id="add-assignee-tab" class="tab-content active">
                            <h4>Добавить исполнителей</h4>
                            <div class="user-search-box">
                                <input type="text" id="available-users-search" placeholder="Поиск пользователей..." 
                                       oninput="filterAvailableUsers()">
                            </div>
                            <div class="users-checklist" id="available-users-list" style="max-height: 200px; overflow-y: auto;">
                                ${availableUsers.map(user => `
                                    <div class="checkbox-item">
                                        <label>
                                            <input type="checkbox" class="available-user-checkbox" value="${user.id}">
                                            ${user.name}
                                        </label>
                                    </div>
                                `).join('')}
                            </div>
                            <div class="modal-footer">
                                <button type="button" class="btn-cancel" onclick="closeManageAssigneesModal()">Отмена</button>
                                <button type="button" class="btn-primary" onclick="addAssignees(${taskId})">Добавить выбранных</button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        `;

        // Добавляем модальное окно в DOM
        const modalContainer = document.createElement('div');
        modalContainer.innerHTML = modalHtml;
        document.body.appendChild(modalContainer);

        // Показываем модальное окно
        setTimeout(() => {
            document.getElementById('manage-assignees-modal').style.display = 'block';
        }, 10);
        
    } catch (error) {
        console.error('Ошибка загрузки данных:', error);
        alert('Ошибка загрузки данных пользователей');
    }
}
// ========== УДАЛЕНИЯ ИСПОЛНИТЕЛЕЙ ==========
async function assignRemove_openModal(taskId) {
    // Находим задачу
    const task = tasks.find(t => t.id === taskId);
    if (!task) {
        alert('Задача не найдена');
        return;
    }
    // Проверяем права
    if (!canUserEditTask(task)) {
        alert('У вас нет прав для управления исполнителями этой задачи');
        return;
    }
    // Получаем текущих исполнителей и фильтруем удаленных
    const currentAssignees = (task.assignments || []).filter(assignee => 
        assignee.status !== 'deleted' && assignee.status !== 'удален'
    );
        // Создаем модальное окно
        const modalHtml = `
            <div class="modal" id="manage-assignees-modal">
                <div class="modal-content" style="max-width: 800px;">
                    <div class="modal-header">
                        <h3>Управление исполнителями задачи: "${task.title}"</h3>
                        <span class="close" onclick="closeManageAssigneesModal()">&times;</span>
                    </div>
                    <div class="modal-body">
                        <div id="remove-assignee-tab" class="tab-content">
                            <h4>Удалить исполнителей</h4>
                            ${currentAssignees.length > 0 ? `
                                <div class="users-checklist" style="max-height: 200px; overflow-y: auto;">
                                    ${currentAssignees.map(assignee => `
                                        <div class="checkbox-item">
                                            <label>
                                                <input type="checkbox" class="remove-user-checkbox" value="${assignee.user_id}">
                                                ${assignee.user_name} (${assignee.user_login})
                                                <small>Статус: ${getStatusText(assignee.status)}</small>
                                            </label>
                                        </div>
                                    `).join('')}
                                </div>
                                <div class="modal-footer">
                                    <button type="button" class="btn-cancel" onclick="closeManageAssigneesModal()">Отмена</button>
                                    <button type="button" class="btn-danger" onclick="removeAssignees(${taskId})">Удалить выбранных</button>
                                </div>
                            ` : '<p>Нет исполнителей для удаления</p>'}
                        </div>
                    </div>
                </div>
            </div>
        `;

        // Добавляем модальное окно в DOM
        const modalContainer = document.createElement('div');
        modalContainer.innerHTML = modalHtml;
        document.body.appendChild(modalContainer);

        // Показываем модальное окно
        setTimeout(() => {
            document.getElementById('manage-assignees-modal').style.display = 'block';
        }, 10);
}

// Функция для переключения вкладок в модальном окне
function switchManageTab(tabName) {
    // Убираем активный класс со всех вкладок и контента
    document.querySelectorAll('.tab-btn').forEach(btn => btn.classList.remove('active'));
    document.querySelectorAll('.tab-content').forEach(content => content.classList.remove('active'));
    
    // Активируем выбранную вкладку
    const activeTabBtn = document.querySelector(`.tab-btn[onclick*="${tabName}"]`);
    if (activeTabBtn) activeTabBtn.classList.add('active');
    
    const activeContent = document.getElementById(`${tabName}-tab`);
    if (activeContent) activeContent.classList.add('active');
}

// Функция для фильтрации доступных пользователей
function filterAvailableUsers() {
    const search = document.getElementById('available-users-search')?.value.toLowerCase() || '';
    const checkboxes = document.querySelectorAll('.available-user-checkbox');
    
    checkboxes.forEach(checkbox => {
        const label = checkbox.parentElement.textContent.toLowerCase();
        const isVisible = label.includes(search) || search === '';
        checkbox.parentElement.parentElement.style.display = isVisible ? '' : 'none';
    });
}

// Функция для фильтрации пользователей для замены всех
function filterReplaceAllUsers() {
    const search = document.getElementById('replace-all-users-search')?.value.toLowerCase() || '';
    const checkboxes = document.querySelectorAll('.replace-all-user-checkbox');
    
    checkboxes.forEach(checkbox => {
        const label = checkbox.parentElement.textContent.toLowerCase();
        const isVisible = label.includes(search) || search === '';
        checkbox.parentElement.parentElement.style.display = isVisible ? '' : 'none';
    });
}

// Функция для добавления исполнителей
async function addAssignees(taskId) {
    const selectedCheckboxes = document.querySelectorAll('.available-user-checkbox:checked');
    const assigneeIds = Array.from(selectedCheckboxes).map(cb => cb.value);
    
    if (assigneeIds.length === 0) {
        alert('Выберите хотя бы одного пользователя для добавления');
        return;
    }
    
    try {
        const response = await fetch(`/api/tasks/${taskId}/assignees`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ assigneeIds })
        });
        
        if (response.ok) {
            const result = await response.json();
            alert(result.message);
            closeManageAssigneesModal();
            loadTasks(); // Перезагружаем задачи
        } else {
            const error = await response.json();
            alert(`Ошибка: ${error.error || 'Неизвестная ошибка'}`);
        }
    } catch (error) {
        console.error('Ошибка:', error);
        alert('Сетевая ошибка при добавлении исполнителей');
    }
}

// Функция для удаления исполнителей
async function removeAssignees(taskId) {
    const selectedCheckboxes = document.querySelectorAll('.remove-user-checkbox:checked');
    const assigneeIds = Array.from(selectedCheckboxes).map(cb => cb.value);
    
    if (assigneeIds.length === 0) {
        alert('Выберите хотя бы одного исполнителя для удаления');
        return;
    }
    
    if (!confirm(`Вы уверены, что хотите удалить ${assigneeIds.length} исполнителей из задачи?`)) {
        return;
    }
    
    // Удаляем каждого исполнителя по отдельности
    const results = [];
    for (const assigneeId of assigneeIds) {
        try {
            const response = await fetch(`/api/tasks/${taskId}/assignees/${assigneeId}`, {
                method: 'DELETE'
            });
            
            if (response.ok) {
                results.push({ id: assigneeId, success: true });
            } else {
                const error = await response.json();
                results.push({ id: assigneeId, success: false, error: error.error });
            }
        } catch (error) {
            results.push({ id: assigneeId, success: false, error: error.message });
        }
    }
    
    const successful = results.filter(r => r.success).length;
    const failed = results.filter(r => !r.success);
    
    if (failed.length > 0) {
        alert(`Удалено ${successful} исполнителей. Ошибки: ${failed.map(f => `ID ${f.id}: ${f.error}`).join('; ')}`);
    } else {
        alert(`Успешно удалено ${successful} исполнителей`);
    }
    
    closeManageAssigneesModal();
    loadTasks(); // Перезагружаем задачи
}

// Функция для замены одного исполнителя
async function replaceAssignee(taskId) {
    const oldAssigneeId = document.getElementById('old-assignee-select').value;
    const newAssigneeId = document.getElementById('new-assignee-select').value;
    
    if (!oldAssigneeId || !newAssigneeId) {
        alert('Выберите старого и нового исполнителя');
        return;
    }
    
    if (!confirm('Вы уверены, что хотите заменить исполнителя?')) {
        return;
    }
    
    try {
        const response = await fetch(`/api/tasks/${taskId}/replace-assignee`, {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ oldAssigneeId, newAssigneeId })
        });
        
        if (response.ok) {
            const result = await response.json();
            alert(result.message);
            closeManageAssigneesModal();
            loadTasks(); // Перезагружаем задачи
        } else {
            const error = await response.json();
            alert(`Ошибка: ${error.error || 'Неизвестная ошибка'}`);
        }
    } catch (error) {
        console.error('Ошибка:', error);
        alert('Сетевая ошибка при замене исполнителя');
    }
}

// Функция для замены всех исполнителей
async function replaceAllAssignees(taskId) {
    const selectedCheckboxes = document.querySelectorAll('.replace-all-user-checkbox:checked');
    const newAssigneeIds = Array.from(selectedCheckboxes).map(cb => cb.value);
    
    if (newAssigneeIds.length === 0) {
        alert('Выберите хотя бы одного нового исполнителя');
        return;
    }
    
    if (!confirm('Вы уверены, что хотите заменить всех исполнителей? Текущие исполнители будут удалены.')) {
        return;
    }
    
    try {
        const response = await fetch(`/api/tasks/${taskId}/replace-all-assignees`, {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ newAssigneeIds })
        });
        
        if (response.ok) {
            const result = await response.json();
            alert(result.message);
            closeManageAssigneesModal();
            loadTasks(); // Перезагружаем задачи
        } else {
            const error = await response.json();
            alert(`Ошибка: ${error.error || 'Неизвестная ошибка'}`);
        }
    } catch (error) {
        console.error('Ошибка:', error);
        alert('Сетевая ошибка при замене исполнителей');
    }
}

// Функция для назначения всех исполнителей одному пользователю
async function assignAllToUser(taskId) {
    const targetUserId = document.getElementById('target-user-select').value;
    
    if (!targetUserId) {
        alert('Выберите пользователя для назначения');
        return;
    }
    
    if (!confirm('Вы уверены, что хотите назначить задачу только этому пользователю? Все текущие исполнители будут удалены.')) {
        return;
    }
    
    try {
        const response = await fetch(`/api/tasks/${taskId}/assign-all-to-user`, {
            method: 'PUT',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({ targetUserId })
        });
        
        if (response.ok) {
            const result = await response.json();
            alert(result.message);
            closeManageAssigneesModal();
            loadTasks(); // Перезагружаем задачи
        } else {
            const error = await response.json();
            alert(`Ошибка: ${error.error || 'Неизвестная ошибка'}`);
        }
    } catch (error) {
        console.error('Ошибка:', error);
        alert('Сетевая ошибка при назначении задачи');
    }
}

// Функция для закрытия модального окна управления исполнителями
function closeManageAssigneesModal() {
    const modal = document.getElementById('manage-assignees-modal');
    if (modal) {
        modal.style.display = 'none';
        // Удаляем модальное окно из DOM через некоторое время
        setTimeout(() => {
            modal.parentElement.remove();
        }, 300);
    }
}

// Обновленная функция рендеринга файлов с группировкой по пользователям
function renderGroupedFiles(task) {
    if (!task.files || task.files.length === 0) {
        return '<span class="no-files">нет файлов</span>';
    }

    // 1. Группируем ВСЕ файлы по пользователю, который их загрузил
    const filesByUploader = {};
    
    // ВАЖНО: Используем все файлы задачи, а не отфильтрованные
    task.files.forEach(file => {
        const uploaderId = file.user_id;
        const uploaderName = file.user_name || 'Неизвестный пользователь';
        
        if (!filesByUploader[uploaderId]) {
            filesByUploader[uploaderId] = {
                name: uploaderName,
                id: uploaderId,
                files: []
            };
        }
        filesByUploader[uploaderId].files.push(file);
    });

    // 2. Определяем, какие группы (загрузчики) может видеть текущий пользователь
    const visibleGroups = [];
    
    for (const uploaderId in filesByUploader) {
        const uploaderGroup = filesByUploader[uploaderId];
        const uploaderIdNum = parseInt(uploaderId);
        
        // Проверяем, может ли текущий пользователь видеть файлы этого загрузчика
        let canSeeThisUploader = false;
        
        // 1. Администратор видит все файлы всех загрузчиков
        if (currentUser.role === 'admin') {
            canSeeThisUploader = true;
        }
        // 2. Создатель задачи видит все файлы всех загрузчиков
        else if (parseInt(task.created_by) === currentUser.id) {
            canSeeThisUploader = true;
        }
        // 3. Исполнитель видит:
        //    - Файлы создателя задачи
        //    - Свои файлы (если он их загрузил)
        else {
            const creatorId = parseInt(task.created_by);
            
            // Файлы загружены создателем задачи
            if (uploaderIdNum === creatorId) {
                canSeeThisUploader = true;
            }
            // Файлы загружены текущим пользователем
            else if (uploaderIdNum === currentUser.id) {
                canSeeThisUploader = true;
            }
            // Если файлы загружены другим исполнителем - не показываем эту группу
            else {
                canSeeThisUploader = false;
            }
        }
        
        // Если текущий пользователь может видеть эту группу, добавляем её
        if (canSeeThisUploader) {
            // В группе показываем ТОЛЬКО файлы этого загрузчика
            visibleGroups.push({
                name: uploaderGroup.name,
                id: uploaderGroup.id,
                files: uploaderGroup.files // Все файлы этого загрузчика
            });
        }
    }

    if (visibleGroups.length === 0) {
        return '<span class="no-files">нет файлов</span>';
    }
    
    // 3. Рендерим только видимые группы
    // Если файлы загружены только одним пользователем, показываем просто список
    if (visibleGroups.length === 1) {
        const uploader = visibleGroups[0];
        return `
            <div class="file-group single-user">
                <div class="file-group-header">
                    <strong>${uploader.name}:</strong>
                </div>
                <div class="file-icons-container">
                    ${uploader.files.map(file => renderFileIcon(file)).join('')}
                </div>
            </div>
        `;
    }
    
    // Если файлы загружены несколькими пользователями, группируем
    return visibleGroups.map(uploader => `
        <div class="file-group">
            <div class="file-group-header">
                <strong>${uploader.name}:</strong>
            </div>
            <div class="file-icons-container">
                ${uploader.files.map(file => renderFileIcon(file)).join('')}
            </div>
        </div>
    `).join('');
}