As an expert developer and tutor could you rate these files' code and then provide these files after improvement?
<!-- index.html -->

<!DOCTYPE html>
<html lang="en">
<head>
    <!-- Meta Tags for Character Set and Responsive Design -->
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>To-Do List App</title>
    <meta name="description" content="A simple and effective to-do list application">
    <link rel="stylesheet" href="main.css">
</head>
<body>
    <div class="wrapper">
        <!-- Sidebar -->
         <div id="sidebar" class="sidebar" role="complementary" aria-label="Project Sidebar">
            <h2>Projects</h2>
            <ul id="project-list">
                <!-- Projects will be rendered here -->
            </ul>
            <div id="add-project">
                <label for="project-name" class="visually-hidden">New Project Name</label>
                <input type="text" id="project-name" placeholder="New Project Name" required aria-required="true">
                <button id="add-project-button" class="btn" aria-label="Add Project">Add Project</button>
            </div>
         </div>

         <!-- Main Content -->
         <main id="app" role="main">
            <h1>To-Do List</h1>

            <div id="todo-container">
                <h2>Todos</h2>
                <!-- Todos will be rendered here -->
            </div>

            <form id="add-todo-form">
                <div id="add-todo">
                    <label for="todo-title" class="visually-hidden">Title</label>
                    <input type="text" id="todo-title" name="todo-title" placeholder="Title" required aria-required="true">
                    <label for="todo-description" class="visually-hidden">Description</label>
                    <input type="text" id="todo-description" placeholder="Description">
                    <label for="todo-due-date" class="visually-hidden">Due Date</label>
                    <input type="date" id="todo-due-date" required aria-required="true">
                    <label for="todo-priority" class="visually-hidden">Priority</label>
                    <select id="todo-priority" aria-label="Priority">
                        <option value="low">Low</option>
                        <option value="medium">Medium</option>
                        <option value="high">High</option>
                    </select>
                    <button id="add-todo-button" class="btn" aria-label="Add Todo">Add Todo</button>
                </div>
            </form>

            <!-- Edit Task Modal -->
             <div id="edit-task-modal" class="modal" role="dialog" aria-labelledby="edit-task-title" aria-modal="true" style="display:none;">
                <div class="modal-content">
                    <span class="close-button" aria-label="Close Modal">&times;</span>
                    <h2 id="edit-task-title">Edit task</h2>

                    <label for="edit-title" class="visually-hidden">Title:</label>
                    <input type="text" id="edit-title" required aria-required="true">

                    <label for="edit-description" class="visually-hidden">Description:</label>
                    <input type="text" id="edit-description">

                    <label for="edit-due-date" class="visually-hidden">Due Date:</label>
                    <input type="date" id="edit-due-date">

                    <label for="edit-priority" class="visually-hidden">Priority:</label>
                    <select id="edit-priority" aria-label="Edit Priority">
                        <option value="low">Low</option>
                        <option value="medium">Medium</option>
                        <option value="high">High</option>
                    </select>

                    <button id="save-changes-button" class="btn" aria-label="Save Changes">Save changes</button>
                    <button id="cancel-button" class="btn" aria-label="Cancel Editing">Cancel</button>
                </div>
             </div>
        </main>
    </div>

    <!-- <script src=".dist/bundle.js"></script> -->
    <!-- <script src="./src/app.js" defer></script> -->
    <!-- <script type="module" src="./src/index.js" defer></script> -->
     <!-- Include the bundled JavaScript file -->
     <!-- <script src="bundle.js"></script> -->
</body>
</html>

/* style.css */

/* CSS Variables for consistent theming */
:root {
    --primary-color: #28a745;
    --secondary-color: #f1f1f1;
    --accent-color: #e0e0e0;
    --text-color: #333;
    --modal-background: rgba(0, 0, 0, 0.4);
    --button-hover-color: #218838;
    --button-bg-color: var(--primary-color);
    --button-text-color: #fff;
    --selected-project-font-weight: bold;
    --font-family: Arial, Helvetica, sans-serif;
}

/* Global Box Sizing and Reset */
*, *::before, *::after {
    box-sizing: border-box;
    margin: 0;
    padding: 0;
}

/* Base Styles */
body {
    font-family: var(--font-family);
    background-color: #f4f4f4;
    padding: 1.25rem; /* 20px */
    color: var(--text-color);
    /* background: linear-gradient(135deg, #153677, #4e085f); */
    /* color: white; */
}

