import SwiftData
import SharedModels
import Foundation

@Model
final class UserProgress {
    var id: String = "main"
    var dailyGoal: Int = 50
    var todayCount: Int = 0
    var todayDate: String = ""
    var currentStreak: Int = 0
    var longestStreak: Int = 0
    var totalReviewed: Int = 0
    var selectedLevel: String = "basic"
    var showVosotros: Bool = true
    var autoFillStem: Bool = false

    // Legacy CloudKit array-backed fields retained for migration compatibility.
    var enabledTenses: [String] = []
    var unlockedBadges: [String] = []
    var enabledTensesBlob: String = ""
    var unlockedBadgesBlob: String = ""

    init() {}

    var selectedVerbLevel: VerbLevel {
        get { VerbLevel(rawValue: selectedLevel) ?? .basic }
        set { selectedLevel = newValue.rawValue }
    }

    var enabledTenseIDs: [String] {
        get { decodeStringArray(from: enabledTensesBlob, fallback: enabledTenses) }
        set {
            enabledTensesBlob = Self.encodeStringArray(newValue)
            enabledTenses = []
        }
    }

    var unlockedBadgeIDs: [String] {
        get { decodeStringArray(from: unlockedBadgesBlob, fallback: unlockedBadges) }
        set {
            unlockedBadgesBlob = Self.encodeStringArray(newValue)
            unlockedBadges = []
        }
    }

    func setTenseEnabled(_ tenseId: String, enabled: Bool) {
        var values = Set(enabledTenseIDs)
        if enabled {
            values.insert(tenseId)
        } else {
            values.remove(tenseId)
        }
        enabledTenseIDs = values.sorted()
    }

    func unlockBadge(_ badgeId: String) {
        var values = Set(unlockedBadgeIDs)
        values.insert(badgeId)
        unlockedBadgeIDs = values.sorted()
    }

    func migrateLegacyStorageIfNeeded() {
        if enabledTensesBlob.isEmpty && !enabledTenses.isEmpty {
            enabledTenseIDs = enabledTenses
        }
        if unlockedBadgesBlob.isEmpty && !unlockedBadges.isEmpty {
            unlockedBadgeIDs = unlockedBadges
        }
    }

    private func decodeStringArray(from blob: String, fallback: [String]) -> [String] {
        guard !blob.isEmpty,
              let data = blob.data(using: .utf8),
              let values = try? JSONDecoder().decode([String].self, from: data) else {
            return fallback
        }
        return values
    }

    private static func encodeStringArray(_ values: [String]) -> String {
        let normalized = Array(Set(values)).sorted()
        guard let data = try? JSONEncoder().encode(normalized),
              let string = String(data: data, encoding: .utf8) else {
            return "[]"
        }
        return string
    }
}
