1import 'dart:async';
2
3enum Priority { low, medium, high, urgent }
4
5class Task {
6 final String id;
7 final String title;
8 final Priority priority;
9 bool completed;
10 final DateTime createdAt;
11
12 Task({
13 required this.id,
14 required this.title,
15 this.priority = Priority.medium,
16 this.completed = false,
17 }) : createdAt = DateTime.now();
18
19 Task copyWith({
20 String? title,
21 Priority? priority,
22 bool? completed,
23 }) {
24 return Task(
25 id: id,
26 title: title ?? this.title,
27 priority: priority ?? this.priority,
28 completed: completed ?? this.completed,
29 );
30 }
31}
32
33class TaskStore {
34 final Map<String, Task> _tasks = {};
35 final _controller = StreamController<List<Task>>.broadcast();
36 int _nextId = 1;
37
38 Stream<List<Task>> get stream => _controller.stream;
39
40 List<Task> get all => _tasks.values.toList()
41 ..sort((a, b) =>
42 b.priority.index.compareTo(a.priority.index));
43
44 void add(String title, {Priority priority = Priority.medium}) {
45 final id = 'task_${_nextId++}';
46 _tasks[id] = Task(
47 id: id,
48 title: title,
49 priority: priority,
50 );
51 _notify();
52 }
53
54 void toggle(String id) {
55 final task = _tasks[id];
56 if (task != null) {
57 _tasks[id] = task.copyWith(completed: !task.completed);
58 _notify();
59 }
60 }
61
62 Future<List<Task>> search(String query) async {
63 await Future.delayed(Duration(milliseconds: 50));
64 final lower = query.toLowerCase();
65 return all
66 .where((t) => t.title.toLowerCase().contains(lower))
67 .toList();
68 }
69
70 Map<Priority, int> countByPriority() {
71 return {
72 for (var p in Priority.values)
73 p: all.where((t) => t.priority == p).length,
74 };
75 }
76
77 void _notify() => _controller.add(all);
78
79 void dispose() => _controller.close();
80}