{% extends "layout.html" %}

{% block content %}
<div class="page-container">
    <!-- Header Section -->
    <div class="page-header">
        <div class="header-content">
            <div class="header-left">
                <h1 class="page-title">
                    <span class="page-icon"><i class="ti ti-clipboard-list"></i></span>
                    Task Management
                </h1>
                <p class="page-subtitle">Manage and track all tasks across projects</p>
            </div>
            <div class="header-actions">
                <button id="refresh-tasks" class="btn btn-secondary">
                    <i class="ti ti-refresh"></i>
                    Refresh
                </button>
                <button id="toggle-archived" class="btn btn-outline" title="Show/Hide Archived Tasks">
                    <i class="ti ti-archive"></i>
                    Show Archived
                </button>
                <button id="add-task-btn" class="btn btn-primary">
                    <i class="ti ti-plus"></i>
                    Add Task
                </button>
            </div>
        </div>
    </div>

    <!-- Search Section -->
    <div class="search-section">
        <div class="smart-search-container">
            <div class="smart-search-box">
                <input type="text" id="smart-search-input" class="smart-search-input" placeholder="Search tasks... (e.g., my-tasks priority:high, project:TimeTrack, overdue)">
                <button type="button" class="smart-search-clear" id="smart-search-clear" title="Clear search"><i class="ti ti-x"></i></button>
            </div>
            <div class="smart-search-suggestions" id="smart-search-suggestions" style="display: none;">
                <!-- Suggestions will be populated here -->
            </div>
        </div>
    </div>

    <!-- Task Statistics -->
    <div class="stats-section">
        <div class="stat-card">
            <div class="stat-value" id="total-tasks">0</div>
            <div class="stat-label">Total Tasks</div>
        </div>
        <div class="stat-card">
            <div class="stat-value" id="completed-tasks">0</div>
            <div class="stat-label">Completed</div>
        </div>
        <div class="stat-card">
            <div class="stat-value" id="in-progress-tasks">0</div>
            <div class="stat-label">In Progress</div>
        </div>
        <div class="stat-card">
            <div class="stat-value" id="overdue-tasks">0</div>
            <div class="stat-label">Overdue</div>
        </div>
        <div class="stat-card" id="archived-stat-card" style="display: none;">
            <div class="stat-value" id="archived-tasks">0</div>
            <div class="stat-label">Archived</div>
        </div>
    </div>

    <!-- Task Board -->
    <div class="task-board" id="task-board">
        <div class="task-column" data-status="TODO">
            <div class="column-header">
                <h3><i class="ti ti-circle"></i> To Do</h3>
                <span class="task-count">0</span>
            </div>
            <div class="column-content" id="column-TODO">
                <!-- Task cards will be populated here -->
            </div>
        </div>
        
        <div class="task-column" data-status="IN_PROGRESS">
            <div class="column-header">
                <h3><i class="ti ti-player-play"></i> In Progress</h3>
                <span class="task-count">0</span>
            </div>
            <div class="column-content" id="column-IN_PROGRESS">
                <!-- Task cards will be populated here -->
            </div>
        </div>
        
        <div class="task-column" data-status="IN_REVIEW">
            <div class="column-header">
                <h3><i class="ti ti-eye"></i> In Review</h3>
                <span class="task-count">0</span>
            </div>
            <div class="column-content" id="column-IN_REVIEW">
                <!-- Task cards will be populated here -->
            </div>
        </div>
        
        <div class="task-column" data-status="DONE">
            <div class="column-header">
                <h3><i class="ti ti-circle-check"></i> Done</h3>
                <span class="task-count">0</span>
            </div>
            <div class="column-content" id="column-DONE">
                <!-- Task cards will be populated here -->
            </div>
        </div>
        
        <div class="task-column" data-status="CANCELLED">
            <div class="column-header">
                <h3><i class="ti ti-circle-x"></i> Cancelled</h3>
                <span class="task-count">0</span>
            </div>
            <div class="column-content" id="column-CANCELLED">
                <!-- Task cards will be populated here -->
            </div>
        </div>
        
        <div class="task-column archived-column" data-status="ARCHIVED" style="display: none;">
            <div class="column-header">
                <h3><i class="ti ti-archive"></i> Archived</h3>
                <span class="task-count">0</span>
            </div>
            <div class="column-content" id="column-ARCHIVED">
                <!-- Archived task cards will be populated here -->
            </div>
        </div>
    </div>

    <!-- Loading and Error States -->
    <div id="loading-indicator" class="loading-spinner" style="display: none;">
        <div class="spinner"></div>
        <p>Loading tasks...</p>
    </div>
    
    <div id="error-message" class="error-alert" style="display: none;">
        <p>Failed to load tasks. Please try again.</p>
    </div>
</div>

<!-- Include Task Modal -->
{% include 'task_modal.html' %}

<!-- Styles -->
<style>
/* Header adjustments for Task Management */
.header-actions {
    display: flex;
    gap: 0.75rem;
    align-items: center;
    flex-wrap: wrap;
}

/* Search Section */
.search-section {
    margin-bottom: 1.5rem;
    padding: 1rem;
    background: #f8f9fa;
    border-radius: 8px;
}

/* Smart Search Styles */
.smart-search-container {
    position: relative;
    width: 100%;
}

.smart-search-box {
    position: relative;
    display: flex;
    align-items: center;
}

.smart-search-input {
    width: 100%;
    padding: 0.5rem 2.5rem 0.5rem 0.75rem;
    border: 1px solid #ddd;
    border-radius: 4px;
    font-size: 14px;
    transition: border-color 0.2s, box-shadow 0.2s;
    background: white;
}

.smart-search-input:focus {
    outline: none;
    border-color: #007bff;
    box-shadow: 0 0 0 2px rgba(0, 123, 255, 0.1);
}

.smart-search-clear {
    position: absolute;
    right: 0.5rem;
    background: none;
    border: none;
    font-size: 16px;
    color: #999;
    cursor: pointer;
    padding: 0.25rem;
    border-radius: 3px;
    width: 24px;
    height: 24px;
    display: flex;
    align-items: center;
    justify-content: center;
    transition: background-color 0.2s, color 0.2s;
}

.smart-search-clear:hover {
    background-color: #f0f0f0;
    color: #333;
}

.smart-search-suggestions {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    background: white;
    border: 1px solid #ddd;
    border-top: none;
    border-radius: 0 0 4px 4px;
    max-height: 200px;
    overflow-y: auto;
    z-index: 1000;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.suggestion-item {
    padding: 0.5rem 0.75rem;
    cursor: pointer;
    border-bottom: 1px solid #f0f0f0;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    transition: background-color 0.1s;
    font-size: 14px;
}

.suggestion-item:hover,
.suggestion-item.active {
    background-color: #f8f9fa;
}

.suggestion-item:last-child {
    border-bottom: none;
}

.suggestion-type {
    background: #e9ecef;
    color: #495057;
    padding: 0.125rem 0.375rem;
    border-radius: 3px;
    font-size: 0.7rem;
    font-weight: 500;
    text-transform: uppercase;
}

.suggestion-value {
    font-weight: 500;
    color: #333;
}

.suggestion-description {
    color: #6c757d;
    font-size: 0.8rem;
}

/* Task Management specific styles removed - using common page styles */

/* Responsive adjustments handled by common page styles */

/* Subtask progress styles */
.task-subtasks {
    margin-top: 0.75rem;
    padding-top: 0.75rem;
    border-top: 1px solid #e9ecef;
}

.subtask-progress {
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.subtask-progress-bar {
    flex: 1;
    height: 6px;
    background: #e9ecef;
    border-radius: 3px;
    overflow: hidden;
}

.subtask-progress-fill {
    height: 100%;
    background: #28a745;
    transition: width 0.3s ease;
}

.subtask-count {
    font-size: 0.75rem;
    color: #6c757d;
    white-space: nowrap;
}




.task-board {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(210px, 1fr));
    gap: 1rem;
    margin-bottom: 2rem;
}

.task-column {
    background: #f8f9fa;
    border-radius: 8px;
    padding: 1rem;
    min-height: 500px;
}

.column-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
    padding-bottom: 0.5rem;
    border-bottom: 2px solid #ddd;
}

.column-header h3 {
    margin: 0;
    font-size: 1.1rem;
    color: #333;
}

.task-count {
    background: #007bff;
    color: white;
    padding: 0.25rem 0.5rem;
    border-radius: 12px;
    font-size: 0.8rem;
}

/* Archived Column Styles */
.archived-column {
    background: #f1f3f4;
    border: 2px dashed #9aa0a6;
    opacity: 0.8;
}

