package com.optix.android.util

import android.app.ActivityManager
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.BatteryManager
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import javax.inject.Inject
import javax.inject.Singleton

/**
 * Real-time device health state.
 *
 * @param batteryPercent  0–100, or -1 if unavailable
 * @param tempCelsius     Device temperature in °C (from battery sensor), or -1f
 * @param ramUsedMb       RAM currently used in MB
 * @param ramTotalMb      Total available RAM in MB
 */
data class HardwareState(
    val batteryPercent: Int    = -1,
    val tempCelsius:    Float  = -1f,
    val ramUsedMb:      Long   = 0L,
    val ramTotalMb:     Long   = 0L,
) {
    /** True when the device is running hot (> 40 °C). */
    val isHot: Boolean get() = tempCelsius > 40f

    /** True when battery is critically low (< 20 %). */
    val isBatteryLow: Boolean get() = batteryPercent in 0..19

    /** RAM utilisation 0.0 – 1.0. */
    val ramRatio: Float get() = if (ramTotalMb > 0) ramUsedMb / ramTotalMb.toFloat() else 0f

    /** True when more than 85 % of RAM is consumed. */
    val isRamCritical: Boolean get() = ramRatio > 0.85f
}

@Singleton
class HardwareMonitor @Inject constructor(
    @ApplicationContext private val context: Context,
) {
    companion object {
        private const val POLL_INTERVAL_MS = 2_500L
    }

    /** Continuously emits [HardwareState] every 2.5 seconds. */
    val state: Flow<HardwareState> = flow {
        val am = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
        val memInfo = ActivityManager.MemoryInfo()

        while (true) {
            // ── Battery & Temperature ────────────────────────────────────────────
            val batteryIntent: Intent? = context.registerReceiver(
                null,
                IntentFilter(Intent.ACTION_BATTERY_CHANGED)
            )
            val level  = batteryIntent?.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)  ?: -1
            val scale  = batteryIntent?.getIntExtra(BatteryManager.EXTRA_SCALE, -1)  ?: -1
            val rawTemp = batteryIntent?.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -10) ?: -10

            val battery = if (level >= 0 && scale > 0) (level * 100 / scale) else -1
            val tempC   = if (rawTemp > -10) rawTemp / 10f else -1f   // Android reports in tenths

            // ── RAM ──────────────────────────────────────────────────────────────
            am.getMemoryInfo(memInfo)
            val totalMb = memInfo.totalMem  / (1024L * 1024L)
            val freeMb  = memInfo.availMem  / (1024L * 1024L)
            val usedMb  = totalMb - freeMb

            emit(
                HardwareState(
                    batteryPercent = battery,
                    tempCelsius    = tempC,
                    ramUsedMb      = usedMb,
                    ramTotalMb     = totalMb,
                )
            )

            delay(POLL_INTERVAL_MS)
        }
    }
}