.wrapper {
    display: flex; /* Use flexbox for layout */
}


/* Sidebar Styling */
.sidebar {
    width: 20vw;
    min-height: 100vh;
    background-color: var(--secondary-color);
    padding: 1.25rem;
    position: fixed;
    overflow-y: auto;
}

.sidebar h2 {
    margin-top: 0;
    color: var(--text-color);
}

.sidebar ul {
    list-style-type: none;
    padding: 0;
}

.sidebar ul li {
    margin: 0.625rem 0;
}

.sidebar ul li.project-item {
    padding: 0.5rem;
    border-radius: 0.25rem;
    cursor: pointer;
    transition: background-color 0.3s ease;
    outline: none;
}

.sidebar ul li.project-item:hover,
.sidebar ul li.project-item:focus,
.sidebar ul li.project-item.selected {
    background-color: var(--accent-color);
}

.sidebar ul li.project-item.selected {
    font-weight: var(--selected-project-font-weight);
}

/* Main Content Styling */
#app {
    max-width: 600px;
    margin-left: 22vw; /* Slightly more then sidebar width for spacing */
    /* background: linear-gradient(135deg, #153677, #4e085f); */
    padding: 1.25rem;
    border-radius: 0.625rem;
    background-color: #fff;
    min-height: 100vh;
}

h1, h2 {
    color: var(--text-color);
}

#project-list, #todo-container {
    background: #fff;
    padding: 0.625rem;
    border-radius: 0.3125rem;
    box-shadow: 0 0 0.625rem rgba(0, 0, 0, 0.1);
    margin-bottom: 1.25rem;
}

/* #project-list li {
    cursor: pointer;
} */

#project-list li.project-item {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

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

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

/* input, select {
    width: calc(100% - 20px);
    padding: 10px;
    margin-bottom: 10px;
} */

button {
    /* padding: 0.625rem; */
    padding: 0.5rem 0.75rem;
    background-color: var(--button-bg-color);
    color: var(--button-text-color);
    border: none;
    border-radius: 0.3125rem;
    cursor: pointer;
    transition: background-color 0.3s ease;
    margin-left: 0.3125rem;
}

button:hover, #project-list li:hover {
    background-color: var(--button-hover-color);
}

button:focus {
    outline: 2px solid #005fcc;
}

/* Priority Classes */
.priority-high {
    color: red;
}

.priority-medium {
    color: gold;
}

.priority-low {
    color: green;
}

/* #edit-task-modal {
    background-color: white;
    padding: 20px;
    border-radius: 5px;
} */

/* Modal Styling */
.modal {
    display: none; /* Hidden by default */
    position: fixed; /* Stay in place */
    z-index: 1000; /* Sit on top */
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    overflow: auto; /* Enable scroll if needed */
    /* background-color: rgb(0, 0, 0);  Fallback color */
    background-color: var(--modal-background) /* Black w/ opacity */
}

.modal-content {
    background-color: #fefefe;
    margin: 10% auto; /* 10% from the top and centered */
    padding: 1.25rem;
    border: 1px solid #888;
    width: 90%; /* Could be more or less, depending on screen size */
    max-width: 31.25rem; /* 500px */
    border-radius: 0.3125rem;

    /* @media (min-width: 600px) {
        width: 60%;
    }

    @media (min-width: 900px) {
        width: 40%;
    } */
}

.close-button {
    color: #aaa;
    float: right;
    font-size: 1.75rem;
    font-weight: bold;
    cursor: pointer;
    border: none;
    background: none;
}

.close-button:hover,
.close-button:focus {
    color: black;
    text-decoration: none;
    outline: none;
    /* cursor: pointer; */
}

/* .selected {
    font-weight: bold;
} */

/* Visually Hidden Class for Accessibility */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}


/* Animations */
.todo-item.fade-in {
    animation: fadeIn 0.5s forwards;
}

.todo-item.fade-out {
    animation: fadeOut 0.5s forwards;
}

@keyframes fadeIn {
    from { 
        opacity: 0; 
    }
    to {
        opacity: 1;
    }
}

@keyframes fadeOut {
    from {
        opacity: 1;
    }
    to {
        opacity: 0;
    }
}

/* Responsive Design */
@media (max-width: 760px) {
    .sidebar {
        width: 100%;
        height: auto;
        position: relative;
    }

    #app {
        margin-left: 0;
        max-width: 100%;
    }

    .modal-content {
        width: 95%;
    }
}

