import Foundation
import SwiftData

// Interface updated 2026-05-17 — see AGENTS.md
@Model final class TypeCount {
    var id: UUID = UUID()
    var typeIdentifier: String = ""
    var displayName: String = ""
    var count: Int = 0
    var contentHash: String = ""
    var earliestDate: Date?
    var latestDate: Date?
    var qualityRaw: String = SnapshotQuality.complete.rawValue
    var isUnsupported: Bool = false
    var contentEquivalentTypeCountID: UUID?
    @Attribute(.externalStorage) var recordArchiveData: Data?
    @Attribute(.externalStorage) var detailCacheData: Data?
    @Attribute(.externalStorage) var yearlyCountsData: Data?
    @Attribute(.externalStorage) var distributionBinsData: Data?
    var snapshot: HealthSnapshot?

    init(typeIdentifier: String, displayName: String, count: Int, quality: SnapshotQuality = .complete) {
        self.id = UUID()
        self.typeIdentifier = typeIdentifier
        self.displayName = displayName
        self.count = count
        self.qualityRaw = quality.rawValue
    }
}

extension TypeCount {
    private static let propertyListEncoder = PropertyListEncoder()
    private static let propertyListDecoder = PropertyListDecoder()

    var quality: SnapshotQuality {
        get { SnapshotQuality(rawValue: qualityRaw) ?? .complete }
        set { qualityRaw = newValue.rawValue }
    }

    var yearlyCounts: [YearlyCount]? {
        get {
            guard let yearlyCountsData else { return [] }
            return try? Self.propertyListDecoder.decode([YearlyCount].self, from: yearlyCountsData)
        }
        set {
            yearlyCountsData = try? Self.propertyListEncoder.encode(newValue ?? [])
        }
    }

    var distributionBins: [TypeDistributionBin]? {
        get {
            guard let distributionBinsData else { return [] }
            return try? Self.propertyListDecoder.decode([TypeDistributionBin].self, from: distributionBinsData)
        }
        set {
            distributionBinsData = try? Self.propertyListEncoder.encode(newValue ?? [])
        }
    }

    var recordValues: [HealthRecordValue] {
        if let recordArchiveData,
           let decoded = HealthRecordArchive.decode(recordArchiveData) {
            return decoded
        }

        return []
    }

    func setRecordValues(_ values: [HealthRecordValue]) {
        recordArchiveData = HealthRecordArchive.encode(values)
    }

    @MainActor var detailCache: TypeCountDetailCache? {
        guard let detailCacheData else { return nil }
        return TypeCountDetailCacheArchive.decode(detailCacheData)
    }

    @MainActor func setDetailCache(_ cache: TypeCountDetailCache?) {
        detailCacheData = cache.flatMap(TypeCountDetailCacheArchive.encode)
    }

    var isContentAlias: Bool {
        contentEquivalentTypeCountID != nil
    }

    var contentRepresentativeTypeCountID: UUID {
        contentEquivalentTypeCountID ?? id
    }
}
