Fix this code to do the following instruction:
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.
Here is the code:
class MyHomePage extends StatefulWidget {
  final String title;
  final String jwtToken;
  final String email;
  final List<Map<String, int>> taskList;

  const MyHomePage({
    super.key,
    required this.title,
    required this.jwtToken,
    required this.email,
    required this.taskList,
  });

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late List<Map<String, int>> taskList;
  final textController = TextEditingController();
  bool isDeleting = false;
  Completer<bool?>? deleteCompleter;
  List<int> pendingDeleteIndexes = [];
  final GlobalKey<AnimatedListState> _listKey = GlobalKey<AnimatedListState>();

  @override
  void initState() {
    super.initState();
    taskList = List.from(widget.taskList); // Inicializa a lista de tarefas
  }

  void _addTask(String st) {
    setState(() {
      if (st.trim() != '' &&
          !taskList.any((task) => task.containsKey(st.trim()))) {
        int insertIndex = taskList.indexWhere((task) => task.values.first == 1);
        if (insertIndex == -1) {
          taskList.insert(0, {st.trim(): 0});
          _listKey.currentState?.insertItem(0);
        } else {
          taskList.insert(insertIndex, {st.trim(): 0});
          _listKey.currentState?.insertItem(insertIndex);
        }
        textController.clear();
      }
    });
  }

  Future<void> saveTaskList(List<Map<String, int>> taskList) async {
    String url = 'https://barra.cos.ufrj.br/rest/tarefas';
    String email = widget.email; // Pega o email do usuário autenticado

    // Cria a estrutura de dados para salvar as tarefas
    List<Map<String, dynamic>> taskData = taskList.map((task) {
      return {
        "nome": task.keys.first, // O nome da tarefa está no primeiro índice
        "status": task.values.first == 1
            ? "true"
            : "false", // 1 para concluída, 0 para não concluída
        "ordem": taskList
            .indexOf(task) // A ordem é baseada no índice da tarefa na lista
      };
    }).toList();

    Map<String, dynamic> data = {
      "email": email,
      "valor": taskData,
    };
    var response = await http.patch(
      Uri.parse(url),
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer ${widget.jwtToken}', // Token JWT do usuário
      },
      body: jsonEncode(data).toString(),
    );

    if (response.statusCode == 200 || response.statusCode == 204) {
      print('Tarefas salvas com sucesso!');
    } else {
      final errorMsg = jsonDecode(response.body)['message'];
      if (errorMsg=='JWT expired'){
        _showDialog('Erro !',errorMsg);
      } else {
        _showDialog('Erro !','Erro: ${response.statusCode}');
      }
    }
  }
  
  void _deleteTask(int index) {
    setState(() {
      final removedTask = taskList.removeAt(index);
      _listKey.currentState?.removeItem(
        index,
        (context, animation) => SizeTransition(
          sizeFactor: animation,
          axis: Axis.vertical,
          child: ListTile(
            title: Text(removedTask.keys.first),
          ),
        ),
      );
      pendingDeleteIndexes.remove(index);
    });
  }

  void _taskDone(int index) {
    setState(() {
      final removedTask = taskList.removeAt(index);
      _listKey.currentState?.removeItem(
        index,
        (context, animation) => SizeTransition(
          sizeFactor: animation,
          axis: Axis.vertical,
          child: ListTile(
            title: Text(removedTask.keys.first),
          ),
        ),
      );
      taskList.add({removedTask.keys.first: 1});
      Future.delayed(Duration(milliseconds: 300), () {
        _listKey.currentState?.insertItem(taskList.length - 1);
      });
    });
  }

  void _taskUnDone(int index) {
    setState(() {
      final removedTask = taskList.removeAt(index);
      _listKey.currentState?.removeItem(
        index,
        (context, animation) => SizeTransition(
          sizeFactor: animation,
          axis: Axis.vertical,
          child: ListTile(
            title: Text(removedTask.keys.first),
          ),
        ),
      );
      taskList.insert(0, {removedTask.keys.first: 0});
      Future.delayed(Duration(milliseconds: 300), () {
        _listKey.currentState?.insertItem(0);
      });
    });
  }

  void _showDialog(String title, String content) {
    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text(title),
          content: Text(content),
          actions: [
            TextButton(
              onPressed: () {
                if (content == 'JWT expired') {
                  Navigator.of(context).pop();
                }
                Navigator.of(context).pop();
              },
              child: const Text('Fechar'),
            ),
          ],
        );
      },
    );
  }

  @override
  void dispose() {
    textController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        foregroundColor: Colors.white,
        backgroundColor: Colors.lightGreen[800],
        title: Text(widget.title),
      ),
      body: Column(
        mainAxisAlignment: MainAxisAlignment.start,
        children: [
          TextField(
            controller: textController,
            autofocus: true,
            onSubmitted: _addTask,
          ),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              FloatingActionButton(
                onPressed: () => _addTask(textController.text),
                tooltip: 'Add text',
                child: const Icon(Icons.add),
              ),
              const SizedBox(width: 16),
              ElevatedButton(
                onPressed: () {
                  saveTaskList(taskList);
                },
                style: ElevatedButton.styleFrom(
                  backgroundColor: Theme.of(context).colorScheme.primaryContainer,
                  foregroundColor: Colors.black,
                ),
                child: const Text('Salvar Lista de Tarefas'),
              ),
            ],
          ),
          Expanded(
            child: AnimatedList(
              key: _listKey,
              initialItemCount: taskList.length,
              itemBuilder: (context, index, animation) {
                Map<String, int> task = taskList[index];
                return SizeTransition(
                  sizeFactor: animation,
                  axis: Axis.vertical,
                  child: ListTile(
                    title: Text(
                      task.keys.first,
                      style: TextStyle(
                        decoration: task.values.first == 1
                            ? TextDecoration.lineThrough
                            : TextDecoration.none,
                      ),
                    ),
                    tileColor: task.values.first == 1 ? Colors.green[100] : Colors.grey[200],
                    leading: Checkbox(
                      value: task.values.first == 1,
                      onChanged: (bool? checked) {
                        if (checked == true) {
                          _taskDone(index);
                        } else {
                          _taskUnDone(index);
                        }
                      },
                    ),
                    trailing: pendingDeleteIndexes.contains(index)
                        ? IconButton(
                            icon: const Icon(Icons.undo),
                            onPressed: () {
                              setState(() {
                                pendingDeleteIndexes.remove(index);
                              });
                            },
                          )
                        : IconButton(
                            icon: const Icon(Icons.delete),
                            onPressed: () {
                              setState(() {
                                pendingDeleteIndexes.add(index);
                              });
                              deleteCompleter = Completer<bool?>();

                              Future.any([
                                Future<bool?>.delayed(const Duration(seconds: 3), () => true),
                                deleteCompleter!.future,
                              ]).then((value) {
                                if (value == true &&
                                    pendingDeleteIndexes.contains(index)) {
                                  _deleteTask(index);
                                }
                              });
                            },
                          ),
                  ),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}