package com.base.datarecovery.view

import android.annotation.SuppressLint
import android.app.AlertDialog
import android.app.Dialog
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import androidx.core.view.isVisible
import androidx.lifecycle.LifecycleCoroutineScope
import com.base.datarecovery.R
import com.base.datarecovery.bean.ConstObject.rememberOption
import com.base.datarecovery.databinding.DialogCameraSettingBinding
import com.base.datarecovery.databinding.DialogDeletePermanentlyBinding
import com.base.datarecovery.databinding.DialogImageTakeBinding
import com.base.datarecovery.databinding.DialogPermissonOpenBinding
import com.base.datarecovery.databinding.DialogRecoveringBinding
import com.base.datarecovery.databinding.DialogRemoveFileTipBinding
import com.base.datarecovery.utils.LogEx
import com.base.datarecovery.view.DialogViews.showCameraSettingDialog
import com.base.datarecovery.view.DialogViews.showPinReEnterDialog
import com.base.datarecovery.view.DialogViews.showRecoveringDialog
import com.base.datarecovery.view.DialogViews.showRemoveOriginalTip
import com.base.datarecovery.view.XmlEx.inflate
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 DialogViews {

    private val TAG = "DialogViews"

    @SuppressLint("SetTextI18n")
    fun Context.showGerPermission(
        tittle: String? = null,
        deny: ((view: Dialog) -> Unit)? = null,
        allow: ((view: Dialog) -> Unit)? = null
    ): Dialog {
        val dialog = Dialog(this)
        val binding = DialogPermissonOpenBinding.inflate(LayoutInflater.from(this))
        dialog.requestWindowFeature(1)
        dialog.window!!.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        dialog.window!!.setLayout(-1, -1)
        dialog.setCanceledOnTouchOutside(false)
        dialog.setCancelable(false)
        dialog.setContentView(binding.root)
        val str = resources.getString(R.string.app_name)

        tittle?.let { binding.idTvTt.text = it }
        binding.idFullLottie.imageAssetsFolder = "recovery_permission_finger/images/"
        binding.idFullLottie.setAnimation("recovery_permission_finger/data.json")
        binding.idFullLottie.playAnimation()
        binding.idDeny.setOnClickListener {
            dialog.dismiss()
            deny?.invoke(dialog)
        }
        binding.idTvAllow.setOnClickListener {
            dialog.dismiss()
            allow?.invoke(dialog)
        }
        dialog.show()
        return dialog
    }


    @SuppressLint("SetTextI18n")
    fun Context.showRecoveringDialog(
        lifecycleScope: LifecycleCoroutineScope,
        list: List<String>,
        dir: File,
        copyProgressAction: () -> Unit,
        finish: () -> Unit
    ) {
        val dialog = BottomSheetDialog(this)
        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()
    }


    fun Context.showImageImportDialog(import: () -> Unit, camera: () -> Unit) {
        val binding = DialogImageTakeBinding.inflate(LayoutInflater.from(this))
        val dialog = AlertDialog.Builder(this, R.style.CustomAlertDialogStyle).setView(binding.root).create()

        dialog.setContentView(binding.root)
        dialog.setCanceledOnTouchOutside(true)
        dialog.show()

        val params = dialog.window?.attributes
        params?.gravity = Gravity.BOTTOM
        params?.y = 50

        dialog.window?.attributes = params

        binding.llImport.setOnClickListener {
            dialog.dismiss()
            import.invoke()
        }
        binding.llCamera.setOnClickListener {
            dialog.dismiss()
            camera.invoke()
        }
    }

    fun Context.showCameraSettingDialog() {
        val binding = DialogCameraSettingBinding.inflate(LayoutInflater.from(this))
        val dialog = AlertDialog.Builder(this, R.style.CustomAlertDialogStyle).setView(binding.root).create()

        dialog.setContentView(binding.root)
        dialog.setCanceledOnTouchOutside(true)
        dialog.show()

        val params = dialog.window?.attributes

        dialog.window?.attributes = params
        binding.tvOk.setOnClickListener { dialog.dismiss() }
    }

    fun Context.showRemoveOriginalTip(click: (isRememberOption: Boolean, isRemove: Boolean) -> Unit) {
        val binding = DialogRemoveFileTipBinding.inflate(LayoutInflater.from(this))
        val dialog = AlertDialog.Builder(this, R.style.CustomAlertDialogStyle).create()

        dialog.setView(binding.root)
        dialog.setContentView(binding.root)
        dialog.setCanceledOnTouchOutside(false)
        dialog.show()

        val params = dialog.window?.attributes
        params?.width = resources.getDimensionPixelOffset(R.dimen.dp_300)
        dialog.window?.attributes = params

        binding.ivSelector.setOnClickListener {
            binding.ivSelector.isSelected = !binding.ivSelector.isSelected
        }

        binding.tvRemove.setOnClickListener {
            dialog.dismiss()
            click.invoke(binding.ivSelector.isSelected, true)
        }
        binding.tvNoRemove.setOnClickListener {
            dialog.dismiss()
            click.invoke(binding.ivSelector.isSelected, false)
        }
    }

    fun Context.showPinReEnterDialog(): CustomDialog {
        val dialog = CustomDialog(this, R.layout.dialog_pin_re_enter)
        dialog.window?.setDimAmount(0f)
        dialog.show()
        return dialog
    }

    fun Context.showDeletePermanentlyDialog(deleteAction: () -> Unit) {
        val binding = DialogDeletePermanentlyBinding.inflate(LayoutInflater.from(this))
        val dialog = AlertDialog.Builder(this, R.style.CustomAlertDialogStyle).create()
        dialog.setView(binding.root)
        dialog.show()


        val params = dialog.window?.attributes
        params?.width = resources.getDimensionPixelOffset(R.dimen.dp_300)
        dialog.window?.attributes = params

        binding.tvDelete.setOnClickListener {
            dialog.cancel()
            deleteAction.invoke()
        }
        binding.tvCancel.setOnClickListener {
            dialog.cancel()
        }
    }

}