/* Scrollbar Styling for WebKit Browsers */
::-webkit-scrollbar {
    width: 8px;
}


// ui.js
import { getState, setCurrentProjectIndex, updateTodo } from "./app";
import { StorageManager } from "./localStorage";
import { Project } from "./project";
import { Todo } from "./todo";

// Event delegation for project and task iterations

/**
 * Render the list of projects in the sidebar.
 * @param {Array} projects - Array of Project instances.
 */
export function renderProjects(projects) {
    const projectContainer = document.querySelector('#project-list');
    projectContainer.innerHTML = ''; // Clear existing projects

    projects.forEach((project, index) => {
        const projectElement = document.createElement('li');
        projectElement.textContent = project.name;
        projectElement.classList.add('project-item');
        projectElement.setAttribute('data-index', index);
        projectElement.setAttribute('tabindex', '0'); // Make focusable

        projectContainer.appendChild(projectElement);

        // Create an option for each project in the dropdown
        // const option = document.createElement('option');
        // option.value = index; // Use index as value
        // option.textContent = project.name;
        // projectSelector.appendChild(option);
    });
}


/**
 * Highlight the selected project in the sidebar.
 * @param {number} index – Index of the selected project.
 */
function highlightSelectedProject(index) {
    const items = document.querySelectorAll('#project-list li')
    items.forEach((item, i) => {
        item.classList.toggle('selected', i === index);
    });
}


// Separate function to create a todo element
function createTodoElement(todo) {
    const todoElement = document.createElement('div');
    todoElement.classList.add('todo-item', `priority-${todo.priority}`);
    todoElement.dataset.id = todo.id

    // Todo title and Due Date
    const todoInfo = document.createElement('span');
    todoInfo.textContent = `${todo.title} – Due: ${todo.dueDate}`;
    todoInfo.classList.add('todo-info');
    todoElement.appendChild(todoInfo);

    // Edit button
    const editButton = createButton('Edit', 'edit-button');
    // Delete button
    const deleteButton = createButton('Delete', 'delete-button');
    
    todoElement.appendChild(editButton);
    todoElement.appendChild(deleteButton);

    // Apply priority-based styling
    todoElement.classList.add(`priority-${todo.priority}`);

    return todoElement;
}

function createButton(text, className) {
    const button = document.createElement('button');
    button.textContent = text;
    button.classList.add(className);
    return button;
}

/**
 * Render the todos for the selected project.
 * @param {Project} project – The Project instance whose todos are to be rendered.
 */
export function renderTodos(project) {
    const todoContainer = document.querySelector("#todo-container");
    todoContainer.innerHTML = ""; // Clear existing todos

    if (!project || !project.todos) {
        console.error("Invalid project or no todos available");
        return;
    }

    project.todos.forEach((todo) => {
        const todoElement = createTodoElement(todo);
        todoContainer.appendChild(todoElement);
    });
}

/**
 * Set up interactions for todo items (edit, delete).
 */
export function setupTodoInteraction() {
    const todoContainer = document.querySelector("#todo-container");

    // Handle edit and delete buttons using event delegation
    todoContainer.addEventListener('click', (event) => {
        const target = event.target;
        const todoElement = target.closest('.todo-item');
        if (!todoElement) return;

        const todoId = todoElement.getAttribute('data-id');
        const currentProjectIndex = getState().currentProjectIndex;
        const currentProject = getState().projects[currentProjectIndex];
        const todo = currentProject.getTodoById(todoId);

        console.log(`Clicked on todo ID: ${todoId}`, { todo });

        if (!todo) {
            console.error(`Todo with ID: ${todoId} not found`)
            return;
        }

        if (target.matches('.edit-button')) {
            showEditForm(todo, currentProject);
        }

        if (target.matches('.delete-button')) {
            handleDeleteTodo(todoId, currentProject);
        }
    });
}

/**
 * Handle deleting a todo.
 * @param {string} todoId – ID of the todo to delete.
 * @param {Project} project – The project containing the todo.
 */
function handleDeleteTodo(todoId, project) {
    if (confirm('Are you sure you want to delete this task?')) {
        project.removeTodo(todoId);
        StorageManager.saveProjects(getState().projects);
        renderTodos(project);
    }
}