.archived-column .column-header {
    border-bottom-color: #9aa0a6;
}

.archived-column .task-count {
    background: #9aa0a6;
}

/* Archived Task Card Styles */
.archived-column .task-card {
    opacity: 0.7;
    border-left: 4px solid #9aa0a6;
}

/* Button Styles */
.btn.btn-outline {
    background: transparent;
    border: 1px solid #6c757d;
    color: #6c757d;
}

.btn.btn-outline:hover {
    background: #6c757d;
    color: white;
}

.btn.btn-outline.active {
    background: #6c757d;
    color: white;
}

/* Task Action Buttons */
.task-actions {
    display: flex;
    justify-content: flex-end;
    gap: 0.25rem;
}

.archive-btn, .restore-btn {
    background: none;
    border: 1px solid #ccc;
    border-radius: 4px;
    padding: 0.25rem 0.5rem;
    cursor: pointer;
    font-size: 0.85rem;
    transition: all 0.2s;
}

.archive-btn:hover {
    background: #f8f9fa;
    border-color: #6c757d;
}

.restore-btn:hover {
    background: #e3f2fd;
    border-color: #007bff;
}

/* Task Date Displays */
.task-completed-date, .task-archived-date {
    font-size: 0.75rem;
    color: #6c757d;
    margin-top: 0.25rem;
    font-style: italic;
}

.task-completed-date {
    color: #28a745;
}

.task-archived-date {
    color: #9aa0a6;
}

.column-content {
    min-height: 400px;
    padding: 0.5rem 0;
}

.task-card {
    background: white;
    border: 1px solid #ddd;
    border-radius: 6px;
    padding: 1rem;
    margin-bottom: 0.75rem;
    cursor: pointer;
    transition: box-shadow 0.2s, transform 0.1s;
}

.task-card:hover {
    box-shadow: 0 2px 8px rgba(0,0,0,0.1);
    transform: translateY(-1px);
}

.task-card.dragging {
    opacity: 0.5;
    transform: rotate(5deg);
}

.task-card-header {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    margin-bottom: 0.5rem;
}

.task-title-section {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    flex: 1;
}

.task-number {
    font-family: 'Courier New', monospace;
    font-size: 0.75rem;
    font-weight: 600;
    color: #007bff;
    background: #e3f2fd;
    padding: 0.125rem 0.375rem;
    border-radius: 3px;
    align-self: flex-start;
}

.task-title {
    font-weight: bold;
    margin: 0;
    color: #333;
    font-size: 0.95rem;
}


.task-project {
    font-size: 0.8rem;
    color: #666;
    margin-bottom: 0.5rem;
}

.task-meta {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: 0.8rem;
    color: #666;
}

.task-assignee {
    font-weight: 500;
    display: flex;
    align-items: center;
    gap: 0.25rem;
}

.task-assignee-avatar {
    width: 20px;
    height: 20px;
    border-radius: 50%;
    object-fit: cover;
    border: 1px solid #e9ecef;
}

.task-due-date {
    color: #666;
}

.task-due-date.overdue {
    color: #dc3545;
    font-weight: bold;
}





@media (max-width: 768px) {
    .task-board {
        grid-template-columns: 1fr;
    }
}
</style>

<!-- SortableJS for drag and drop -->
<script src="https://cdn.jsdelivr.net/npm/sortablejs@latest/Sortable.min.js"></script>

<script>
// User preferences for date formatting
const USER_DATE_FORMAT = '{{ g.user.preferences.date_format if g.user.preferences else "ISO" }}';

// Date formatting utility function
function formatUserDate(dateString) {
    if (!dateString) return '';
    
    const date = new Date(dateString);
    if (isNaN(date.getTime())) return '';
    
    switch (USER_DATE_FORMAT) {
        case 'US':
            return date.toLocaleDateString('en-US'); // MM/DD/YYYY
        case 'EU':
        case 'UK':
            return date.toLocaleDateString('en-GB'); // DD/MM/YYYY
        case 'Readable':
            return date.toLocaleDateString('en-US', { 
                weekday: 'short', 
                year: 'numeric', 
                month: 'short', 
                day: 'numeric' 
            }); // Mon, Dec 25, 2024
        case 'ISO':
        default:
            return date.toISOString().split('T')[0]; // YYYY-MM-DD
    }
}

// Date input formatting function - formats ISO date for user input
function formatDateForInput(isoDateString) {
    if (!isoDateString) return '';
    
    const date = new Date(isoDateString);
    if (isNaN(date.getTime())) return '';
    
    return formatUserDate(isoDateString);
}

// Date parsing function - converts user-formatted date to ISO format
function parseUserDate(dateString) {
    if (!dateString || dateString.trim() === '') return null;
    
    const trimmed = dateString.trim();
    let date;
    
    switch (USER_DATE_FORMAT) {
        case 'US': // MM/DD/YYYY
            const usParts = trimmed.split('/');
            if (usParts.length === 3) {
                const month = parseInt(usParts[0], 10);
                const day = parseInt(usParts[1], 10);
                const year = parseInt(usParts[2], 10);
                if (month >= 1 && month <= 12 && day >= 1 && day <= 31 && year > 1900) {
                    date = new Date(year, month - 1, day);
                }
            }
            break;
            
        case 'EU':
        case 'UK': // DD/MM/YYYY
            const euParts = trimmed.split('/');
            if (euParts.length === 3) {
                const day = parseInt(euParts[0], 10);
                const month = parseInt(euParts[1], 10);
                const year = parseInt(euParts[2], 10);
                if (month >= 1 && month <= 12 && day >= 1 && day <= 31 && year > 1900) {
                    date = new Date(year, month - 1, day);
                }
            }
            break;
            
        case 'Readable': // Mon, Dec 25, 2024
            date = new Date(trimmed);
            break;
            
        case 'ISO': // YYYY-MM-DD
        default:
            if (/^\d{4}-\d{2}-\d{2}$/.test(trimmed)) {
                date = new Date(trimmed);
            }
            break;
    }
    
    if (!date || isNaN(date.getTime())) {
        return null;
    }
    
    return date.toISOString().split('T')[0];
}

// Date validation function
function validateDateInput(inputElement, errorElement) {
    const value = inputElement.value.trim();
    if (!value) {
        errorElement.style.display = 'none';
        return true;
    }
    
    const parsedDate = parseUserDate(value);
    if (!parsedDate) {
        let expectedFormat;
        switch (USER_DATE_FORMAT) {
            case 'US': expectedFormat = 'MM/DD/YYYY'; break;
            case 'EU':
            case 'UK': expectedFormat = 'DD/MM/YYYY'; break;
            case 'Readable': expectedFormat = 'Mon, Dec 25, 2024'; break;
            case 'ISO':
            default: expectedFormat = 'YYYY-MM-DD'; break;
        }
        errorElement.textContent = `Invalid date format. Expected: ${expectedFormat}`;
        errorElement.style.display = 'block';
        return false;
    }
    
    errorElement.style.display = 'none';
    return true;
}

// Hybrid Date Input Functions
function setupHybridDateInput(inputId) {
    const formattedInput = document.getElementById(inputId);
    const nativeInput = document.getElementById(inputId + '-native');
    
    if (!formattedInput || !nativeInput) return;
    
    // Sync from native input to formatted input
    nativeInput.addEventListener('change', function() {
        if (this.value) {
            formattedInput.value = formatDateForInput(this.value);
            // Trigger change event on formatted input
            formattedInput.dispatchEvent(new Event('change'));
        }
    });
    
    // Sync from formatted input to native input
    formattedInput.addEventListener('change', function() {
        const isoDate = parseUserDate(this.value);
        if (isoDate) {
            nativeInput.value = isoDate;
        } else {
            nativeInput.value = '';
        }
    });
    
    // Clear both inputs when formatted input is cleared
    formattedInput.addEventListener('input', function() {
        if (this.value === '') {
            nativeInput.value = '';
        }
    });
}

function openCalendarPicker(inputId) {
    const nativeInput = document.getElementById(inputId + '-native');
    if (nativeInput) {
        nativeInput.focus();
        
        // Try showPicker() first for modern browsers
        if (nativeInput.showPicker) {
            try {
                nativeInput.showPicker();
            } catch (e) {
                // Fallback to click if showPicker fails
                nativeInput.click();
            }
        } else {
            // Fallback for older browsers
            nativeInput.click();
        }
    }
}

