import Foundation import SwiftData @MainActor @Observable final class TrackingEngine { private(set) var activeSessions: [UUID: Date] = [:] private(set) var elapsedTimes: [UUID: TimeInterval] = [:] private var tickTask: Task? init() { tickTask = Task { while !Task.isCancelled { try? await Task.sleep(for: .seconds(1)) self.tick() } } } private func tick() { let now = Date.now for (id, start) in activeSessions { elapsedTimes[id] = now.timeIntervalSince(start) } } func isRunning(_ task: TaskItem) -> Bool { activeSessions[task.id] != nil } func elapsed(for task: TaskItem) -> TimeInterval { elapsedTimes[task.id] ?? 0 } func startTimer(for task: TaskItem, context: ModelContext) { guard !isRunning(task) else { return } let now = Date.now let record = TrackingRecord(task: task, recordType: .timerSession, startTime: now) context.insert(record) task.trackingRecords.append(record) activeSessions[task.id] = now elapsedTimes[task.id] = 0 } func stopTimer(for task: TaskItem, context: ModelContext) { guard let startTime = activeSessions[task.id] else { return } let now = Date.now if let record = task.trackingRecords.first(where: { $0.isRunning }) { record.endTime = now record.duration = now.timeIntervalSince(startTime) } activeSessions.removeValue(forKey: task.id) elapsedTimes.removeValue(forKey: task.id) } func incrementCounter(for task: TaskItem, context: ModelContext) { let record = TrackingRecord(task: task, recordType: .countLog, timestamp: .now) context.insert(record) task.trackingRecords.append(record) } }