this is the class for a task list that i am developing in flutter. I would like to add the following functionalities to it. Please generate the full code.

Neste trabalho vamos acrescentar duas animações na lista de tarefas:
Ao concluir uma tarefa, ela deve deslizar por sobre a lista de tarefas (8 pontos)
Uma opção simples é usar um Stack e um AnimatedPositioned
Pode usar as classes do tutorial de animação da aula de hoje.
Pode (deve!) usar a classe AnimatedList.
A tarefa concluída deve fazer um "tilt" ao ir para a posição, como se estivesse caindo um lado primeiro (inclinar e depois alinhar horizontalmente de novo). (2 pontos)
Essas animações devem ser feitas apenas ao concluir uma tarefa.
Não é necessário fazer a animação ao "desconcluir" uma tarefa (embora seja fácil...)
Não altere o comportamento do "deletar tarefa" (continua o desfazer com 3 segundos)
Se você colocou um "desfazer" de três segundos no concluir tarefa, tire - vai atrapalhar a animação!
Implemente o desconcluir tarefa! Deve apenas mover a tarefa para o final da lista de tarefas não concluída.

class HomePage extends StatefulWidget {
  final String title;

  const HomePage({
    super.key,
    required this.title,
  });

  @override
  State<HomePage> createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  List<String> taskList = [];
  final Map<String, bool> deletingTasks = {};
  Map<String, bool> taskStatus = {}; // Keep track of task statuses
  final textController = TextEditingController();
  final FocusNode textFieldFocus = FocusNode();
  int finishedTaskIndex = -1;
  final ApiService _apiService = ApiService(); // Use the singleton instance