const saveChangesHandler = () => {
        const updatedTitle = document.querySelector("#edit-title").value.trim();        
        const updatedDescription = document.querySelector("#edit-description").value.trim();
        const updatedDueDate = document.querySelector("#edit-due-date").value;
        const updatedPriority = document.querySelector("#edit-priority").value;

        if (!updatedTitle || !updatedDueDate) {
            alert("Title and Due Date are required.");
            return;
        }

        // Update todo properties
        todo.title = updatedTitle;
        todo.description = updatedDescription;
        todo.dueDate = updatedDueDate;
        todo.priority = updatedPriority;

        try {
            updateTodo(todo); // Update in state and save
            closeModal();
        } catch (error) {
            console.error("Error updating todo:", error);
        }
    closeModal();
}
/**
 * Show the edit form modal with the current task data.
 * @param {Todo} todo – The todo to edit.
 * @param {Project} project – The project containing the todo.
 */
function showEditForm(todo, project) {
    if (!project) {
        console.error("Project is undefined"); // Debugging line
        return; // Exit if project is undefined
    }

    // Fill in the form with current todo data
    document.querySelector("#edit-title").value = todo.title;
    document.querySelector("#edit-description").value = todo.description;
    document.querySelector("#edit-due-date").value = todo.dueDate;
    document.querySelector("#edit-priority").value = todo.priority;

    const modal = document.querySelector("#edit-task-modal");
    if (!modal) {
        console.error("Edit Task Modal not found in the DOM");
        return;
    }

    modal.style.display = "block";
    document.body.classList.add('modal-open'); // Prevent background scrolling
    modal.setAttribute('aria-hidden', 'false');
    modal.querySelector("#edit-title").focus();

    // Save changes
    document.querySelector("#save-changes-button").addEventListener('click', saveChangesHandler)
    

    // Cancel changes
    document.querySelector('#cancel-button').onclick = () => {
        closeModal();
    };
    
    // Close modal when clicking the close button
    document.querySelector('.close-button').onclick = () => {
        closeModal();
    };

    // Close modal when clicking outside of the modal control
    window.addEventListener("click", (event) => {
        if (event.target === modal) {
            closeModal();
        }
    });
}

/**
 * Function to close the edit modal.
 */
function closeModal() {
    const modal = document.querySelector('#edit-task-modal');
    if (modal) {
        modal.style.display = "none";
        document.body.classList.remove('modal-open');
        modal.setAttribute('aria-hidden', 'true');
    }
    document.querySelector('#save-changes-button').removeEventListener('click', saveChangesHandler);
}

// /**
//  * Function to close the edit modal.
//  */
// function closeModal() {
//     const modal = document.querySelector('#edit-task-modal');
//     if (modal) {
//         modal.style.display = 'none';
//     }
// }

/**
 * Setup project selection interactions.
 */
export function setupProjectSelection() {
    const projectContainer = document.querySelector('#project-list');

    projectContainer.addEventListener('click', (event) => {
        if (event.target && event.target.matches('li.project-item')) {
            const index = parseInt(event.target.getAttribute('data-index'));
            setCurrentProjectIndex(index);
            highlightSelectedProject(index);
            const currentProject = getState().projects[index];
            renderTodos(currentProject);
        }
    });

    // Accessibility: Allow selection via keyboard
    projectContainer.addEventListener('keydown', (event) => {
        if (event.key === "Enter" && event.target.matches('li.project-item')) {
            const index = parseInt(event.target.getAttribute('data-index'));
            setCurrentProjectIndex(index);
            highlightSelectedProject(index);
            const currentProject = getState().projects[index];
            renderTodos(currentProject);
        }
    });
}

/**
 * Initialize UI interactions.
 */
export function initializeUI() {
    setupProjectSelection();
    setupTodoInteraction();
    setupModalCloseOnEscape();
}

/**
 * Set up closing the modal when Esc key is pressed.
 */
function setupModalCloseOnEscape() {
    const modal = document.querySelector('#edit-task-modal');
    window.addEventListener('keydown', (event) => {
        if (event.key === 'Escape' && modal.style.display !== 'none') {
            closeModal();
        }
    });
}

/**
 * Function to handle adding a new todo.
 */
