// // TodosViewModel.swift // iris // // Created by Codex. // import Foundation @MainActor final class TodosViewModel: ObservableObject { @Published private(set) var todos: [TodoItem] = [] @Published var newTitle: String = "" private let store: TodoStore init(store: TodoStore = TodoStore()) { self.store = store refresh() } func refresh() { todos = sortedItems(store.snapshot()) } func addTodo() { let trimmed = normalizedTitle(newTitle) guard !trimmed.isEmpty else { return } store.add(title: trimmed) newTitle = "" refresh() } func deleteTodo(id: UUID) { store.delete(id: id) refresh() } func toggleCompleted(id: UUID) { guard let current = todos.first(where: { $0.id == id }) else { return } store.setCompleted(id: id, completed: !current.isCompleted) refresh() } func updateTitle(id: UUID, title: String) { let trimmed = normalizedTitle(title) guard !trimmed.isEmpty else { return } store.updateTitle(id: id, title: trimmed) refresh() } private func normalizedTitle(_ raw: String) -> String { raw.trimmingCharacters(in: .whitespacesAndNewlines) } private func sortedItems(_ items: [TodoItem]) -> [TodoItem] { items.sorted { lhs, rhs in if lhs.isCompleted != rhs.isCompleted { return !lhs.isCompleted } if lhs.isCompleted { let lhsDate = lhs.completedAt ?? lhs.updatedAt let rhsDate = rhs.completedAt ?? rhs.updatedAt if lhsDate != rhsDate { return lhsDate > rhsDate } } else if lhs.createdAt != rhs.createdAt { return lhs.createdAt > rhs.createdAt } return lhs.id.uuidString < rhs.id.uuidString } } }