// Smart Search Parser
class SmartTaskSearch {
    constructor() {
        this.searchTokens = {
            'assigned:': { 
                type: 'user', 
                suggestions: [],
                description: 'Filter by assigned user'
            },
            'created-by:': { 
                type: 'user', 
                suggestions: [],
                description: 'Filter by task creator'
            },
            'project:': { 
                type: 'project', 
                suggestions: [],
                description: 'Filter by project'
            },
            'sprint:': { 
                type: 'sprint', 
                suggestions: [],
                description: 'Filter by sprint'
            },
            'status:': { 
                type: 'status', 
                suggestions: ['not-started', 'in-progress', 'on-hold', 'completed'],
                description: 'Filter by task status'
            },
            'priority:': { 
                type: 'priority', 
                suggestions: ['low', 'medium', 'high', 'urgent'],
                description: 'Filter by priority level'
            },
            'due:': { 
                type: 'date', 
                suggestions: ['today', 'tomorrow', 'this-week', 'next-week', 'overdue'],
                description: 'Filter by due date'
            },
            'created:': { 
                type: 'date', 
                suggestions: ['today', 'yesterday', 'this-week', 'last-week'],
                description: 'Filter by creation date'
            }
        };
        
        this.specialKeywords = [
            { value: 'overdue', type: 'keyword', description: 'Tasks past their due date' },
            { value: 'unassigned', type: 'keyword', description: 'Tasks without assignee' },
            { value: 'my-tasks', type: 'view', description: 'Tasks assigned to me' },
            { value: 'all-tasks', type: 'view', description: 'All tasks in the system' },
            { value: 'project-tasks', type: 'view', description: 'Tasks grouped by project' },
            { value: 'urgent', type: 'keyword', description: 'High priority tasks' }
        ];
        
        // Add team-tasks only if user has a team
        const hasTeam = {{ 'true' if g.user.team_id else 'false' }};
        if (hasTeam) {
            this.specialKeywords.splice(4, 0, { 
                value: 'team-tasks', 
                type: 'view', 
                description: 'Tasks for my team' 
            });
        }
        
        this.currentSuggestionIndex = -1;
    }
    
    parseQuery(searchText) {
        const filters = {
            assignee: '',
            creator: '',
            project: '',
            sprint: '',
            status: '',
            priority: '',
            dueDate: '',
            createdDate: '',
            view: '',
            keywords: []
        };
        
        // Split search text into tokens
        const tokens = searchText.match(/\S+/g) || [];
        
        for (const token of tokens) {
            if (token.includes(':')) {
                const [key, value] = token.split(':', 2);
                const fullKey = key + ':';
                
                switch (fullKey) {
                    case 'assigned:':
                        filters.assignee = value.replace('@', '');
                        break;
                    case 'created-by:':
                        filters.creator = value.replace('@', '');
                        break;
                    case 'project:':
                        filters.project = value;
                        break;
                    case 'sprint:':
                        filters.sprint = value;
                        break;
                    case 'status:':
                        filters.status = this.normalizeStatus(value);
                        break;
                    case 'priority:':
                        filters.priority = value.toUpperCase();
                        break;
                    case 'due:':
                        filters.dueDate = this.parseDate(value);
                        break;
                    case 'created:':
                        filters.createdDate = this.parseDate(value);
                        break;
                }
            } else {
                // Handle special keywords and view keywords
                const lowerToken = token.toLowerCase();
                if (['my-tasks', 'all-tasks', 'team-tasks', 'project-tasks'].includes(lowerToken)) {
                    filters.view = lowerToken;
                } else {
                    filters.keywords.push(lowerToken);
                }
            }
        }
        
        return filters;
    }
    
    normalizeStatus(status) {
        const statusMap = {
            'not-started': 'TODO',
            'to-do': 'TODO',
            'todo': 'TODO',
            'in-progress': 'IN_PROGRESS',
            'in-review': 'IN_REVIEW',
            'on-hold': 'IN_REVIEW',
            'completed': 'DONE',
            'done': 'DONE',
            'cancelled': 'CANCELLED',
            'archived': 'ARCHIVED'
        };
        return statusMap[status.toLowerCase()] || status.toUpperCase();
    }
    
    parseDate(dateStr) {
        const today = new Date();
        const todayStart = new Date(today.getFullYear(), today.getMonth(), today.getDate());
        
        switch (dateStr.toLowerCase()) {
            case 'today':
                return {
                    start: todayStart,
                    end: new Date(todayStart.getTime() + 24 * 60 * 60 * 1000 - 1)
                };
            case 'yesterday':
                const yesterday = new Date(todayStart.getTime() - 24 * 60 * 60 * 1000);
                return {
                    start: yesterday,
                    end: new Date(yesterday.getTime() + 24 * 60 * 60 * 1000 - 1)
                };
            case 'tomorrow':
                const tomorrow = new Date(todayStart.getTime() + 24 * 60 * 60 * 1000);
                return {
                    start: tomorrow,
                    end: new Date(tomorrow.getTime() + 24 * 60 * 60 * 1000 - 1)
                };
            case 'this-week':
                const startOfWeek = new Date(todayStart);
                startOfWeek.setDate(todayStart.getDate() - todayStart.getDay());
                const endOfWeek = new Date(startOfWeek.getTime() + 7 * 24 * 60 * 60 * 1000 - 1);
                return { start: startOfWeek, end: endOfWeek };
            case 'overdue':
                return { end: todayStart, type: 'before' };
            default:
                // Try to parse as ISO date
                if (/^\d{4}-\d{2}-\d{2}$/.test(dateStr)) {
                    const date = new Date(dateStr);
                    return {
                        start: date,
                        end: new Date(date.getTime() + 24 * 60 * 60 * 1000 - 1)
                    };
                }
                return null;
        }
    }
    
    async getSuggestions(query, cursorPosition) {
        const suggestions = [];
        
        // Get the current token being typed
        const beforeCursor = query.substring(0, cursorPosition);
        const tokens = beforeCursor.split(/\s+/);
        const currentToken = tokens[tokens.length - 1] || '';
        
        // Check if we're typing a token with ':'
        if (currentToken.includes(':')) {
            const [key, partial] = currentToken.split(':', 2);
            const fullKey = key + ':';
            
            if (this.searchTokens[fullKey]) {
                const tokenInfo = this.searchTokens[fullKey];
                
                // Get suggestions for this token type
                if (tokenInfo.type === 'user') {
                    const users = await this.fetchUserSuggestions(partial);
                    users.forEach(user => {
                        suggestions.push({
                            type: 'user',
                            value: `${key}:@${user.username}`,
                            display: `@${user.username}`,
                            description: `Assigned to ${user.username}`
                        });
                    });
                } else if (tokenInfo.type === 'project') {
                    const projects = await this.fetchProjectSuggestions(partial);
                    projects.forEach(project => {
                        suggestions.push({
                            type: 'project',
                            value: `${key}:${project.code}`,
                            display: project.code,
                            description: project.name
                        });
                    });
                } else if (tokenInfo.type === 'sprint') {
                    const sprints = await this.fetchSprintSuggestions(partial);
                    sprints.forEach(sprint => {
                        suggestions.push({
                            type: 'sprint',
                            value: `${key}:${sprint.name}`,
                            display: sprint.name,
                            description: `Sprint (${sprint.status})`
                        });
                    });
                } else {
                    // Static suggestions
                    tokenInfo.suggestions
                        .filter(s => s.toLowerCase().includes(partial.toLowerCase()))
                        .forEach(suggestion => {
                            suggestions.push({
                                type: tokenInfo.type,
                                value: `${key}:${suggestion}`,
                                display: suggestion,
                                description: tokenInfo.description
                            });
                        });
                }
            }
        } else {
            // Suggest token keys
            Object.keys(this.searchTokens).forEach(tokenKey => {
                if (tokenKey.toLowerCase().includes(currentToken.toLowerCase())) {
                    suggestions.push({
                        type: 'token',
                        value: tokenKey,
                        display: tokenKey,
                        description: this.searchTokens[tokenKey].description
                    });
                }
            });
            
            // Suggest special keywords
            this.specialKeywords
                .filter(keyword => keyword.value.toLowerCase().includes(currentToken.toLowerCase()))
                .forEach(keyword => {
                    suggestions.push({
                        type: keyword.type,
                        value: keyword.value,
                        display: keyword.value,
                        description: keyword.description
                    });
                });
        }
        
        return suggestions.slice(0, 8); // Limit to 8 suggestions
    }
    
    async fetchUserSuggestions(partial) {
        try {
            const response = await fetch(`/api/search/users?q=${encodeURIComponent(partial)}`);
            const data = await response.json();
            return data.success ? data.users : [];
        } catch (error) {
            console.error('Error fetching user suggestions:', error);
            return [];
        }
    }
    
