//
//  HealthKitHelper.swift
//  Werkout_ios
//
//  Created by Trey Tartt on 8/13/23.
//

import Foundation
import HealthKit

struct HealthKitWorkoutData {
    var caloriesBurned: Double?
    var minHeartRate: Double?
    var maxHeartRate: Double?
    var avgHeartRate: Double?
}

class HealthKitHelper {
    // this is dirty and i dont care
    var returnCount = 0
    let healthStore = HKHealthStore()
    
    var healthKitWorkoutData = HealthKitWorkoutData(
        caloriesBurned: nil,
        minHeartRate: nil,
        maxHeartRate: nil,
        avgHeartRate: nil)
    
    var completion: ((HealthKitWorkoutData) -> Void)?
    
    func getDetails(forHealthKitUUID uuid: UUID, completion: @escaping ((HealthKitWorkoutData) -> Void)) {
        self.completion = completion
        self.returnCount = 0
        
        print("get details \(uuid.uuidString)")
        
        let predicate = HKQuery.predicateForObject(with: uuid)
        let query = HKSampleQuery(sampleType: HKWorkoutType.workoutType(),
                                  predicate: predicate,
                                  limit: 0,
                                  sortDescriptors: nil)
        { (sampleQuery, results, error ) -> Void in
            
            if let queryError = error {
                self.shitReturned()
                self.shitReturned()
                print( "There was an error while reading the samples: \(queryError.localizedDescription)")
            } else {
                for samples: HKSample in results! {
                    let workout: HKWorkout = (samples as! HKWorkout)
                    self.getTotalBurned(forWorkout: workout)
                    self.getHeartRateStuff(forWorkout: workout)
                    print("got workout")
                }
            }
        }
        healthStore.execute(query)
    }
    
    func getHeartRateStuff(forWorkout workout: HKWorkout) {
        print("get heart")
        let heartType = HKQuantityType.quantityType(forIdentifier: .heartRate)
        let heartPredicate: NSPredicate? = HKQuery.predicateForSamples(withStart: workout.startDate,
                                                                       end: workout.endDate,
                                                                       options: HKQueryOptions.strictEndDate)
        
        let heartQuery = HKStatisticsQuery(quantityType: heartType!,
                                           quantitySamplePredicate: heartPredicate,
                                           options: [.discreteAverage, .discreteMin, .discreteMax],
                                           completionHandler: {(query: HKStatisticsQuery, result: HKStatistics?, error: Error?) -> Void in
            if let result = result,
               let minValue = result.minimumQuantity(),
               let maxValue = result.maximumQuantity(),
               let avgValue = result.averageQuantity() {
                
                let _minHeartRate = minValue.doubleValue(
                    for: HKUnit(from: "count/min")
                )
                
                let _maxHeartRate = maxValue.doubleValue(
                    for: HKUnit(from: "count/min")
                )
                
                let _avgHeartRate = avgValue.doubleValue(
                    for: HKUnit(from: "count/min")
                )
                self.healthKitWorkoutData.avgHeartRate = _avgHeartRate
                self.healthKitWorkoutData.minHeartRate = _minHeartRate
                self.healthKitWorkoutData.maxHeartRate = _maxHeartRate
                print("got heart")
            }
            self.shitReturned()
        })
        healthStore.execute(heartQuery)
    }
    
    func getTotalBurned(forWorkout workout: HKWorkout) {
        print("get total burned")
        let calType = HKQuantityType.quantityType(forIdentifier: .activeEnergyBurned)
        let calPredicate: NSPredicate? = HKQuery.predicateForSamples(withStart: workout.startDate,
                                                                     end: workout.endDate,
                                                                     options: HKQueryOptions.strictEndDate)
        
        let calQuery = HKStatisticsQuery(quantityType: calType!,
                                         quantitySamplePredicate: calPredicate,
                                         options: [.cumulativeSum],
                                         completionHandler: {(query: HKStatisticsQuery, result: HKStatistics?, error: Error?) -> Void in
            if let result = result {
                self.healthKitWorkoutData.caloriesBurned = result.sumQuantity()?.doubleValue(for: HKUnit.kilocalorie()) ?? -1
                print("got total burned")
            }
            self.shitReturned()
        })
        healthStore.execute(calQuery)
    }
    
    func shitReturned() {
        DispatchQueue.main.async {
            self.returnCount += 1
            print("\(self.returnCount)")
            if self.returnCount == 2 {
                self.completion?(self.healthKitWorkoutData)
            }
        }
    }
}
