package com.dphms.optimizer.lite

import java.util.Locale
import android.app.Notification
import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.Service
import android.content.Intent
import android.os.Build
import android.os.IBinder
import androidx.core.app.NotificationCompat
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.*
import java.io.BufferedReader
import java.io.File
import java.io.InputStreamReader

class OptimizerService : Service() {

    companion object {
        const val ACTION_STOP_ALL = "com.dphms.optimizer.lite.STOP_ALL"
        const val ACTION_CLEAR_CACHES = "com.dphms.optimizer.lite.CLEAR_CACHES"
        const val ACTION_WIDGET_STOP = "com.dphms.optimizer.lite.WIDGET_STOP"
        const val ACTION_WIDGET_CLEAR = "com.dphms.optimizer.lite.WIDGET_CLEAR"
        const val CHANNEL_ID = "dphms_lite_service"
        const val NOTIF_ID = 1001
    }

    private val scope = CoroutineScope(Dispatchers.IO + SupervisorJob())

    override fun onCreate() {
        super.onCreate()
        createNotificationChannel()
        startForeground(NOTIF_ID, createNotification("DPHMS Lite Ready"))
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        when (intent?.action) {
            ACTION_STOP_ALL, ACTION_WIDGET_STOP -> performStopAll()
            ACTION_CLEAR_CACHES, ACTION_WIDGET_CLEAR -> performClearCaches()
        }
        return START_NOT_STICKY
    }

    private fun performStopAll() {
        scope.launch {
            updateNotification("Stopping all apps...")
            val service = ShizukuManager.bindService(this@OptimizerService) ?: return@launch
            val optimizer = SystemOptimizer(service)

            val ramBefore = optimizer.getRamInfo()
            val packages = service.listPackages()
            val excluded = setOf(
                "com.dphms.optimizer.lite", "moe.shizuku.privileged.api",
                "android", "com.android.systemui", "com.android.phone",
                "com.android.settings", "com.android.launcher3",
                "com.google.android.inputmethod", "com.motorola.launcher3"
            )

            var stopped = 0
            for (pkg in packages) {
                if (excluded.contains(pkg)) continue
                service.forceStopPackage(pkg)
                stopped++
                if (stopped % 10 == 0) updateNotification("Stopped $stopped / ${packages.size} apps")
            }

            val ramAfter = optimizer.getRamInfo()
            val ramFreed = ramBefore.usedMb - ramAfter.usedMb

            updateNotification("Done: $stopped apps stopped, ${ramFreed}MB RAM freed")
            sendResultBroadcast("STOP", stopped, ramFreed.toInt())
            delay(3000)
            stopSelf()
        }
    }

    private fun performClearCaches() {
        scope.launch {
            updateNotification("Clearing caches...")
            val service = ShizukuManager.bindService(this@OptimizerService) ?: return@launch

            val storageBefore = SystemOptimizer(service).getStorageInfo()
            service.trimCaches()
            val storageAfter = SystemOptimizer(service).getStorageInfo()
            val cacheFreed = (storageAfter.freeGb - storageBefore.freeGb).coerceAtLeast(0.0)

            updateNotification("Done: ${String.format(Locale.US, "%.1f", cacheFreed)}GB storage freed")
            sendResultBroadcast("CLEAR", 0, cacheFreed.toInt())
            delay(3000)
            stopSelf()
        }
    }

    private fun sendResultBroadcast(type: String, count: Int, freedMb: Int) {
        val intent = Intent("com.dphms.optimizer.lite.RESULT")
        intent.putExtra("type", type)
        intent.putExtra("count", count)
        intent.putExtra("freed_mb", freedMb)
        sendBroadcast(intent)
    }

    private fun updateNotification(text: String) {
        val nm = getSystemService(NotificationManager::class.java)
        nm.notify(NOTIF_ID, createNotification(text))
    }

    private fun createNotification(text: String): Notification {
        return NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("DPHMS Lite")
            .setContentText(text)
            .setSmallIcon(android.R.drawable.ic_menu_manage)
            .setOngoing(true)
            .build()
    }

    private fun createNotificationChannel() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = NotificationChannel(CHANNEL_ID, "DPHMS Lite Service", NotificationManager.IMPORTANCE_LOW)
            getSystemService(NotificationManager::class.java).createNotificationChannel(channel)
        }
    }

    override fun onBind(intent: Intent?): IBinder? = null
    override fun onDestroy() { scope.cancel(); super.onDestroy() }
}