    async fetchProjectSuggestions(partial) {
        try {
            const response = await fetch(`/api/search/projects?q=${encodeURIComponent(partial)}`);
            const data = await response.json();
            return data.success ? data.projects : [];
        } catch (error) {
            console.error('Error fetching project suggestions:', error);
            return [];
        }
    }
    
    async fetchSprintSuggestions(partial) {
        try {
            const response = await fetch(`/api/search/sprints?q=${encodeURIComponent(partial)}`);
            const data = await response.json();
            return data.success ? data.sprints : [];
        } catch (error) {
            console.error('Error fetching sprint suggestions:', error);
            return [];
        }
    }
}

// Task Management Controller
class UnifiedTaskManager {
    constructor() {
        this.tasks = [];
        this.currentView = 'all';
        this.filters = {
            project: '',
            assignee: '',
            priority: '',
            status: '',
            startDate: '',
            endDate: '',
            dateField: 'created',
            sprint: ''
        };
        this.currentTask = null;
        this.sortableInstances = [];
        this.showArchived = false;
        this.currentUserId = {{ g.user.id|tojson }};
        this.smartSearch = new SmartTaskSearch();
        this.searchQuery = '';
        this.isSearching = false;
    }

    async init() {
        this.setupEventListeners();
        this.setupSortable();
        await this.loadTasks();
    }

    getUserAvatar(userId) {
        // Find user in team members
        const user = window.teamMembers.find(member => member.id === userId);
        if (user && user.avatar_url) {
            return user.avatar_url;
        }
        
        // Generate default avatar using DiceBear API
        const username = user ? user.username : `user_${userId}`;
        const hash = this.hashCode(username + '_' + userId);
        return `https://api.dicebear.com/7.x/initials/svg?seed=${hash}&size=24&backgroundColor=ffffff`;
    }
    
    hashCode(str) {
        let hash = 0;
        for (let i = 0; i < str.length; i++) {
            const char = str.charCodeAt(i);
            hash = ((hash << 5) - hash) + char;
            hash = hash & hash; // Convert to 32bit integer
        }
        return Math.abs(hash).toString(16);
    }

    setupEventListeners() {
        // Smart Search
        this.setupSmartSearch();
        


        // Actions
        document.getElementById('add-task-btn').addEventListener('click', () => {
            this.openTaskModal();
        });

        document.getElementById('refresh-tasks').addEventListener('click', () => {
            this.loadTasks();
        });

        document.getElementById('toggle-archived').addEventListener('click', () => {
            this.toggleArchivedView();
        });
        
        // Date validation
        document.getElementById('task-due-date').addEventListener('blur', () => {
            const input = document.getElementById('task-due-date');
            const error = document.getElementById('task-due-date-error');
            validateDateInput(input, error);
        });
        
        // Setup hybrid date inputs
        setupHybridDateInput('task-due-date');
    }

    setupSortable() {
        const columns = document.querySelectorAll('.column-content');
        columns.forEach(column => {
            const sortable = Sortable.create(column, {
                group: 'tasks',
                animation: 150,
                onEnd: (evt) => {
                    this.handleTaskMove(evt);
                }
            });
            this.sortableInstances.push(sortable);
        });
    }

    setupSmartSearch() {
        const searchInput = document.getElementById('smart-search-input');
        const searchClear = document.getElementById('smart-search-clear');
        const suggestions = document.getElementById('smart-search-suggestions');
        
        let suggestionTimeout;
        
        // Search input handling
        searchInput.addEventListener('input', async (e) => {
            const query = e.target.value;
            this.searchQuery = query;
            
            // Clear previous timeout
            clearTimeout(suggestionTimeout);
            
            if (query.trim() === '') {
                suggestions.style.display = 'none';
                this.clearSmartSearch();
                return;
            }
            
            // Debounce suggestions
            suggestionTimeout = setTimeout(async () => {
                await this.showSuggestions(query, e.target.selectionStart);
            }, 200);
        });
        
        // Handle key navigation
        searchInput.addEventListener('keydown', (e) => {
            if (suggestions.style.display === 'none') return;
            
            const suggestionItems = suggestions.querySelectorAll('.suggestion-item');
            
            switch (e.key) {
                case 'ArrowDown':
                    e.preventDefault();
                    this.smartSearch.currentSuggestionIndex = 
                        Math.min(this.smartSearch.currentSuggestionIndex + 1, suggestionItems.length - 1);
                    this.updateSuggestionSelection();
                    break;
                case 'ArrowUp':
                    e.preventDefault();
                    this.smartSearch.currentSuggestionIndex = 
                        Math.max(this.smartSearch.currentSuggestionIndex - 1, -1);
                    this.updateSuggestionSelection();
                    break;
                case 'Enter':
                    e.preventDefault();
                    if (this.smartSearch.currentSuggestionIndex >= 0) {
                        this.applySuggestion(suggestionItems[this.smartSearch.currentSuggestionIndex]);
                    } else {
                        this.applySmartSearch();
                    }
                    break;
                case 'Escape':
                    suggestions.style.display = 'none';
                    break;
                case 'Tab':
                    if (this.smartSearch.currentSuggestionIndex >= 0) {
                        e.preventDefault();
                        this.applySuggestion(suggestionItems[this.smartSearch.currentSuggestionIndex]);
                    }
                    break;
            }
        });
        
        // Apply search on enter or when losing focus
        searchInput.addEventListener('keypress', (e) => {
            if (e.key === 'Enter' && suggestions.style.display === 'none') {
                this.applySmartSearch();
            }
        });
        
        searchInput.addEventListener('blur', () => {
            // Delay hiding suggestions to allow clicking
            setTimeout(() => {
                suggestions.style.display = 'none';
            }, 200);
        });
        
        // Clear search
        searchClear.addEventListener('click', () => {
            searchInput.value = '';
            this.searchQuery = '';
            suggestions.style.display = 'none';
            this.clearSmartSearch();
        });
        
        // Hide suggestions when clicking outside
        document.addEventListener('click', (e) => {
            if (!e.target.closest('.smart-search-container')) {
                suggestions.style.display = 'none';
            }
        });
    }
    
    async showSuggestions(query, cursorPosition) {
        const suggestions = document.getElementById('smart-search-suggestions');
        const suggestionItems = await this.smartSearch.getSuggestions(query, cursorPosition);
        
        if (suggestionItems.length === 0) {
            suggestions.style.display = 'none';
            return;
        }
        
        suggestions.innerHTML = '';
        suggestionItems.forEach((item, index) => {
            const div = document.createElement('div');
            div.className = 'suggestion-item';
            div.innerHTML = `
                <span class="suggestion-type">${item.type}</span>
                <span class="suggestion-value">${item.display}</span>
                <span class="suggestion-description">${item.description}</span>
            `;
            
            div.addEventListener('click', () => {
                this.applySuggestion(div, item);
            });
            
            suggestions.appendChild(div);
        });
        
        suggestions.style.display = 'block';
        this.smartSearch.currentSuggestionIndex = -1;
    }
    
    updateSuggestionSelection() {
        const suggestionItems = document.querySelectorAll('.suggestion-item');
        suggestionItems.forEach((item, index) => {
            item.classList.toggle('active', index === this.smartSearch.currentSuggestionIndex);
        });
    }
    
    applySuggestion(suggestionElement, suggestionData = null) {
        const searchInput = document.getElementById('smart-search-input');
        const suggestions = document.getElementById('smart-search-suggestions');
        
        if (!suggestionData) {
            const type = suggestionElement.querySelector('.suggestion-type').textContent;
            const value = suggestionElement.querySelector('.suggestion-value').textContent;
            suggestionData = { type, value, display: value };
        }
        
        // Get current query and replace last token
        const currentQuery = searchInput.value;
        const cursorPos = searchInput.selectionStart;
        const beforeCursor = currentQuery.substring(0, cursorPos);
        const afterCursor = currentQuery.substring(cursorPos);
        
        const tokens = beforeCursor.split(/\s+/);
        tokens[tokens.length - 1] = suggestionData.value;
        
        const newQuery = tokens.join(' ') + ' ' + afterCursor;
        searchInput.value = newQuery.trim();
        this.searchQuery = newQuery.trim();
        
        // Position cursor after the completed token
        const newCursorPos = tokens.join(' ').length;
        searchInput.setSelectionRange(newCursorPos, newCursorPos);
        
        suggestions.style.display = 'none';
        searchInput.focus();
        
        // Apply the search immediately if it's a complete filter
        if (suggestionData.type !== 'token') {
            this.applySmartSearch();
        }
    }
    
