//
//  SleepSummaryToDictionaryMapper.swift
//  Plugin
//
//  Created by Francisco Guerrero Escamilla on 07/10/25.
//  Copyright © 2025 Max Lynch. All rights reserved.
//

import Foundation
import RookSDK

struct SleepSummaryToDictionaryMapper {

  // MARK:  Properties

  private let dateHelper: DateHelper = DateHelper()

  // MARK:  Implementation

  func map(_ summary: RookSleepSummary) -> [String: Any?] {
    var dictionary: [String : Any?] = [:]
    dictionary.updateValue(dateHelper.getISO8601StringDate(date: summary.datetime), forKey: "datetime")
    dictionary.updateValue(summary.sourceOfData, forKey: "sourceOfData")
    dictionary.updateValue(summary.sleepHealthScore, forKey: "sleepHealthScore")
    dictionary.updateValue(dateHelper.getISO8601StringDate(date: summary.sleepStartDatetime), forKey: "sleepStartDatetime")
    dictionary.updateValue(dateHelper.getISO8601StringDate(date: summary.sleepEndDatetime), forKey: "sleepEndDatetime")
    dictionary.updateValue(dateHelper.getISO8601StringDate(date: summary.sleepEndDatetime), forKey: "sleepDate")
    dictionary.updateValue(summary.sleepDurationSeconds, forKey: "sleepDurationSeconds")
    dictionary.updateValue(summary.timeInBedSeconds, forKey: "timeInBedSeconds")
    dictionary.updateValue(summary.lightSleepDurationSeconds, forKey: "lightSleepDurationSeconds")
    dictionary.updateValue(summary.remSleepDurationSeconds, forKey: "remSleepDurationSeconds")
    dictionary.updateValue(summary.deepSleepDurationSeconds, forKey: "deepSleepDurationSeconds")
    dictionary.updateValue(summary.timeToFallAsleepSeconds, forKey: "timeToFallAsleepSeconds")
    dictionary.updateValue(summary.timeAwakeDuringSleepSeconds, forKey: "timeAwakeDuringSleepSeconds")
    dictionary.updateValue(summary.sleepQualityRating1_5_Score, forKey: "sleepQualityRating1_5_Score")
    dictionary.updateValue(summary.sleepEfficiency1_100_Score, forKey: "sleepEfficiency1_100_Score")
    dictionary.updateValue(summary.sleepGoalSeconds, forKey: "sleepGoalSeconds")
    dictionary.updateValue(summary.sleepContinuity1_5_Score, forKey: "sleepContinuity1_5_Score")
    dictionary.updateValue(summary.sleepContinuity1_5_Rating, forKey: "sleepContinuity1_5_Rating")
    dictionary.updateValue(summary.hrMaxBPM, forKey: "hrMaxBPM")
    dictionary.updateValue(summary.hrMinimumBPM, forKey: "hrMinimumBPM")
    dictionary.updateValue(summary.hrAvgBPM, forKey: "hrAvgBPM")
    dictionary.updateValue(summary.hrRestingBPM, forKey: "hrRestingBPM")
    dictionary.updateValue(summary.hrBasalBPM, forKey: "hrBasalBPM")
    dictionary.updateValue(
      summary.hrGranularDataBPM?.map({
        [
          "dateTime": dateHelper.getISO8601StringDate(date: $0.dateTime),
          "hrBPM": $0.hrBPM
        ]
      }),
      forKey: "hrGranularDataBPM")
    dictionary.updateValue(summary.hrvAvgRmssdNumber, forKey: "hrvAvgRmssdNumber")
    dictionary.updateValue(summary.hrvAvgSdnnNumber, forKey: "hrvAvgSdnnNumber")
    dictionary.updateValue(summary.hrvSdnnGranularData?.map({
      [
        "dateTime": dateHelper.getISO8601StringDate(date: $0.dateTime),
        "hrvSDNN": $0.hrvSDNN
      ]
    }), forKey: "hrvSdnnGranularData")
    dictionary.updateValue(summary.hrvRmssdGranularData?.map({
      [
        "dateTime": dateHelper.getISO8601StringDate(date: $0.dateTime),
        "hrvRmssd": $0.hrvRmssd
      ]
    }), forKey: "hrvRmssdGranularData")
    dictionary.updateValue(mapTemperature(summary.temperatureMinimumCelsius), forKey: "temperatureMinimumCelsius")
    dictionary.updateValue(mapTemperature(summary.temperatureAvgCelsius), forKey: "temperatureAvgCelsius")
    dictionary.updateValue(mapTemperature(summary.temperatureMaxCelsius), forKey: "temperatureMaxCelsius")
    dictionary.updateValue(summary.temperatureGranularDataCelsius?.map({
      [
        "dateTime": dateHelper.getISO8601StringDate(date: $0.dateTime),
        "temperatureCelsius": $0.temperatureCelsius,
        "measurementType": $0.measurementType,
      ]
    }), forKey: "temperatureGranularDataCelsius")
    dictionary.updateValue(mapTemperature(summary.temperatureDeltaCelsius), forKey: "temperatureDeltaCelsius")
    dictionary.updateValue(summary.breathsMinimumPerMin, forKey: "breathsMinimumPerMin")
    dictionary.updateValue(summary.breathsAvgPerMin, forKey: "breathsAvgPerMin")
    dictionary.updateValue(summary.breathsMaxPerMin, forKey: "breathsMaxPerMin")
    dictionary.updateValue(summary.breathingGranularDataBreathsPerMin?.map({
      [
        "dateTime": dateHelper.getISO8601StringDate(date: $0.dateTime),
        "breathsPerMin": $0.breathsPerMin
      ]
    }), forKey: "breathingGranularDataBreathsPerMin")
    dictionary.updateValue(summary.snoringEventsCountNumber, forKey: "snoringEventsCountNumber")
    dictionary.updateValue(summary.snoringDurationTotalSeconds, forKey: "snoringDurationTotalSeconds")
    dictionary.updateValue(summary.snoringGranularDataSnores?.map({
      [
        "dateTime": dateHelper.getISO8601StringDate(date: $0.dateTime),
        "intervalDurationSeconds": $0.intervalDurationSeconds,
        "snoringEventsCountNumber": $0.snoringEventsCountNumber
      ]
    }), forKey: "snoringGranularDataSnores")
    dictionary.updateValue(summary.saturationAvgPercentage, forKey: "saturationAvgPercentage")
    dictionary.updateValue(summary.saturationGranularDataPercentage?.map({
      [
        "dateTime": dateHelper.getISO8601StringDate(date: $0.dateTime),
        "saturationPercentage": $0.saturationPercentage
      ]
    }), forKey: "saturationGranularDataPercentage")
    dictionary.updateValue(summary.saturationMinPercentage, forKey: "saturationMinPercentage")
    dictionary.updateValue(summary.saturationMaxPercentage, forKey: "saturationMaxPercentage")
    dictionary.updateValue(summary.apneaEvents?.map({
      [
        "startDate": dateHelper.getISO8601StringDate(date: $0.startDate),
        "endDate": dateHelper.getISO8601StringDate(date: $0.endDate),
        "duration": $0.duration,
        "appleValue": $0.appleValue
      ]
    }), forKey: "apneaEvents")
    dictionary.updateValue(summary.sleepSamples?.map({
      [
        "startDate": dateHelper.getISO8601StringDate(date: $0.startDate),
        "endDate": dateHelper.getISO8601StringDate(date: $0.endDate),
        "duration": $0.duration,
        "zone": $0.zone
      ]
    }), forKey: "sleepSamples")
    dictionary.updateValue(summary.maxWristTemperature, forKey: "maxWristTemperature")
    dictionary.updateValue(summary.minWristTemperature, forKey: "minWristTemperature")
    dictionary.updateValue(summary.averageWristTemperature, forKey: "averageWristTemperature")
    dictionary.updateValue(summary.granularWristTemperatureData?.map({
      [
        "startDate": dateHelper.getISO8601StringDate(date: $0.startDate),
        "endDate": dateHelper.getISO8601StringDate(date: $0.endDate),
        "value": $0.value,
      ]
    }), forKey: "granularWristTemperatureData")
    return dictionary
  }

  private func mapTemperature(_ object: [RookTemperature]?) -> [String: Any]? {
    if let item: RookTemperature = object?.first {
      return [
        "temperatureCelsius": item.temperatureCelsius,
        "measurementType": item.measurementType
      ]
    } else {
      return nil
    }
  }
}