  // Função para obter as tarefas do servidor
  Future _getTasks() async {
    try {
      Map? data = await _apiService.getTasks();
      if (data.isEmpty) {
        // A obtenção dos dados falhou
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(content: Text('Não foi possivel obter a lista de tarefas')),
        );
        await _apiService.deleteTasks();
      } else {
        setState(() {
          taskList = data["list"];
          taskStatus = data["status"];
          finishedTaskIndex = data["finishedTaskIndex"];
        });
      }
    } catch (e) {
      // print(e);
    }
  }

  @override
  void initState() {
    super.initState();
    _getTasks();  // Fetch tasks when the widget is initialized
  }

  // Function to add a task
  void _addTask(String st) {
    final trimmedTask = st.trim();
    if (trimmedTask.isEmpty) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Por favor, escreva uma tarefa antes de adicionar!')),
      );
      FocusScope.of(context).requestFocus(textFieldFocus);
    } else if (taskList.contains(trimmedTask)) {
      ScaffoldMessenger.of(context).showSnackBar(
        const SnackBar(content: Text('Essa tarefa já foi adicionada!')),
      );
      FocusScope.of(context).requestFocus(textFieldFocus);
    } else {
      setState(() {
        taskList.insert(finishedTaskIndex + 1, trimmedTask);
        taskStatus[trimmedTask] = false; // Initialize the task status to false (unchecked)
        finishedTaskIndex++;
        textController.clear();
        _apiService.updateTasks(taskList, taskStatus);
      });
      FocusScope.of(context).requestFocus(textFieldFocus);
    }
  }

  // Function to delete a task (with delay)
  void _deleteTask(String task) async {
    setState(() {
      deletingTasks[task] = true; // Mark task as being deleted
    });

    // Wait for 3 seconds before deleting the task
    await Future.delayed(const Duration(seconds: 3));

    if (deletingTasks[task] == true) {
      setState(() {
        if (taskStatus[task] == false) {
          finishedTaskIndex--;
        }
        taskList.remove(task); // Remove task if deletion not undone
        taskStatus.remove(task); // Remove task status
        _apiService.updateTasks(taskList, taskStatus);
      });
    }
    deletingTasks.remove(task); // Remove deletion state after task is gone
  }

  // Function to undo the deletion of a task
  void _undeleteTask(String task) {
    setState(() {
      deletingTasks[task] = false; // Undo the deletion state
    });
  }

  // Function to change the status (checked/unchecked) of a task
  void _changeTaskStatus(String task, bool value) {
    setState(() {
      taskStatus[task] = value; // Update the task's checked status
      if (value == true) {
        taskList.remove(task);
        taskList.insert(finishedTaskIndex, task);
        finishedTaskIndex--;
      } else {
        taskList.remove(task);
        taskList.insert(0, task);
        finishedTaskIndex++;
      }
      _apiService.updateTasks(taskList, taskStatus);
    });
  }

  @override
  void dispose() {
    textController.dispose();
    textFieldFocus.dispose(); // Dispose the FocusNode
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        foregroundColor: Colors.white,
        backgroundColor: Colors.indigo[400],
        title: Text(widget.title),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        children: [
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: Row(
              children: [
                Expanded(
                  child: TextField(
                    controller: textController,
                    autofocus: true,
                    focusNode: textFieldFocus,
                    onSubmitted: _addTask,
                    decoration: InputDecoration(
                      border: OutlineInputBorder(
                        borderRadius: BorderRadius.circular(30.0),
                      ),
                      filled: true,
                      hintStyle: TextStyle(color: Colors.grey[500]),
                      hintText: "Escreva sua tarefa",
                      fillColor: Colors.white70,
                    ),
                  ),
                ),
                const SizedBox(width: 10),
                IconButton(
                  icon: const Icon(Icons.add),
                  onPressed: () => _addTask(textController.text),
                  tooltip: 'Adicionar tarefa',
                ),
              ],
            ),
          ),
          Expanded(
            child: ListView.builder(
              itemCount: taskList.length,
              itemBuilder: (context, index) {
                String task = taskList[index];
                return Dismissible(
                  key: UniqueKey(),
                  background: Container(
                    color: Colors.green[400],
                    alignment: Alignment.centerLeft,
                    padding: const EdgeInsets.only(left: 20),
                    child: const Icon(Icons.check, color: Colors.white),
                  ),
                  secondaryBackground: Container(
                    color: Colors.red[400],
                    alignment: Alignment.centerRight,
                    padding: const EdgeInsets.only(right: 20),
                    child: const Icon(Icons.delete, color: Colors.white),
                  ),
                  onDismissed: (direction) {
                    if (direction == DismissDirection.startToEnd) { // Da esquerda para a direita
                      _changeTaskStatus(task, true);
                    } else if (direction == DismissDirection.endToStart) { // Da direita para a esquerda
                      _deleteTask(task);
                    }
                  },
                  child: Card(
                    color: deletingTasks[task] == true
                        ? Colors.red[400]
                        : (index % 2 == 0) ? Colors.indigo[300] : Colors.indigo[400],
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(9.0),
                    ),
                    child: CheckboxListTile(
                      controlAffinity: ListTileControlAffinity.leading,
                      title: taskStatus[task] == true
                          ? Text(task, style: const TextStyle(decoration: TextDecoration.lineThrough, color: Colors.white, decorationColor: Colors.white, decorationThickness: 1.5))
                          : Text(task, style: const TextStyle(color: Colors.white)),
                      value: taskStatus[task],
                      checkColor: Colors.black,
                      activeColor: Colors.white,
                      onChanged: (bool? value) {
                        if (value != null) {
                          _changeTaskStatus(task, value);
                        }
                      },
                      secondary: IconButton(
                        icon: deletingTasks[task] == true
                            ? const Icon(Icons.undo_rounded, color: Colors.white)
                            : const Icon(Icons.delete_rounded, color: Colors.white),
                        onPressed: () {
                          if (deletingTasks[task] == true) {
                            _undeleteTask(task);
                          } else {
                            _deleteTask(task);
                          }
                        },
                      ),
                    ),
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}