package com.syaroful.agrilinkvocpro.presentation.screen.detail

import android.util.Log
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.syaroful.agrilinkvocpro.core.utils.ResultState
import com.syaroful.agrilinkvocpro.core.utils.extention.mapToUserFriendlyError
import com.syaroful.agrilinkvocpro.core.utils.extention.toFormattedString
import com.syaroful.agrilinkvocpro.data.UserPreferences
import com.syaroful.agrilinkvocpro.data.model.DhtGraphicDataResponse
import com.syaroful.agrilinkvocpro.data.model.NpkGraphicDataResponse
import com.syaroful.agrilinkvocpro.data.model.SensorDataResponse
import com.syaroful.agrilinkvocpro.data.repository.SensorDataRepository
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.launch
import java.util.Date


private const val TAG = "DetailViewModel"

class DetailViewModel(
    private val sensorDataRepository: SensorDataRepository,
    private val userPreferences: UserPreferences
) : ViewModel() {

    val currentSensorData: SensorDataResponse?
        get() = sensorDataRepository.latestSensorData

    private val _npkDataState = MutableStateFlow<ResultState<NpkGraphicDataResponse>>(ResultState.Idle)
    val npkDataState: StateFlow<ResultState<NpkGraphicDataResponse>> = _npkDataState.asStateFlow()

    private val _dhtDataState = MutableStateFlow<ResultState<DhtGraphicDataResponse>>(ResultState.Idle)
    val dhtDataState: StateFlow<ResultState<DhtGraphicDataResponse>> = _dhtDataState.asStateFlow()

    private val today = Date()

    fun fetchNpkData(
        date: String = today.toFormattedString(),
        sensor: String,
    ) {
        viewModelScope.launch {
            _npkDataState.value = ResultState.Loading
            val token = userPreferences.tokenFlow.first()
            val authHeader = "Bearer $token"
            try {
                delay(1000L)
                val response = sensorDataRepository.getNpkDataSensor(
                    authHeader = authHeader,
                    startDate = date,
                    endDate = date,
                    timeRange = "HOURLY",
                    sensor = sensor
                )
                if (response.isSuccessful) {
                    response.body()?.let { body ->
                        _npkDataState.value = ResultState.Success(body)
                    } ?: run {
                        _npkDataState.value = ResultState.Error("Data tidak ditemukan")
                    }
                } else {
                    _npkDataState.value = ResultState.Error("Error: ${response.code()} - ${response.message()}")
                }
            } catch (e: Exception) {
                val errorMessage = mapToUserFriendlyError(e)
                _npkDataState.value = ResultState.Error(errorMessage)
                Log.d(TAG, "Failed to fetch data: ${e.message}")
            }
        }
    }

    fun fetchDhtData(
        date: String = today.toFormattedString(),
        sensor: String,
    ) {
        viewModelScope.launch {
            _dhtDataState.value = ResultState.Loading
            val token = userPreferences.tokenFlow.first()
            val authHeader = "Bearer $token"
            try {
                delay(1000L)
                val response = sensorDataRepository.getDhtDataSensor(
                    authHeader = authHeader,
                    startDate = date,
                    endDate = date,
                    timeRange = "HOURLY",
                    sensor = sensor
                )
                if (response.isSuccessful) {
                    response.body()?.let { body ->
                        _dhtDataState.value = ResultState.Success(body)
                    } ?: run {
                        _dhtDataState.value = ResultState.Error("Data tidak ditemukan")
                    }
                } else {
                    _dhtDataState.value = ResultState.Error("Error: ${response.code()} - ${response.message()}")
                }
            } catch (e: Exception) {
                val errorMessage = mapToUserFriendlyError(e)
                _dhtDataState.value = ResultState.Error(errorMessage)
                Log.d(TAG, "Failed to fetch data: ${e.message}")
            }
        }
    }
}