package com.dumpster.cleaner.ui.recovery

import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import androidx.lifecycle.LifecycleCoroutineScope
import com.dumpster.cleaner.R
import com.dumpster.cleaner.databinding.DialogRecoveringBinding
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import java.io.File
import kotlin.random.Random

object RecoveringDialog {

    @SuppressLint("SetTextI18n")
    fun Context.showRecoveringDialog(
        lifecycleScope: LifecycleCoroutineScope,
        list: List<String>,
        dir: File,
        copyProgressAction: () -> Unit,
        finish: () -> Unit
    ) {
        val dialog = BottomSheetDialog(this, R.style.BottomSheetDialog)
        val binding = DialogRecoveringBinding.inflate(LayoutInflater.from(this))
        dialog.setContentView(binding.root)
        dialog.setCanceledOnTouchOutside(false)

        val mutableSharedFlow = MutableSharedFlow<Int>(
            replay = 5,//当新的订阅者Collect时，发送几个已经发送过的数据给它
            extraBufferCapacity = 5,//减去replay，MutableSharedFlow还缓存多少数据,缓冲池容量 = replay + extraBufferCapacity
            onBufferOverflow = BufferOverflow.SUSPEND//缓存策略，三种 丢掉最新值、丢掉最旧值和挂起
        )
        val sharedFlow: SharedFlow<Int> = mutableSharedFlow

        val parentView = binding.root.parent as View
        val behavior = BottomSheetBehavior.from(parentView)
        //展开
        behavior.state = BottomSheetBehavior.STATE_EXPANDED
        // 设置禁止通过拖动来隐藏
        behavior.isHideable = false

        // 禁止点击外部区域关闭
        dialog.setOnCancelListener { dialogInterface ->
            dialogInterface.cancel() // 这里可以处理点击外部区域的逻辑
        }

        lifecycleScope.launch(Dispatchers.IO) {

            val arrayList = arrayListOf<String>().apply {
                addAll(list)
            }
            var index = 0
            while (arrayList.isNotEmpty()) {
                val path = arrayList[0]
                arrayList.removeAt(0)
                val file = File(path)
                runCatching {
                    val recoveryFile = File(dir, file.name)
                    file.copyTo(recoveryFile, true)
                }
                mutableSharedFlow.emit(index)
                delay(Random.nextLong(500, 1500))
                index++
            }
            mutableSharedFlow.emit(-1)
        }

        lifecycleScope.launch(Dispatchers.Main) {
            sharedFlow.collectLatest {
//                LogEx.logDebug(TAG, "Flow $it")
                if (it == -1) {
                    finish.invoke()
                    dialog.dismiss()
                    cancel()
                } else {
                    val process = it.toFloat() / list.size.toFloat()
                    if (process > 0.3) {
                        copyProgressAction.invoke()
                    }
                    binding.tvNumber.text = "${it + 1}/${list.size}"
                }
            }
        }

        dialog.show()
    }
}