// // LoginViewModel.swift // VolnahubApp // // Created by cheykrym on 09/06/2025. // import Foundation import Combine class LoginViewModel: ObservableObject { @Published var username: String = "" @Published var userId: String = "" @Published var password: String = "" @Published var isLoading: Bool = true // сразу true, чтобы показать спиннер при автологине @Published var showError: Bool = false @Published var errorMessage: String = "" @Published var isLoggedIn: Bool = false @Published var socketState: SocketService.ConnectionState @Published var chatLoadingState: ChatLoadingState = .idle private let authService = AuthService() private let socketService = SocketService.shared private var cancellables = Set() enum ChatLoadingState: Equatable { case idle case loading } private enum DefaultsKeys { static let currentUser = "currentUser" static let userId = "userId" } init() { socketState = socketService.currentConnectionState observeSocketState() observeChatsReload() // loadStoredUser() // Запускаем автологин autoLogin() } private func observeSocketState() { socketService.connectionStatePublisher .receive(on: DispatchQueue.main) .sink { [weak self] state in self?.handleSocketStateChange(state) } .store(in: &cancellables) } private func observeChatsReload() { NotificationCenter.default.publisher(for: .chatsReloadCompleted) .receive(on: DispatchQueue.main) .sink { [weak self] _ in self?.chatLoadingState = .idle } .store(in: &cancellables) } private func handleSocketStateChange(_ state: SocketService.ConnectionState) { socketState = state if state == .connected { triggerChatsReloadIfNeeded() } else { chatLoadingState = .idle } } private func triggerChatsReloadIfNeeded() { guard chatLoadingState != .loading else { return } chatLoadingState = .loading NotificationCenter.default.post(name: .chatsShouldRefresh, object: nil) } func autoLogin() { authService.autoLogin { [weak self] success, error in DispatchQueue.main.async { // self?.isLoading = false if success { self?.loadStoredUser() self?.isLoggedIn = true self?.socketService.connectForCurrentUser() } else { self?.isLoggedIn = false self?.errorMessage = error ?? NSLocalizedString("Произошла ошибка.", comment: "") self?.showError = false self?.socketService.disconnect() } self?.isLoading = false } } } func login() { isLoading = true showError = false authService.login(username: username, password: password) { [weak self] success, error in DispatchQueue.main.async { self?.isLoading = false if success { self?.loadStoredUser() self?.isLoggedIn = true self?.socketService.connectForCurrentUser() } else { self?.errorMessage = error ?? NSLocalizedString("Неизвестная ошибка", comment: "") self?.showError = true self?.socketService.disconnect() } } } } func registerUser(username: String, password: String, invite: String?, completion: @escaping (Bool, String?) -> Void) { authService.register(username: username, password: password, invite: invite) { [weak self] success, message in DispatchQueue.main.async { if success { self?.isLoggedIn = true // 👈 переключаем на главный экран после автологина self?.loadStoredUser() self?.socketService.connectForCurrentUser() } else { self?.socketService.disconnect() } completion(success, message) } } } func logoutCurrentUser() { authService.logoutCurrentUser { [weak self] success, error in DispatchQueue.main.async { if success { self?.loadStoredUser() self?.password = "" self?.isLoggedIn = true self?.showError = false self?.socketService.connectForCurrentUser() } else { self?.username = "" self?.userId = "" self?.password = "" self?.isLoggedIn = false self?.errorMessage = error ?? NSLocalizedString("Ошибка при деавторизации.", comment: "") self?.showError = false self?.socketService.disconnect() } } } } // func logout() { // username = "" // password = "" // isLoggedIn = false // showError = false // errorMessage = "" // } private func loadStoredUser() { let defaults = UserDefaults.standard username = defaults.string(forKey: DefaultsKeys.currentUser) ?? "" userId = KeychainService.shared.get(forKey: DefaultsKeys.userId, service: username) ?? "" if AppConfig.DEBUG{ print("username: \(username) | userId: \(userId)")} } }