    applySmartSearch() {
        if (!this.searchQuery.trim()) {
            this.clearSmartSearch();
            return;
        }
        
        const parsedFilters = this.smartSearch.parseQuery(this.searchQuery);
        
        // Convert smart search filters to existing filter format
        if (parsedFilters.assignee) {
            // Find user by username
            const user = this.getTeamMemberByUsername(parsedFilters.assignee);
            this.filters.assignee = user ? user.id : '';
        }
        
        if (parsedFilters.project) {
            // Find project by code
            const project = this.getProjectByCode(parsedFilters.project);
            this.filters.project = project ? project.id : '';
        }
        
        if (parsedFilters.sprint) {
            // Find sprint by name
            const sprint = this.getSprintByName(parsedFilters.sprint);
            this.filters.sprint = sprint ? sprint.id : parsedFilters.sprint;
        }
        
        if (parsedFilters.status) {
            this.filters.status = parsedFilters.status;
        }
        
        if (parsedFilters.priority) {
            this.filters.priority = parsedFilters.priority;
        }
        
        // Handle date filters
        if (parsedFilters.dueDate) {
            this.filters.dateField = 'due';
            if (parsedFilters.dueDate.start) {
                this.filters.startDate = parsedFilters.dueDate.start.toISOString().split('T')[0];
            }
            if (parsedFilters.dueDate.end) {
                this.filters.endDate = parsedFilters.dueDate.end.toISOString().split('T')[0];
            }
        }
        
        if (parsedFilters.createdDate) {
            this.filters.dateField = 'created';
            if (parsedFilters.createdDate.start) {
                this.filters.startDate = parsedFilters.createdDate.start.toISOString().split('T')[0];
            }
            if (parsedFilters.createdDate.end) {
                this.filters.endDate = parsedFilters.createdDate.end.toISOString().split('T')[0];
            }
        }
        
        // Handle view switching
        if (parsedFilters.view) {
            switch (parsedFilters.view) {
                case 'my-tasks':
                    this.currentView = 'personal';
                    break;
                case 'all-tasks':
                    this.currentView = 'all';
                    break;
                case 'team-tasks':
                    this.currentView = 'team';
                    break;
                case 'project-tasks':
                    this.currentView = 'project';
                    break;
            }
        }
        
        // Handle special keywords
        if (parsedFilters.keywords.includes('overdue')) {
            this.filters.dateField = 'due';
            this.filters.endDate = new Date().toISOString().split('T')[0];
        }
        
        if (parsedFilters.keywords.includes('unassigned')) {
            this.filters.assignee = 'unassigned';
        }
        
        if (parsedFilters.keywords.includes('urgent')) {
            this.filters.priority = 'URGENT';
        }
        
        this.isSearching = true;
        this.applyFilters();
    }
    
    clearSmartSearch() {
        // Reset all filters and view
        this.filters = {
            project: '',
            assignee: '',
            priority: '',
            status: '',
            startDate: '',
            endDate: '',
            dateField: 'created',
            sprint: ''
        };
        this.currentView = 'all'; // Reset to default view
        this.isSearching = false;
        this.applyFilters();
    }
    
    // Helper methods for finding data by name/code
    getTeamMemberByUsername(username) {
        // This would need to be populated from the available team members
        // For now, return null and let the backend handle it
        return null;
    }
    
    getProjectByCode(code) {
        // This would need to be populated from available projects
        return null;
    }
    
    getSprintByName(name) {
        // This would need to be populated from available sprints
        return null;
    }

    async loadSprintsForModal() {
        try {
            const response = await fetch('/api/sprints');
            const data = await response.json();
            
            if (data.success) {
                // Update task modal sprint dropdown
                const taskSprintSelect = document.getElementById('task-sprint');
                // Clear existing options except the default "No Sprint" option
                taskSprintSelect.innerHTML = '<option value="">No Sprint</option>';
                
                // Add sprint options to modal dropdown
                data.sprints.forEach(sprint => {
                    const modalOption = document.createElement('option');
                    modalOption.value = sprint.id;
                    modalOption.textContent = `${sprint.name} (${sprint.status})`;
                    taskSprintSelect.appendChild(modalOption);
                });
            }
        } catch (error) {
            console.error('Error loading sprints:', error);
        }
    }

    async loadTasks() {
        document.getElementById('loading-indicator').style.display = 'flex';
        document.getElementById('error-message').style.display = 'none';

        try {
            const response = await fetch('/api/tasks/unified');
            const data = await response.json();
            
            if (data.success) {
                this.tasks = data.tasks;
                this.renderTasks();
                this.updateStatistics();
            } else {
                throw new Error(data.message || 'Failed to load tasks');
            }
        } catch (error) {
            console.error('Error loading tasks:', error);
            document.getElementById('error-message').style.display = 'block';
        } finally {
            document.getElementById('loading-indicator').style.display = 'none';
        }
    }

    renderTasks() {
        // Clear all columns
        document.querySelectorAll('.column-content').forEach(column => {
            column.innerHTML = '';
        });

        // Filter tasks based on current view and filters
        const filteredTasks = this.getFilteredTasks();
        
        // Group tasks by status
        const tasksByStatus = {
            'TODO': [],
            'IN_PROGRESS': [],
            'IN_REVIEW': [],
            'DONE': [],
            'CANCELLED': [],
            'ARCHIVED': []
        };

        filteredTasks.forEach(task => {
            if (tasksByStatus[task.status]) {
                tasksByStatus[task.status].push(task);
            }
        });

        // Render tasks in each column
        Object.keys(tasksByStatus).forEach(status => {
            const column = document.getElementById(`column-${status}`);
            const tasks = tasksByStatus[status];
            
            tasks.forEach(task => {
                const taskCard = this.createTaskCard(task);
                column.appendChild(taskCard);
            });
            
            // Update task count
            const countElement = column.parentElement.querySelector('.task-count');
            countElement.textContent = tasks.length;
        });
    }

    getFilteredTasks() {
        return this.tasks.filter(task => {
            // View filter
            if (this.currentView === 'personal' && task.assigned_to_id !== this.currentUserId) {
                return false;
            }
            if (this.currentView === 'team' && !task.is_team_task) {
                return false;
            }
            if (this.currentView === 'project' && !task.project_id) {
                return false;
            }

            // Project filter
            if (this.filters.project && task.project_id != this.filters.project) {
                return false;
            }

            // Assignee filter
            if (this.filters.assignee) {
                if (this.filters.assignee === 'unassigned' && task.assigned_to_id) {
                    return false;
                }
                if (this.filters.assignee !== 'unassigned' && task.assigned_to_id != this.filters.assignee) {
                    return false;
                }
            }

            // Priority filter
            if (this.filters.priority && task.priority !== this.filters.priority) {
                return false;
            }

            // Status filter
            if (this.filters.status && task.status !== this.filters.status) {
                return false;
            }

            // Date range filter
            if (this.filters.startDate || this.filters.endDate) {
                let taskDate = null;
                
                switch (this.filters.dateField) {
                    case 'created':
                        taskDate = task.created_at ? new Date(task.created_at) : null;
                        break;
                    case 'due':
                        taskDate = task.due_date ? new Date(task.due_date) : null;
                        break;
                    case 'completed':
                        taskDate = task.completed_date ? new Date(task.completed_date) : null;
                        break;
                }
                
                if (taskDate) {
                    if (this.filters.startDate && taskDate < new Date(this.filters.startDate)) {
                        return false;
                    }
                    if (this.filters.endDate && taskDate > new Date(this.filters.endDate)) {
                        return false;
                    }
                } else if (this.filters.startDate || this.filters.endDate) {
                    // If we're filtering by date but task has no date in the selected field, exclude it
                    return false;
                }
            }

            // Sprint filter
            if (this.filters.sprint) {
                if (this.filters.sprint === 'no-sprint' && task.sprint_id) {
                    return false;
                }
                if (this.filters.sprint === 'current' && !task.is_current_sprint) {
                    return false;
                }
                if (this.filters.sprint !== 'no-sprint' && this.filters.sprint !== 'current' && 
                    task.sprint_id != this.filters.sprint) {
                    return false;
                }
            }

            return true;
        });
    }

