import Foundation /// Data model shared between the main app and widget extension via App Group UserDefaults. struct WidgetData: Codable, Equatable { let threatScore: Double let recentAlerts: [WidgetAlert] let alertCount: Int let unreadCount: Int let criticalCount: Int let exposureCount: Int let lastUpdated: Date static let placeholder = WidgetData( threatScore: 0.25, recentAlerts: WidgetAlert.placeholders, alertCount: 5, unreadCount: 3, criticalCount: 1, exposureCount: 2, lastUpdated: Date() ) static let unavailable = WidgetData( threatScore: 0, recentAlerts: [], alertCount: 0, unreadCount: 0, criticalCount: 0, exposureCount: 0, lastUpdated: Date() ) var threatLevel: ThreatLevel { let pct = threatScore if pct >= 0.7 { return .critical } if pct >= 0.4 { return .high } if pct >= 0.2 { return .medium } return .low } } enum ThreatLevel: String, Codable { case low, medium, high, critical var label: String { rawValue.capitalized } } struct WidgetAlert: Codable, Identifiable, Equatable { let id: String let title: String let message: String let severity: String let type: String let createdAt: Date? var severityEnum: AlertSeverity { AlertSeverity(rawValue: severity) ?? .low } var typeEnum: AlertType { AlertType(rawValue: type) ?? .exposure } static let placeholders: [WidgetAlert] = [ WidgetAlert( id: "placeholder-1", title: "Data Breach Detected", message: "Your email was found in a recent data breach.", severity: "critical", type: "breach", createdAt: Date() ), WidgetAlert( id: "placeholder-2", title: "New Exposure Found", message: "Personal information exposed on a public forum.", severity: "high", type: "exposure", createdAt: Date().addingTimeInterval(-3600) ), WidgetAlert( id: "placeholder-3", title: "Voice Match Detected", message: "Suspicious call pattern flagged.", severity: "medium", type: "voiceMatch", createdAt: Date().addingTimeInterval(-7200) ), ] } enum AlertSeverity: String, Codable { case low = "low" case medium = "medium" case high = "high" case critical = "critical" } enum AlertType: String, Codable { case exposure = "exposure" case breach = "breach" case login = "login" case voiceMatch = "voiceMatch" case removal = "removal" }