package com.github.bmx666.appcachecleaner.ui.viewmodel

import android.content.Context
import android.os.Build
import androidx.annotation.RequiresApi
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.github.bmx666.appcachecleaner.R
import com.github.bmx666.appcachecleaner.data.PackageRepository
import com.github.bmx666.appcachecleaner.util.toFormattedString
import dagger.hilt.android.lifecycle.HiltViewModel
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import org.springframework.util.unit.DataSize
import javax.inject.Inject


@HiltViewModel
class CleanResultViewModel @Inject constructor(
    private val repo: PackageRepository,
    @param:ApplicationContext private val context: Context,
): ViewModel()
{
    private val _isInterruptedBySystem = MutableStateFlow(false)
    val isInterruptedBySystem: StateFlow<Boolean> = _isInterruptedBySystem

    private val _actions = MutableStateFlow(false)
    val actions: StateFlow<Boolean> = _actions

    var titleText by mutableStateOf("")

    fun resetTitle() {
        titleText = ""
    }

    fun finishClearCache(interrupted: Boolean) {
        val resId =
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                when (interrupted) {
                    true -> R.string.text_clean_cache_interrupt_processing
                    else -> R.string.text_clean_cache_finish_processing
                }
            } else {
                when (interrupted) {
                    true -> R.string.text_clean_cache_interrupt
                    else -> R.string.text_clean_cache_finish
                }
            }

        titleText = context.getString(resId)

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
            calculateCleanedCache(interrupted)

        if (!interrupted)
            _actions.value = true
    }

    fun finishClearData(interrupted: Boolean) {
        val resId =
            when (interrupted) {
                true -> R.string.text_clean_data_interrupt
                else -> R.string.text_clean_data_finish
            }

        titleText = context.getString(resId)

        if (!interrupted)
            _actions.value = true
    }

    fun resetActions() {
        _actions.value = false
    }

    fun showInterruptedBySystemDialog() {
        _isInterruptedBySystem.value = true
    }

    fun resetInterruptedBySystemDialog() {
        _isInterruptedBySystem.value = false
    }

    @RequiresApi(Build.VERSION_CODES.O)
    private fun calculateCleanedCache(interrupted: Boolean) {
        viewModelScope.launch(Dispatchers.IO) {
            try {
                // Re-reads checked packages' stats (after a settle delay) and writes
                // the fresh sizes back into the warm master list, returning bytes cleaned.
                val cleanedCacheBytes = repo.refreshStatsAfterCacheClean()
                val sizeStr = DataSize.ofBytes(cleanedCacheBytes)
                    .toFormattedString(context)

                val resId = when (interrupted) {
                    true -> R.string.text_clean_cache_interrupt_display_size
                    else -> R.string.text_clean_cache_finish_display_size
                }

                titleText = context.getString(resId, sizeStr)
            } finally {
            }
        }
    }
}