    createTaskCard(task) {
        const card = document.createElement('div');
        card.className = 'management-card task-card';
        card.dataset.taskId = task.id;
        card.addEventListener('click', () => this.openTaskModal(task));

        const dueDate = task.due_date ? new Date(task.due_date) : null;
        const isOverdue = dueDate && dueDate < new Date() && task.status !== 'COMPLETED' && task.status !== 'ARCHIVED';
        
        // Add archive/restore buttons for completed and archived tasks
        let actionButtons = '';
        if (task.status === 'COMPLETED') {
            actionButtons = `
                <div class="task-actions">
                    <button class="archive-btn" onclick="taskManager.archiveTask(${task.id}); event.stopPropagation();" title="Archive Task"><i class="ti ti-archive"></i></button>
                </div>
            `;
        } else if (task.status === 'ARCHIVED') {
            actionButtons = `
                <div class="task-actions">
                    <button class="restore-btn" onclick="taskManager.restoreTask(${task.id}); event.stopPropagation();" title="Restore Task"><i class="ti ti-arrow-back-up"></i></button>
                </div>
            `;
        }
        
        card.innerHTML = `
            <div class="task-card-header">
                <div class="task-title-section">
                    <span class="task-number">${task.task_number || 'TSK-???'}</span>
                    <h4 class="task-title">${task.name}</h4>
                </div>
                <span class="priority-badge ${task.priority}">${task.priority}</span>
            </div>
            ${task.project_name ? `<div class="task-project">${task.project_code} - ${task.project_name}</div>` : ''}
            <div class="task-meta">
                <span class="task-assignee">
                    ${task.assigned_to_id ? `<img src="${this.getUserAvatar(task.assigned_to_id)}" alt="${task.assigned_to_name}" class="task-assignee-avatar">` : ''}
                    ${task.assigned_to_name || 'Unassigned'}
                </span>
                ${dueDate ? `<span class="task-due-date ${isOverdue ? 'overdue' : ''}">${formatUserDate(task.due_date)}</span>` : ''}
            </div>
            ${task.subtasks && task.subtasks.length > 0 ? this.renderSubtaskProgress(task.subtasks) : ''}
            ${task.status === 'COMPLETED' ? `<div class="task-completed-date">Completed: ${formatUserDate(task.completed_date)}</div>` : ''}
            ${task.status === 'ARCHIVED' ? `<div class="task-archived-date">Archived: ${formatUserDate(task.archived_date)}</div>` : ''}
            ${actionButtons}
        `;

        return card;
    }

    renderSubtaskProgress(subtasks) {
        if (!subtasks || subtasks.length === 0) return '';
        
        const completedCount = subtasks.filter(s => s.status === 'COMPLETED').length;
        const totalCount = subtasks.length;
        const percentage = Math.round((completedCount / totalCount) * 100);
        
        return `
            <div class="task-subtasks">
                <div class="subtask-progress">
                    <div class="subtask-progress-bar">
                        <div class="subtask-progress-fill" style="width: ${percentage}%"></div>
                    </div>
                    <span class="subtask-count">${completedCount}/${totalCount} subtasks</span>
                </div>
            </div>
        `;
    }

    applyFilters() {
        this.renderTasks();
    }

    updateStatistics() {
        const total = this.tasks.length;
        const completed = this.tasks.filter(t => t.status === 'COMPLETED').length;
        const inProgress = this.tasks.filter(t => t.status === 'IN_PROGRESS').length;
        const archived = this.tasks.filter(t => t.status === 'ARCHIVED').length;
        const overdue = this.tasks.filter(t => {
            const dueDate = t.due_date ? new Date(t.due_date) : null;
            return dueDate && dueDate < new Date() && t.status !== 'COMPLETED' && t.status !== 'ARCHIVED';
        }).length;

        document.getElementById('total-tasks').textContent = total;
        document.getElementById('completed-tasks').textContent = completed;
        document.getElementById('in-progress-tasks').textContent = inProgress;
        document.getElementById('overdue-tasks').textContent = overdue;
        document.getElementById('archived-tasks').textContent = archived;
    }

    toggleArchivedView() {
        this.showArchived = !this.showArchived;
        const toggleBtn = document.getElementById('toggle-archived');
        const archivedColumn = document.querySelector('.archived-column');
        const archivedStatCard = document.getElementById('archived-stat-card');
        
        if (this.showArchived) {
            toggleBtn.innerHTML = '<i class="ti ti-archive"></i> Hide Archived';
            toggleBtn.classList.add('active');
            archivedColumn.style.display = 'block';
            archivedStatCard.style.display = 'block';
        } else {
            toggleBtn.innerHTML = '<i class="ti ti-archive"></i> Show Archived';
            toggleBtn.classList.remove('active');
            archivedColumn.style.display = 'none';
            archivedStatCard.style.display = 'none';
        }
        
        this.renderTasks();
    }

