package com.rookandroidtransmission.transformations import com.facebook.react.bridge.ReadableArray import com.facebook.react.bridge.ReadableMap import com.rookmotion.rook.transmission.domain.model.granular.BreathingGranularDataBreathsPerMinItem import com.rookmotion.rook.transmission.domain.model.granular.HrGranularDataBpmItem import com.rookmotion.rook.transmission.domain.model.granular.HrvRmssdGranularDataNumberItem import com.rookmotion.rook.transmission.domain.model.granular.HrvSdnnGranularDataNumberItem import com.rookmotion.rook.transmission.domain.model.granular.SaturationGranularDataPercentageItem import com.rookmotion.rook.transmission.domain.model.granular.SnoringGranularDataSnoresItem import com.rookmotion.rook.transmission.domain.model.granular.TemperatureGranularDataCelsiusItem import com.rookmotion.rook.transmission.domain.model.granular.TemperatureItem import com.rookmotion.rook.transmission.domain.model.summary.SleepSummaryItem import java.lang.reflect.ParameterizedType import java.time.LocalDate import java.time.LocalDateTime import java.time.ZonedDateTime object EncodeSleepSummaryItem { fun fromReadableMap(readableMap: ReadableMap): SleepSummaryItem { val clazz = SleepSummaryItem::class.java val instance = SleepSummaryItem( dateTime = ZonedDateTime.now(), sourceOfData= "HC", sleepStartDateTime= ZonedDateTime.now(), sleepEndDateTime= ZonedDateTime.now(), sleepDate= LocalDate.now(), ) var keys = readableMap.keySetIterator() while (keys.hasNextKey()) { val fieldName = keys.nextKey() val fieldValue = readableMap.getDynamic(fieldName) try { val field = clazz.getDeclaredField(fieldName) field.isAccessible = true when { field.type == String::class.java -> field.set(instance, fieldValue.asString()) field.type == Integer::class.java-> field.set(instance, fieldValue.asInt()) field.type == Int::class.java -> field.set(instance, fieldValue.asInt()) field.type == Double::class.java -> field.set(instance, fieldValue.asDouble()) field.type == Double::class.javaObjectType -> field.set(instance, fieldValue.asDouble()) field.type == Boolean::class.java -> field.set(instance, fieldValue.asBoolean()) field.type == Boolean::class.javaObjectType -> field.set(instance, fieldValue.asBoolean()) field.type == ZonedDateTime::class.java -> field.set(instance, RookDateTimeUtils.stringToZonedDateTime(fieldValue.asString())) field.type == LocalDate::class.java -> field.set(instance, RookDateTimeUtils.stringToLocalDate(fieldValue.asString())) field.type == TemperatureItem::class.java -> { val rawTemperatureItem = fieldValue.asMap() field.set(instance, TemperatureItem( temperatureCelsius = rawTemperatureItem.getDouble("temperatureCelsius"), measurementType = rawTemperatureItem.getString("measurementType") ?: "" )) } field.type == List::class.java && field.genericType is ParameterizedType -> { val genericType = field.genericType as ParameterizedType field.set(instance, parseList(fieldValue.asArray(), genericType)) } } } catch (e: NoSuchFieldException) { println("El campo $fieldName no existe en la clase SleepSummaryItem") } } return instance } private fun parseList(array: ReadableArray, genericType: ParameterizedType): List? { if (genericType.actualTypeArguments.first() == HrGranularDataBpmItem::class.java) { return fromReadableArrayToGranularDataBPM(array) } if (genericType.actualTypeArguments.first() == HrvSdnnGranularDataNumberItem::class.java) { return fromReadableArrayToGranularDataNumber(array) } if (genericType.actualTypeArguments.first() == HrvRmssdGranularDataNumberItem::class.java) { return fromReadableArrayToHrvRmssdGranularDataNumberItem(array) } if (genericType.actualTypeArguments.first() == TemperatureGranularDataCelsiusItem::class.java) { return fromReadableArrayToTemperatureGranularDataCelsiusItem(array) } if (genericType.actualTypeArguments.first() == BreathingGranularDataBreathsPerMinItem::class.java) { return fromReadableArrayToBreathingGranularDataBreathsPerMinItem(array) } if (genericType.actualTypeArguments.first() == SnoringGranularDataSnoresItem::class.java) { return fromReadableArrayToSnoringGranularDataSnoresItem(array) } if (genericType.actualTypeArguments.first() == SaturationGranularDataPercentageItem::class.java) { return fromReadableArrayToSaturationGranularDataPercentageItem(array) } return null } private fun fromReadableArrayToGranularDataBPM(readableArray: ReadableArray): List { val data: MutableList = mutableListOf() for (i in 0 until readableArray.size()) { val rawItem = readableArray.getMap(i); val bpmItem = HrGranularDataBpmItem( hrBpm = rawItem.getInt("hrBpm"), dateTime = RookDateTimeUtils.stringToZonedDateTime(rawItem.getString("dateTime") ?: "2023-01-01") ) data.add(bpmItem) } return data } private fun fromReadableArrayToGranularDataNumber(readableArray: ReadableArray): List { val data: MutableList = mutableListOf() for (i in 0 until readableArray.size()) { val rawItem = readableArray.getMap(i); val bpmItem = HrvSdnnGranularDataNumberItem( hrvSdnn = rawItem.getDouble("hrvSdnn"), dateTime = RookDateTimeUtils.stringToZonedDateTime(rawItem.getString("dateTime") ?: "2023-01-01") ) data.add(bpmItem) } return data } private fun fromReadableArrayToHrvRmssdGranularDataNumberItem(readableArray: ReadableArray): List { val data: MutableList = mutableListOf() for (i in 0 until readableArray.size()) { val rawItem = readableArray.getMap(i); val bpmItem = HrvRmssdGranularDataNumberItem( hrvRmssd = rawItem.getDouble("hrvSdnn"), dateTime = RookDateTimeUtils.stringToZonedDateTime(rawItem.getString("dateTime") ?: "2023-01-01") ) data.add(bpmItem) } return data } private fun fromReadableArrayToTemperatureGranularDataCelsiusItem(readableArray: ReadableArray): List { val data: MutableList = mutableListOf() for (i in 0 until readableArray.size()) { val rawItem = readableArray.getMap(i); val bpmItem = TemperatureGranularDataCelsiusItem( dateTime = RookDateTimeUtils.stringToZonedDateTime(rawItem.getString("dateTime") ?: "2023-01-01"), temperatureCelsius = rawItem.getDouble("temperatureCelsius"), measurementType = rawItem.getString("measurementType") ?: "" ) data.add(bpmItem) } return data } private fun fromReadableArrayToBreathingGranularDataBreathsPerMinItem(readableArray: ReadableArray): List { val data: MutableList = mutableListOf() for (i in 0 until readableArray.size()) { val rawItem = readableArray.getMap(i); val bpmItem = BreathingGranularDataBreathsPerMinItem( dateTime = RookDateTimeUtils.stringToZonedDateTime(rawItem.getString("dateTime") ?: "2023-01-01"), breathsPerMin = rawItem.getDouble("temperatureCelsius") ) data.add(bpmItem) } return data } private fun fromReadableArrayToSnoringGranularDataSnoresItem(readableArray: ReadableArray): List { val data: MutableList = mutableListOf() for (i in 0 until readableArray.size()) { val rawItem = readableArray.getMap(i); val bpmItem = SnoringGranularDataSnoresItem( dateTime = RookDateTimeUtils.stringToZonedDateTime(rawItem.getString("dateTime") ?: "2023-01-01"), intervalDurationSeconds = rawItem.getInt("intervalDurationSeconds"), snoringEventsCountNumber = rawItem.getInt("snoringEventsCountNumber") ) data.add(bpmItem) } return data } private fun fromReadableArrayToSaturationGranularDataPercentageItem(readableArray: ReadableArray): List { val data: MutableList = mutableListOf() for (i in 0 until readableArray.size()) { val rawItem = readableArray.getMap(i); val bpmItem = SaturationGranularDataPercentageItem( dateTime = RookDateTimeUtils.stringToZonedDateTime(rawItem.getString("dateTime") ?: "2023-01-01"), saturationPercentage = rawItem.getDouble("saturationPercentage"), ) data.add(bpmItem) } return data } }