import Foundation import ManaCore import Observation /// State-Maschine für ``ManaForgotPasswordView``. Wraps /// `AuthClient.forgotPassword`. /// /// **User-Enumeration-Schutz:** Server antwortet immer 200, /// unabhängig davon ob die Email existiert. Die UI meldet daher /// generisch ("Wenn dein Account existiert, ist eine Mail unterwegs"). @MainActor @Observable public final class ForgotPasswordViewModel { public enum Status: Equatable, Sendable { case idle case sending case sent case error(String) } public var email: String = "" public private(set) var status: Status = .idle private let auth: AuthClient private let resetUniversalLink: URL /// - Parameter resetUniversalLink: Universal-Link der App für den /// Reset-Klick aus der Email. Z.B. /// `URL(string: "https://cardecky.mana.how/auth/reset")!`. public init(auth: AuthClient, resetUniversalLink: URL) { self.auth = auth self.resetUniversalLink = resetUniversalLink } public var canSubmit: Bool { guard !email.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty else { return false } if case .sending = status { return false } return true } public var isSending: Bool { if case .sending = status { return true } return false } public func submit() async { let trimmed = email.trimmingCharacters(in: .whitespacesAndNewlines) guard !trimmed.isEmpty else { return } status = .sending do { try await auth.forgotPassword(email: trimmed, resetUniversalLink: resetUniversalLink) status = .sent } catch let error as AuthError { status = .error(error.errorDescription ?? "Senden fehlgeschlagen") } catch { status = .error(String(describing: error)) } } }