    async archiveTask(taskId) {
        if (confirm('Are you sure you want to archive this task? It will be moved to the archived section.')) {
            try {
                const response = await fetch(`/api/tasks/${taskId}/archive`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    }
                });
                
                const data = await response.json();
                if (data.success) {
                    await this.loadTasks();
                } else {
                    alert('Failed to archive task: ' + data.message);
                }
            } catch (error) {
                console.error('Error archiving task:', error);
                alert('Failed to archive task: ' + error.message);
            }
        }
    }

    async restoreTask(taskId) {
        if (confirm('Are you sure you want to restore this task? It will be moved back to completed status.')) {
            try {
                const response = await fetch(`/api/tasks/${taskId}/restore`, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    }
                });
                
                const data = await response.json();
                if (data.success) {
                    await this.loadTasks();
                } else {
                    alert('Failed to restore task: ' + data.message);
                }
            } catch (error) {
                console.error('Error restoring task:', error);
                alert('Failed to restore task: ' + error.message);
            }
        }
    }

    async refreshTaskCard(taskId) {
        // Fetch updated task data
        try {
            const response = await fetch(`/api/tasks/${taskId}`);
            const task = await response.json();
            
            if (task) {
                // Find and replace the task card
                const oldCard = document.querySelector(`[data-task-id="${taskId}"]`);
                if (oldCard) {
                    const newCard = this.createTaskCard(task);
                    oldCard.replaceWith(newCard);
                }
                
                // Update task in local array
                const index = this.tasks.findIndex(t => t.id == taskId);
                if (index !== -1) {
                    this.tasks[index] = task;
                }
            }
        } catch (error) {
            console.error('Error refreshing task card:', error);
        }
    }

    async handleTaskMove(evt) {
        const taskId = evt.item.dataset.taskId;
        const newStatus = evt.to.id.replace('column-', '');
        
        try {
            const response = await fetch(`/api/tasks/${taskId}/status`, {
                method: 'PUT',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({ status: newStatus })
            });
            
            const data = await response.json();
            if (data.success) {
                // Update local task data
                const task = this.tasks.find(t => t.id == taskId);
                if (task) {
                    task.status = newStatus;
                    this.updateStatistics();
                }
            } else {
                throw new Error(data.message || 'Failed to update task');
            }
        } catch (error) {
            console.error('Error updating task status:', error);
            // Revert the move
            this.renderTasks();
        }
    }

    async openTaskModal(task = null) {
        this.currentTask = task;
        const modal = document.getElementById('task-modal');
        
        // Load sprints for the modal dropdown
        await this.loadSprintsForModal();
        
        if (task) {
            document.getElementById('modal-title').textContent = 'Edit Task';
            document.getElementById('task-id').value = task.id;
            document.getElementById('task-name').value = task.name;
            document.getElementById('task-description').value = task.description || '';
            document.getElementById('task-priority').value = task.priority;
            document.getElementById('task-project').value = task.project_id || '';
            document.getElementById('task-assignee').value = task.assigned_to_id || '';
            document.getElementById('task-due-date').value = formatDateForInput(task.due_date) || '';
            document.getElementById('task-estimated-hours').value = task.estimated_hours || '';
            document.getElementById('task-status').value = task.status;
            document.getElementById('task-sprint').value = task.sprint_id || '';
            document.getElementById('delete-task-btn').style.display = 'inline-block';
            
            // Load dependencies
            await this.loadDependencies(task.id);
            
            // Initialize subtasks
            initializeSubtasks(task.id);
            
            // Show comments section and load comments
            document.getElementById('comments-section').style.display = 'block';
            await this.loadComments(task.id);
        } else {
            document.getElementById('modal-title').textContent = 'Add New Task';
            document.getElementById('task-form').reset();
            document.getElementById('task-id').value = '';
            document.getElementById('delete-task-btn').style.display = 'none';
            
            // Clear dependencies
            this.clearDependencies();
            
            // Initialize empty subtasks
            initializeSubtasks(null);
            
            // Hide comments section for new tasks
            document.getElementById('comments-section').style.display = 'none';
        }
        
        modal.style.display = 'block';
    }

    async saveTask() {
        // Validate date input before saving
        const dueDateInput = document.getElementById('task-due-date');
        const dueDateError = document.getElementById('task-due-date-error');
        
        if (!validateDateInput(dueDateInput, dueDateError)) {
            dueDateInput.focus();
            return;
        }
        
        const taskData = {
            name: document.getElementById('task-name').value,
            description: document.getElementById('task-description').value,
            priority: document.getElementById('task-priority').value,
            project_id: document.getElementById('task-project').value || null,
            assigned_to_id: document.getElementById('task-assignee').value || null,
            due_date: parseUserDate(document.getElementById('task-due-date').value) || null,
            estimated_hours: document.getElementById('task-estimated-hours').value || null,
            status: document.getElementById('task-status').value,
            sprint_id: document.getElementById('task-sprint').value || null
        };

        const taskId = document.getElementById('task-id').value;
        const isEdit = taskId !== '';

        try {
            const response = await fetch(`/api/tasks${isEdit ? `/${taskId}` : ''}`, {
                method: isEdit ? 'PUT' : 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(taskData)
            });
            
            const data = await response.json();
            if (data.success) {
                // Save subtasks if we have a task ID
                const savedTaskId = isEdit ? taskId : data.task.id;
                if (savedTaskId) {
                    await saveSubtasks(savedTaskId);
                }
                
                closeTaskModal();
                await this.loadTasks();
            } else {
                throw new Error(data.message || 'Failed to save task');
            }
        } catch (error) {
            console.error('Error saving task:', error);
            alert('Failed to save task: ' + error.message);
        }
    }

    async deleteTask() {
        if (!this.currentTask) return;
        
        if (confirm('Are you sure you want to delete this task?')) {
            try {
                const response = await fetch(`/api/tasks/${this.currentTask.id}`, {
                    method: 'DELETE'
                });
                
                const data = await response.json();
                if (data.success) {
                    closeTaskModal();
                    await this.loadTasks();
                } else {
                    throw new Error(data.message || 'Failed to delete task');
                }
            } catch (error) {
                console.error('Error deleting task:', error);
                alert('Failed to delete task: ' + error.message);
            }
        }
    }
    
    // Dependency management methods
    async loadDependencies(taskId) {
        try {
            const response = await fetch(`/api/tasks/${taskId}/dependencies`);
            const data = await response.json();
            
            if (data.success) {
                this.renderDependencies(data.dependencies);
            } else {
                console.error('Failed to load dependencies:', data.message);
            }
        } catch (error) {
            console.error('Error loading dependencies:', error);
        }
    }
    
    renderDependencies(dependencies) {
        const blockedByContainer = document.getElementById('blocked-by-container');
        const blocksContainer = document.getElementById('blocks-container');
        
        // Clear existing dependencies
        blockedByContainer.innerHTML = '';
        blocksContainer.innerHTML = '';
        
        // Render blocked by dependencies
        dependencies.blocked_by.forEach(dep => {
            const depElement = this.createDependencyElement(dep, 'blocked_by');
            blockedByContainer.appendChild(depElement);
        });
        
        // Render blocks dependencies
        dependencies.blocks.forEach(dep => {
            const depElement = this.createDependencyElement(dep, 'blocks');
            blocksContainer.appendChild(depElement);
        });
    }
    
    createDependencyElement(dependency, type) {
        const element = document.createElement('div');
        element.className = 'dependency-item';
        
        element.innerHTML = `
            <div class="dependency-task-info">
                <span class="dependency-task-number">${dependency.task_number}</span>
                <span class="dependency-task-title">${dependency.name}</span>
            </div>
            <button class="dependency-remove-btn" onclick="taskManager.removeDependency(${dependency.id}, '${type}')">Remove</button>
        `;
        
        return element;
    }
    
    clearDependencies() {
        document.getElementById('blocked-by-container').innerHTML = '';
        document.getElementById('blocks-container').innerHTML = '';
        document.getElementById('blocked-by-input').value = '';
        document.getElementById('blocks-input').value = '';
    }
    
    async addDependency(taskNumber, type) {
        const taskId = document.getElementById('task-id').value;
        if (!taskId) {
            alert('Please save the task first before adding dependencies.');
            return;
        }
        
        if (!taskNumber || taskNumber.trim() === '') {
            alert('Please enter a task number.');
            return;
        }
        
        try {
            const response = await fetch(`/api/tasks/${taskId}/dependencies`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    task_number: taskNumber.trim(),
                    type: type
                })
            });
            
            const data = await response.json();
            if (data.success) {
                // Reload dependencies
                await this.loadDependencies(taskId);
                // Clear input
                document.getElementById(`${type.replace('_', '-')}-input`).value = '';
            } else {
                alert('Failed to add dependency: ' + data.message);
            }
        } catch (error) {
            console.error('Error adding dependency:', error);
            alert('Failed to add dependency: ' + error.message);
        }
    }
    
    async removeDependency(dependencyTaskId, type) {
        const taskId = document.getElementById('task-id').value;
        if (!taskId) return;
        
        if (confirm('Are you sure you want to remove this dependency?')) {
            try {
                const response = await fetch(`/api/tasks/${taskId}/dependencies/${dependencyTaskId}`, {
                    method: 'DELETE',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        type: type
                    })
                });
                
                const data = await response.json();
                if (data.success) {
                    // Reload dependencies
                    await this.loadDependencies(taskId);
                } else {
                    alert('Failed to remove dependency: ' + data.message);
                }
            } catch (error) {
                console.error('Error removing dependency:', error);
                alert('Failed to remove dependency: ' + error.message);
            }
        }
    }
    
    // Comment management methods
    async loadComments(taskId) {
        try {
            const response = await fetch(`/api/tasks/${taskId}/comments`);
            const data = await response.json();
            
            if (data.success) {
                this.renderComments(data.comments);
                
                // Show/hide team visibility option based on company settings
                const visibilitySelect = document.getElementById('comment-visibility');
                if (data.allow_team_visibility) {
                    visibilitySelect.style.display = 'inline-block';
                } else {
                    visibilitySelect.style.display = 'none';
                }
            } else {
                console.error('Failed to load comments:', data.message);
            }
        } catch (error) {
            console.error('Error loading comments:', error);
        }
    }
    
    renderComments(comments) {
        const container = document.getElementById('comments-container');
        container.innerHTML = '';
        
        if (comments.length === 0) {
            container.innerHTML = '<p class="no-comments">No comments yet. Be the first to comment!</p>';
            return;
        }
        
        comments.forEach(comment => {
            const commentElement = this.createCommentElement(comment);
            container.appendChild(commentElement);
        });
    }
    
    createCommentElement(comment) {
        const element = document.createElement('div');
        element.className = 'comment-item';
        element.dataset.commentId = comment.id;
        
        const visibilityBadge = comment.visibility === 'Team' ? 
            '<span class="comment-visibility-badge team"><i class="ti ti-users"></i> Team</span>' : '';
        
        const editedText = comment.is_edited ? 
            ` <span class="comment-edited">(edited)</span>` : '';
        
        element.innerHTML = `
            <div class="comment-header">
                <div class="comment-author-info">
                    <img src="${comment.author.avatar_url}" alt="${comment.author.username}" class="comment-author-avatar">
                    <div class="comment-author-details">
                        <span class="comment-author">${comment.author.username}</span>
                        <span class="comment-time">${this.formatRelativeTime(comment.created_at)}${editedText}</span>
                    </div>
                </div>
                ${visibilityBadge}
            </div>
            <div class="comment-content">${this.escapeHtml(comment.content)}</div>
            <div class="comment-actions">
                ${comment.can_edit ? '<button class="comment-action" onclick="taskManager.editComment(' + comment.id + ')">Edit</button>' : ''}
                ${comment.can_delete ? '<button class="comment-action" onclick="taskManager.deleteComment(' + comment.id + ')">Delete</button>' : ''}
                <button class="comment-action" onclick="taskManager.replyToComment(${comment.id})">Reply</button>
            </div>
            <div class="comment-edit-form" id="comment-edit-${comment.id}" style="display: none;">
                <textarea class="comment-edit-textarea">${this.escapeHtml(comment.content)}</textarea>
                <div class="comment-edit-actions">
                    <button class="btn btn-sm btn-primary" onclick="taskManager.saveCommentEdit(${comment.id})">Save</button>
                    <button class="btn btn-sm btn-secondary" onclick="taskManager.cancelCommentEdit(${comment.id})">Cancel</button>
                </div>
            </div>
            <div class="comment-reply-form" id="comment-reply-${comment.id}" style="display: none;">
                <textarea placeholder="Write a reply..." rows="2"></textarea>
                <div class="comment-edit-actions">
                    <button class="btn btn-sm btn-primary" onclick="taskManager.saveReply(${comment.id})">Reply</button>
                    <button class="btn btn-sm btn-secondary" onclick="taskManager.cancelReply(${comment.id})">Cancel</button>
                </div>
            </div>
        `;
        
        // Add replies if any
        if (comment.replies && comment.replies.length > 0) {
            const repliesContainer = document.createElement('div');
            repliesContainer.className = 'comment-replies';
            
            comment.replies.forEach(reply => {
                const replyElement = this.createReplyElement(reply);
                repliesContainer.appendChild(replyElement);
            });
            
            element.appendChild(repliesContainer);
        }
        
        return element;
    }
    
    createReplyElement(reply) {
        const element = document.createElement('div');
        element.className = 'comment-reply';
        element.dataset.commentId = reply.id;
        
        const editedText = reply.is_edited ? 
            ` <span class="comment-edited">(edited)</span>` : '';
        
        element.innerHTML = `
            <div class="comment-header">
                <div class="comment-author-info">
                    <img src="${reply.author.avatar_url}" alt="${reply.author.username}" class="comment-author-avatar">
                    <div class="comment-author-details">
                        <span class="comment-author">${reply.author.username}</span>
                        <span class="comment-time">${this.formatRelativeTime(reply.created_at)}${editedText}</span>
                    </div>
                </div>
            </div>
            <div class="comment-content">${this.escapeHtml(reply.content)}</div>
            <div class="comment-actions">
                ${reply.can_edit ? '<button class="comment-action" onclick="taskManager.editComment(' + reply.id + ')">Edit</button>' : ''}
                ${reply.can_delete ? '<button class="comment-action" onclick="taskManager.deleteComment(' + reply.id + ')">Delete</button>' : ''}
            </div>
        `;
        
        return element;
    }
    
    async addComment() {
        const taskId = document.getElementById('task-id').value;
        const contentTextarea = document.getElementById('new-comment');
        const content = contentTextarea.value.trim();
        const visibility = document.getElementById('comment-visibility').value;
        
        if (!taskId || !content) {
            alert('Please enter a comment');
            return;
        }
        
        try {
            const response = await fetch(`/api/tasks/${taskId}/comments`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    content: content,
                    visibility: visibility
                })
            });
            
            const data = await response.json();
            if (data.success) {
                contentTextarea.value = '';
                await this.loadComments(taskId);
            } else {
                alert('Failed to post comment: ' + data.message);
            }
        } catch (error) {
            console.error('Error posting comment:', error);
            alert('Failed to post comment: ' + error.message);
        }
    }
    
    editComment(commentId) {
        const commentElement = document.querySelector(`[data-comment-id="${commentId}"]`);
        const editForm = document.getElementById(`comment-edit-${commentId}`);
        const content = commentElement.querySelector('.comment-content');
        
        content.style.display = 'none';
        editForm.style.display = 'block';
    }
    
    cancelCommentEdit(commentId) {
        const editForm = document.getElementById(`comment-edit-${commentId}`);
        const content = document.querySelector(`[data-comment-id="${commentId}"] .comment-content`);
        
        content.style.display = 'block';
        editForm.style.display = 'none';
    }
    
    async saveCommentEdit(commentId) {
        const editForm = document.getElementById(`comment-edit-${commentId}`);
        const textarea = editForm.querySelector('textarea');
        const content = textarea.value.trim();
        
        if (!content) {
            alert('Comment cannot be empty');
            return;
        }
        
        try {
            const response = await fetch(`/api/comments/${commentId}`, {
                method: 'PUT',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    content: content
                })
            });
            
            const data = await response.json();
            if (data.success) {
                const taskId = document.getElementById('task-id').value;
                await this.loadComments(taskId);
            } else {
                alert('Failed to update comment: ' + data.message);
            }
        } catch (error) {
            console.error('Error updating comment:', error);
            alert('Failed to update comment: ' + error.message);
        }
    }
    
    async deleteComment(commentId) {
        if (!confirm('Are you sure you want to delete this comment?')) {
            return;
        }
        
        try {
            const response = await fetch(`/api/comments/${commentId}`, {
                method: 'DELETE',
                headers: {
                    'Content-Type': 'application/json'
                }
            });
            
            // Check if response is JSON
            const contentType = response.headers.get('content-type');
            if (!contentType || !contentType.includes('application/json')) {
                console.error('Response is not JSON:', await response.text());
                if (response.status === 401) {
                    alert('Your session has expired. Please refresh the page and login again.');
                    window.location.href = '/login';
                    return;
                } else if (response.status === 404) {
                    alert('Comment not found. It may have been already deleted.');
                } else {
                    alert('Failed to delete comment. Please try again.');
                }
                return;
            }
            
            const data = await response.json();
            if (data.success) {
                const taskId = document.getElementById('task-id').value;
                await this.loadComments(taskId);
            } else {
                alert('Failed to delete comment: ' + data.message);
            }
        } catch (error) {
            console.error('Error deleting comment:', error);
            alert('Failed to delete comment: ' + error.message);
        }
    }
    
    replyToComment(commentId) {
        const replyForm = document.getElementById(`comment-reply-${commentId}`);
        replyForm.style.display = 'block';
        replyForm.querySelector('textarea').focus();
    }
    
    cancelReply(commentId) {
        const replyForm = document.getElementById(`comment-reply-${commentId}`);
        replyForm.style.display = 'none';
        replyForm.querySelector('textarea').value = '';
    }
    
    async saveReply(parentCommentId) {
        const taskId = document.getElementById('task-id').value;
        const replyForm = document.getElementById(`comment-reply-${parentCommentId}`);
        const content = replyForm.querySelector('textarea').value.trim();
        
        if (!content) {
            alert('Please enter a reply');
            return;
        }
        
        try {
            const response = await fetch(`/api/tasks/${taskId}/comments`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    content: content,
                    parent_comment_id: parentCommentId,
                    visibility: 'COMPANY' // Replies inherit parent visibility
                })
            });
            
            const data = await response.json();
            if (data.success) {
                replyForm.style.display = 'none';
                replyForm.querySelector('textarea').value = '';
                await this.loadComments(taskId);
            } else {
                alert('Failed to post reply: ' + data.message);
            }
        } catch (error) {
            console.error('Error posting reply:', error);
            alert('Failed to post reply: ' + error.message);
        }
    }
    
    formatRelativeTime(dateString) {
        const date = new Date(dateString);
        const now = new Date();
        const diffMs = now - date;
        const diffSecs = Math.floor(diffMs / 1000);
        const diffMins = Math.floor(diffSecs / 60);
        const diffHours = Math.floor(diffMins / 60);
        const diffDays = Math.floor(diffHours / 24);
        
        if (diffSecs < 60) {
            return 'just now';
        } else if (diffMins < 60) {
            return `${diffMins} minute${diffMins > 1 ? 's' : ''} ago`;
        } else if (diffHours < 24) {
            return `${diffHours} hour${diffHours > 1 ? 's' : ''} ago`;
        } else if (diffDays < 7) {
            return `${diffDays} day${diffDays > 1 ? 's' : ''} ago`;
        } else {
            return date.toLocaleDateString();
        }
    }
    
    escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }
}