function handleAddTodo() {
    try {
        const title = document.querySelector('#todo-title').value;
        const description = document.querySelector('#todo-description').value;
        const dueDate = document.querySelector('#todo-due-date').value;
        const priority = document.querySelector('#todo-priority').value;

        if (title && dueDate) { // Ensure title and due date are provided
            addTodo(title, description, dueDate, priority); // Call function to add a new todo
            clearTodoInputs();
        } else {
            showAlert('Please fill in both title and due date.'); // Alert if fields are empty
        }
    } catch (error) {
        console.error('Error adding todo:', error);
    }
}

/**
 * Function to handle adding a new project.
 */
function handleAddProject() {
    try {
        const projectName = document.querySelector('#project-name').value;

        // Call function to add a new project
        if (projectName) {
            addProject(projectName);
            document.querySelector('#project-name').value = ''; // Clear input field
        } else {
            showAlert('Please enter a project name.') // Alert if project name is empty
        }
    } catch (error) {
        console.error('Error adding project:', error);
    }
}

/**
 * Function to clear todo input fields
 */
function clearTodoInputs() {
    document.querySelector('#todo-title').value = ''; // Clear input field after adding
    document.querySelector('#todo-description').value = '';
    document.querySelector('#todo-due-date').value = '';
    document.querySelector('#todo-priority').value = 'low'; // Reset priority to default
}

// Function to show alert messages
function showAlert(message) {
    const alertBox = document.createElement('div');
    alertBox.classList.add('alert');
    alertBox.textContent = message;

    document.body.appendChild(alertBox);

    // alertBox.style.display = 'block';
    setTimeout(() => {
        // alertBox.style.display = 'none';
        alertBox.classList.add('fade-out');
        alertBox.addEventListener('transitionend', () => {
            alertBox.remove();
        })
    }, 3000);
}

// todo.js

import { v4 as uuidv4 } from 'uuid'; // Ensure you have installed the `uuid` package via npm

const PRIORITY_LEVELS = {
    LOW: 'low',
    MEDIUM: 'medium',
    HIGH: 'high',
};

/**
 * Represents a single Todo item.
 */
export class Todo {
    /**
     * Creates a new Todo instance.
     * @param {string} title – The title of the todo.
     * @param {string} [description=''] – The description of the todo.
     * @param {string} dueDate – The due date of the todo in YYYY-MM-DD format.
     * @param {string} priority – The priority level ('low', 'medium', 'high').
     * @param {string} [notes=''] – Additional notes for the todo.
     * @param {string} [id] – Unique identifier for the todo.
     */
    constructor(title, description = '', dueDate, priority, notes = '', id = uuidv4()) {
        // Data Validation
        if (!title || typeof title !== 'string') {
            throw new Error('Title is required and must be a string.');
        }
        if (!dueDate || isNaN(dueDate) || !(dueDate instanceof Date)) {
            throw new Error('A valid Due Date is required');
        }
        if (!Object.values(PRIORITY_LEVELS).includes(priority)) {
            throw new Error(`Priority must be one of ${Object.values(PRIORITY_LEVELS).join(', ')}.`);
        }

        Object.defineProperty(this, 'id', {
            value: id,
            writable: false,
            enumerable: true,
        });

        this.id = id; // Robust unique ID generation
        this.title = title;
        this.description = description;
        this.dueDate = new Date(dueDate);
        this.priority = priority;
        this.notes = notes;
        this.completed = false; // Track completion status
        this.subtasks = []; // Array to hold subtasks if needed
        this.recurrence = null; // For recurring tasks
        this.checklist = [];
    }

    /**
     * Toggle the completion status of todo
     */
    toggleCompletion() {
        this.completed = !this.completed;
        return this;
    }

    /**
     * Add a subtask to the todo.
     * @param {Todo} subtask – The subtask to add.
     */
    addSubtask(subtask) {
        if (subtask instanceof Todo) {
            this.subtasks.push(subtask);
        } else {
            throw new Error('Subtask must be an instance of Todo.');
        }
    }

    /**
     * Remove a subtask from the todo by ID.
     * @param {string} subtaskId – The ID of the subtask to remove.
     */
    removeSubtask(subtaskId) {
        this.subtasks = this.subtasks.filter((st) => st.id !== subtaskId);
    }
}

// project.js

import { Todo } from './todo.js';

/**
 * Represents a project containing multiple todos.
 */
export class Project {
    /**
     * Creates a new Project instance.
     * @param {string} name – The name of the project.
     */
    constructor(name) {
        if (!name || typeof name !== 'string') {
            throw new Error('Project name is required and must be a string.');
        }

        this.name = name;
        this.todos = []; // Array to hold todos
    }

