import Foundation
import CoreData

/// Per-source recurring monthly contribution amount.
///
/// Backed by the `InvestmentSource.monthlyContribution` Core Data attribute so the value
/// syncs across devices via iCloud/CloudKit. Previously stored in `UserDefaults`, which is
/// device-local and did NOT sync — `migrateIfNeeded(context:)` moves any legacy value over.
enum MonthlyContributionStore {
    /// Legacy UserDefaults key (pre-iCloud). Only read once during migration.
    private static let legacyKey = "monthlyContributions"

    private static var viewContext: NSManagedObjectContext { CoreDataStack.shared.viewContext }

    static func contribution(for sourceId: UUID) -> Decimal? {
        guard let source = fetchSource(sourceId),
              let amount = source.monthlyContribution?.decimalValue,
              amount > 0 else { return nil }
        return amount
    }

    static func setContribution(_ amount: Decimal?, for sourceId: UUID) {
        guard let source = fetchSource(sourceId) else { return }
        if let amount, amount > 0 {
            source.monthlyContribution = NSDecimalNumber(decimal: amount)
        } else {
            source.monthlyContribution = nil
        }
        try? viewContext.save()
    }

    private static func fetchSource(_ id: UUID) -> InvestmentSource? {
        let request = InvestmentSource.fetchRequest()
        request.predicate = NSPredicate(format: "id == %@", id as CVarArg)
        request.fetchLimit = 1
        return try? viewContext.fetch(request).first
    }

    // MARK: - Migration

    /// One-time migration of legacy UserDefaults contributions into Core Data so they sync
    /// via iCloud. Runs on every launch but is a no-op once the legacy key is cleared.
    static func migrateIfNeeded(context: NSManagedObjectContext) {
        guard let data = UserDefaults.standard.data(forKey: legacyKey),
              let dict = try? JSONDecoder().decode([String: Double].self, from: data),
              !dict.isEmpty else { return }

        let sources = (try? context.fetch(InvestmentSource.fetchRequest())) ?? []
        var changed = false
        for source in sources where source.monthlyContribution == nil {
            if let raw = dict[source.id.uuidString], raw > 0 {
                source.monthlyContribution = NSDecimalNumber(value: raw)
                changed = true
            }
        }
        if changed { try? context.save() }
        UserDefaults.standard.removeObject(forKey: legacyKey)
    }
}
