import Foundation import SwiftData import UIKit @MainActor final class BookDetailViewModel: ObservableObject { @Published var book: BookRemote @Published var isInLibrary = false init(book: BookRemote) { self.book = book } func refresh(context: ModelContext) { let all = (try? context.fetch(FetchDescriptor())) ?? [] isInLibrary = all.contains(where: { local in match(local: local, remote: book) }) } func toggleLibrary(context: ModelContext) { let all = (try? context.fetch(FetchDescriptor())) ?? [] if let existing = all.first(where: { match(local: $0, remote: book) }) { context.delete(existing) isInLibrary = false UINotificationFeedbackGenerator().notificationOccurred(.warning) } else { let local = LibraryBook( title: book.title, authorsString: book.authors.joined(separator: ", "), coverUrlString: book.coverImageUrl?.absoluteString, isbn10: book.isbn10, isbn13: book.isbn13, publishedYear: book.publishedYear, categoriesString: book.categories.joined(separator: ", "), summary: book.description, language: book.language, sourceLocale: book.sourceLocale, remotePayloadJson: nil, statusRaw: (book.readingStatus ?? .wantToRead).rawValue, readingProgress: book.readingProgress ?? 0 ) context.insert(local) isInLibrary = true UINotificationFeedbackGenerator().notificationOccurred(.success) } try? context.save() } private func match(local: LibraryBook, remote: BookRemote) -> Bool { if let lhs = local.isbn13, let rhs = remote.isbn13 { return lhs == rhs } if let lhs = local.isbn10, let rhs = remote.isbn10 { return lhs == rhs } return local.title == remote.title } }