Files
InvestmentTrackerApp/PortfolioJournal/Services/AccountStore.swift
T
2026-01-19 14:40:43 +01:00

114 lines
3.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
// Clean up any duplicate Default accounts from previous bug
self.accountRepository.cleanupDuplicateDefaultAccounts()
// Create default account if needed (now fetches directly from DB)
let defaultAccount = self.accountRepository.createDefaultAccountIfNeeded()
// Trigger async fetch to populate the published accounts array
self.accountRepository.fetchAccounts()
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
if let selected = self?.selectedAccount, selected.isDeleted {
self?.selectedAccount = nil
}
self?.syncSelectedAccount()
}
.store(in: &cancellables)
NotificationCenter.default.publisher(for: .didResetData)
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in
guard let self else { return }
self.accountRepository.fetchAccounts()
self.selectedAccount = nil
self.showAllAccounts = true
self.persistSelection()
}
.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 selectedId = selectedAccount?.safeId,
accounts.contains(where: { $0.safeId == selectedId }) {
return
}
selectedAccount = accounts.first
}
func selectAllAccounts() {
showAllAccounts = true
selectedAccount = nil
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?.safeId
CoreDataStack.shared.save()
}
func canAddAccount() -> Bool {
iapService.isPremium || accounts.count < 1
}
}
extension Account {
var safeId: UUID? {
guard !isDeleted else { return nil }
return value(forKey: "id") as? UUID
}
}