import Foundation
import HealthKitExtensions
import HealthKit
import Charts

struct HRSample: Identifiable {
    
    let id = UUID()

    let startDate: Date

    let endDate: Date

    let min: Int

    let max: Int

    init(date: Date, duration: TimeInterval, min: Int, max: Int) {
        self.startDate = date
        self.endDate = date.addingTimeInterval(duration)
        self.min = min
        self.max = max
    }

    static func create(from samples: [HeartRate], start: Date, end: Date, categories: Int) -> [HRSample] {
        let interval = end.timeIntervalSince(start) / Double(categories)
        var categories: [HRSample] = []
        var categoryEndDuration = interval
        var minimum = Int.max
        var maximum = Int.min
        var hasSamplesInCategory = false

        let unit = HKUnit.count().unitDivided(by: .minute())

        func advanceToNextCategory() {
            defer { categoryEndDuration += interval }
            guard hasSamplesInCategory else {
                return
            }
            categories.append(.init(
                date: start.addingTimeInterval(categoryEndDuration - (interval * 0.48)),
                duration: interval * 0.96,
                min: minimum,
                max: maximum))
            minimum = Int.max
            maximum = Int.min
            hasSamplesInCategory = false
        }

        for sample in samples.sorted(ascending: true, using: { $0.startDate }) {
            let timestamp = sample.startDate.timeIntervalSince(start)
            while timestamp > categoryEndDuration {
                advanceToNextCategory()
            }
            let value = sample.quantity.doubleValue(for: unit).roundedInt
            minimum = Swift.min(minimum, value)
            maximum = Swift.max(maximum, value)
            hasSamplesInCategory = true
        }

        advanceToNextCategory()
        return categories
    }

    func test(start: Date, end: Date) {
        let duration = end.timeIntervalSince(start)
        let interval = DateComponents(second: Int(duration) / 20)

        let quantityType = HKObjectType.quantityType(
            forIdentifier: .heartRate
        )!

        let query = HKStatisticsCollectionQuery(
            quantityType: quantityType,
            quantitySamplePredicate: nil,
            options: [.discreteMax, .discreteMin],
            anchorDate: start,
            intervalComponents: interval
        )

        query.initialResultsHandler = { _, results, error in
            var weeklyData: [Date: (Double, Double)] = [:]

            results!.enumerateStatistics(
                from: start,
                to: end
            ) { statistics, _ in
                if let minValue = statistics.minimumQuantity() {
                    if let maxValue = statistics.maximumQuantity() {
                        let minHeartRate = minValue.doubleValue(
                            for: HKUnit(from: "count/min")
                        )
                        let maxHeartRate = maxValue.doubleValue(
                            for: HKUnit(from: "count/min")
                        )

                        weeklyData[statistics.startDate] = (
                            minHeartRate, maxHeartRate
                        )
                    }
                }
            }

            // use `weeklyData`
        }
    }
}
