InvestmentTrackerApp/PortfolioJournal/Services/AccountStore.swift

86 lines
2.5 KiB
Swift

import Foundation
import Combine
import CoreData
@MainActor
class AccountStore: ObservableObject {
@Published private(set) var accounts: [Account] = []
@Published var selectedAccount: Account?
@Published var showAllAccounts = true
private let accountRepository: AccountRepository
private let iapService: IAPService
private var cancellables = Set<AnyCancellable>()
init(
accountRepository: AccountRepository? = nil,
iapService: IAPService
) {
self.accountRepository = accountRepository ?? AccountRepository()
self.iapService = iapService
self.accountRepository.fetchAccounts()
let defaultAccount = self.accountRepository.createDefaultAccountIfNeeded()
accounts = self.accountRepository.accounts
selectedAccount = defaultAccount
loadSelection()
setupObservers()
}
private func setupObservers() {
accountRepository.$accounts
.receive(on: DispatchQueue.main)
.sink { [weak self] accounts in
self?.accounts = accounts
self?.syncSelectedAccount()
}
.store(in: &cancellables)
}
private func loadSelection() {
let context = CoreDataStack.shared.viewContext
let settings = AppSettings.getOrCreate(in: context)
showAllAccounts = settings.showAllAccounts
if let selectedId = settings.selectedAccountId,
let account = accountRepository.fetchAccount(by: selectedId) {
selectedAccount = account
} else {
selectedAccount = accounts.first
}
}
private func syncSelectedAccount() {
if showAllAccounts { return }
if let selected = selectedAccount,
accounts.contains(where: { $0.id == selected.id }) {
return
}
selectedAccount = accounts.first
}
func selectAllAccounts() {
showAllAccounts = true
persistSelection()
}
func selectAccount(_ account: Account) {
showAllAccounts = false
selectedAccount = account
persistSelection()
}
func persistSelection() {
let context = CoreDataStack.shared.viewContext
let settings = AppSettings.getOrCreate(in: context)
settings.showAllAccounts = showAllAccounts
settings.selectedAccountId = showAllAccounts ? nil : selectedAccount?.id
CoreDataStack.shared.save()
}
func canAddAccount() -> Bool {
iapService.isPremium || accounts.count < 1
}
}