    /**
     * Add a new Todo to the project.
     * @param {Todo} todo – The todo instance to add.
     */
    addTodo(todo) {
        if (todo instanceof Todo) {
            this.todos.push(todo);
        } else {
            throw new Error('Only instances of Todo can be added.');
        }
    }

    /**
     * Remove a todo by its ID
     * @param {*} todoId 
     */
    removeTodo(todoId) {
        const initialLength = this.todos.length;
        this.todos = this.todos.filter((t) => t.id !== todoId); // Remove the todo
        if (this.todos.length === initialLength) {
            console.warn(`Todo with ID ${todoId} not found`);
        }
    }

    /**
     * Get a todo by its ID
     * @param {string} todoId – The ID of the todo to retrieve.
     * @returns {Todo|null} The todo instance or null if not found
     */
    getTodoById(todoId) {
        return this.todos.find((t) => t.id === todoId) || null;
    }

    /**
     * Update a todo's details
     * @param {Todo} updatedTodo – The updated Todo instance.
     */
    updateTodo(updatedTodo) {
        const index = this.todos.findIndex((t) => t.id === updatedTodo.id);
        if (index !== -1) {
            this.todos[index] = updatedTodo;
        } else {
            throw new Error(`Todo with ID ${updatedTodo.id} not found`);
        }
    }

    /**
     * Toggle completion status of a todo by its ID.
     * @param {string} todoId – The ID of the todo to toggle.
     */
    toggleTodoCompletion(todoId) {
        const todo = this.getTodoById(todoId);
        if (todo) {
            todo.toggleCompletion();
        } else {
            throw new Error(`Todo with ID ${todoId} not found`);
        }
    }

    /**
     * Get all completed todos.
     * @returns {Todo[]} Array of completed todos.
     */
    getCompletedTodos() {
        return this.todos.filter((todo) => todo.completed);
    }
}

// index.js

import './style.css';
import { addProject, addTodo, initializeApp } from './app.js';
import { initializeUI } from './ui.js';

// Initialize the application
initializeApp();

// Initialize UI interactions
initializeUI();

// Event listeners
document.addEventListener('click', (event) => {
    if (event.target.matches('#add-todo-button')) {
        handleAddTodo();
    }
    if (event.target.matches('#add-project-button')) {
        handleAddProject();
    }

    // Handle modal close actions
    if (event.target.matches('.close-button') || event.target.matches('#cancel-button')) {
        closeModal();
    }
});

/**
 * Optional: Keyboard accessibility for modal (e.g., closing with Escape key).
 */
window.addEventListener('keydown', (event) => {
    const modal = document.querySelector('#edit-task-modal');
    if (event.key === 'Escape' && modal.style.display === 'block') {
        closeModal();
    }
});

// localStorage.js

import { Project } from './project.js';
import { Todo } from './todo.js';

/**
 * Manages saving and loading projects to and from localStorage.
 */
export class StorageManager {
    /**
     * Save projects to localStorage.
     * @param {Array} projects – Array of Project instances.
     */
    static async saveProjects(projects) {
        try {
            const serializedProjects = JSON.stringify(projects);
            localStorage.setItem('projects', serializedProjects);
        } catch (error) {
            console.error('Error saving to localStorage:', error);
        }
    }

    /**
     * Loads projects from localStorage.
     * @returns {Array} Array of Project instances.
     */
    static async loadProjects() {
        try {
            const serializedProjects = localStorage.getItem('projects');
            if (!serializedProjects) return [];
            
            const projectsData = JSON.parse(serializedProjects);
            return projectsData.map((projectData) => {
                const project = new Project(projectData.name);
                project.todos = Array.isArray(projectData.todos) ? projectData.todos.map((todoData) => {
                    // Validate dueDate
                    if (!todoData.dueDate || isNaN(Date.parse(todoData.dueDate))) {
                        throw new Error(`Invalid due date for todo: ${todoData.dueDate}`);
                    }
    
                    const todo = new Todo(
                        todoData.title,
                        todoData.description,
                        new Date(todoData.dueDate),
                        todoData.priority,
                        todoData.notes,
                        todoData.id // Pass the existing ID
                    );
                    todo.completed = todoData.completed;
                    todo.subtasks = Array.isArray(todoData.subtasks) ? todoData.subtasks.map((subtaskData) => {
                        return new Todo(
                            subtaskData.title,
                            subtaskData.description,
                            subtaskData.dueDate,
                            subtaskData.priority,
                            subtaskData.notes,
                            subtaskData.id
                        );
                    })
                : [];
                todo.recurrence = todoData.recurrence || null;
                return todo;
                })
            : [];
            return project;
            });
        } catch (error) {
            console.error('Failed to load projects from localStorage:', error);
            // Optional: clean corrupted data
            localStorage.removeItem('projects');
            aler('Stored data was corrupted and has been reset.');
            // Return an empty array or default projects
            return [];
        }
    }
}