// Global functions
let taskManager;

document.addEventListener('DOMContentLoaded', function() {
    taskManager = new UnifiedTaskManager();
    taskManager.init();
});

function closeTaskModal() {
    document.getElementById('task-modal').style.display = 'none';
    taskManager.currentTask = null;
}

function saveTask() {
    taskManager.saveTask();
}

function deleteTask() {
    taskManager.deleteTask();
}

function addComment() {
    taskManager.addComment();
}

function addSubtask() {
    // TODO: Implement subtask functionality
}

function addBlockedBy() {
    const input = document.getElementById('blocked-by-input');
    const taskNumber = input.value.trim();
    if (taskNumber) {
        taskManager.addDependency(taskNumber, 'blocked_by');
    }
}

function addBlocks() {
    const input = document.getElementById('blocks-input');
    const taskNumber = input.value.trim();
    if (taskNumber) {
        taskManager.addDependency(taskNumber, 'blocks');
    }
}

// Close modal when clicking outside
window.onclick = function(event) {
    const modal = document.getElementById('task-modal');
    if (event.target === modal) {
        closeTaskModal();
    }
};

// Make team members available globally for subtasks
window.teamMembers = {{ team_members | tojson }};

// Make refreshTaskCard available globally
window.refreshTaskCard = function(taskId) {
    if (window.taskManager) {
        window.taskManager.refreshTaskCard(taskId);
    }
};
</script>

<!-- Include subtasks functionality -->
<script src="{{ url_for('static', filename='js/subtasks.js') }}"></script>
{% endblock %}