import Foundation import Combine /// Manages authentication state, user session, profile management, and audio sync access authorization. final class AuthManager: ObservableObject { static let shared = AuthManager() @Published private(set) var currentUser: UserAccount? @Published var isProcessing: Bool = false @Published var authErrorMessage: String? @Published private(set) var isRestoringSession: Bool = true var isLoggedIn: Bool { currentUser != nil } /// Production server authentication service. private let authService: AuthServiceProtocol init(authService: AuthServiceProtocol = RemoteAuthService()) { self.authService = authService self.currentUser = authService.getCurrentUser() authService.restoreSession { [weak self] result in DispatchQueue.main.async { guard let self else { return } self.isRestoringSession = false switch result { case .success(let user): self.currentUser = user case .failure(let error): self.currentUser = nil self.authErrorMessage = error.localizedDescription } } } } // MARK: - Auth Actions /// User login via username/email/phone & password. func login(identifier: String, password: String, completion: ((Bool, String?) -> Void)? = nil) { isProcessing = true authErrorMessage = nil let req = LoginRequest(identifier: identifier, password: password) authService.login(request: req) { [weak self] result in DispatchQueue.main.async { guard let self = self else { return } self.isProcessing = false switch result { case .success(let user): self.currentUser = user completion?(true, nil) case .failure(let error): self.authErrorMessage = error.localizedDescription completion?(false, error.localizedDescription) } } } } /// User registration. func register(username: String, identifier: String, password: String, completion: ((Bool, String?) -> Void)? = nil) { isProcessing = true authErrorMessage = nil let req = RegisterRequest(username: username, identifier: identifier, password: password) authService.register(request: req) { [weak self] result in DispatchQueue.main.async { guard let self = self else { return } self.isProcessing = false switch result { case .success(let user): self.currentUser = user completion?(true, nil) case .failure(let error): self.authErrorMessage = error.localizedDescription completion?(false, error.localizedDescription) } } } } /// Update profile information (nickname, email, phone, avatar). func updateProfile(username: String?, email: String?, phoneNumber: String?, avatarURL: String?, completion: ((Bool, String?) -> Void)? = nil) { isProcessing = true authErrorMessage = nil let req = UpdateProfileRequest(username: username, email: email, phoneNumber: phoneNumber, avatarURL: avatarURL) authService.updateProfile(request: req) { [weak self] result in DispatchQueue.main.async { guard let self = self else { return } self.isProcessing = false switch result { case .success(let user): self.currentUser = user completion?(true, nil) case .failure(let error): self.authErrorMessage = error.localizedDescription completion?(false, error.localizedDescription) } } } } /// Change password. func changePassword(oldPassword: String, newPassword: String, completion: ((Bool, String?) -> Void)? = nil) { isProcessing = true authErrorMessage = nil let req = ChangePasswordRequest(oldPassword: oldPassword, newPassword: newPassword) authService.changePassword(request: req) { [weak self] result in DispatchQueue.main.async { guard let self = self else { return } self.isProcessing = false switch result { case .success: completion?(true, nil) case .failure(let error): self.authErrorMessage = error.localizedDescription completion?(false, error.localizedDescription) } } } } /// Logout current user. func logout() { authService.logout { [weak self] in DispatchQueue.main.async { self?.currentUser = nil } } } }