// app.js

import { Project } from './project.js';
import { Todo } from './todo.js';
import { StorageManager } from './localStorage.js';
import { renderTodos, renderProjects } from './ui.js';

/**
 * Application state encapsulated in an object.
 */
const state = {
  projects: [],
  currentProjectIndex: 0
};

export function getProjects() {
  return [...state.projects] // Return a shallow copy to prevent mutations
}

export function getCurrentProjectIndex() {
  return state.currentProjectIndex;
}

export function getCurrentProject() {
  return state.projects[state.currentProjectIndex];
}

/**
 * Getter for the application state.
 * @returns {Object} The current state.
 */
export function getState() {
  return state;
}

/**
 * Sets the current project index and renders its todos.
 * @param {number} index – The index of the project to set as current.
 */
export function setCurrentProjectIndex(index) {
  if (index >= 0 && index < state.projects.length) {
    state.currentProjectIndex = index;
    renderTodos(state.projects[index]);
  } else {
    console.error('Invalid project index.');
  }
}

// export function selectProject(index) {
//   if (index => 0 && index < projectsArray.length) {
//     currentProjectIndex = index;
//     renderTodos(projectsArray[index]);
//   } else {
//     console.error('Invalid project index');
//   }
// }

/**
 * Initializes the application by loading projects and rendering them.
 */
export function initializeApp() {
  // Load existing projects from localStorage on startup
  const loadedProjects = StorageManager.loadProjects();

  if (loadedProjects.length > 0) {
    state.projects = loadedProjects;
  } else {
    // Create a default project if none exist
    const defaultProject = new Project('Default Project');
    state.projects.push(defaultProject);
    StorageManager.saveProjects(state.projects);
  }

  // Render the loaded or default projects
  renderProjects(state.projects);
  renderTodos(getCurrentProject());
}

/**
 * Adds a new todo to the current project
 * @param {string} title – The title of the todo.
 * @param {string} description – The description of the todo.
 * @param {string} dueDate – The due date of the todo.
 * @param {string} priority – The priority of the todo.
 */
export function addTodo(title, description, dueDate, priority) {
  const currentProject = state.projects[state.currentProjectIndex]; // Use selected project

  if (!currentProject) {
    console.error('No current project selected');
    return;
  }

  try {
    const newTodo = new Todo(title, description, dueDate, priority);
    currentProject.addTodo(newTodo);
    // Save updated projects to localStorage
    StorageManager.saveProjects(state.projects);

    // Render todos for the current project
    renderTodos(currentProject);
  } catch (error) {
    console.error('Error adding todo:', error);
  }
  // return newTodo; // Return the created Todo object
}

/**
 * Adds a new project to the application.
 * @param {string} projectName – The name of the new project.
 */
export function addProject(projectName) {
  if (!projectName || typeof projectName !== 'string') {
    console.error('Invalid project name');
    return;
  }
  try {
    const newProject = new Project(projectName);
    state.projects.push(newProject);
    // Save updated projects to localStorage
    StorageManager.saveProjects(state.projects);

    // Re-render the projects list
    renderProjects(state.projects);
  } catch (error) {
    console.error('Error adding project:', error);
  }
}

// Function to update a todo
/**
 * Updates the existing todo in the current project.
 * @param {Todo} updatedTodo – The todo instance with updated details.
 * @returns 
 */
export function updateTodo(updatedTodo) {
  const currentProject = state.projects[state.currentProjectIndex];
  if (!currentProject) {
    console.error('No current project selected.');
    return;
  }

  try {
    currentProject.updateTodo(updatedTodo);
    StorageManager.saveProjects(state.projects);
    renderTodos(currentProject);
  } catch (error) {
    console.error('Error updating todo:', error);
  }
}