package com.base.filerecoveryrecyclebin.view

import android.annotation.SuppressLint
import android.app.Activity
import android.app.AlertDialog
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.CountDownTimer
import android.text.SpannableString
import android.text.Spanned
import android.text.style.ForegroundColorSpan
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.WindowManager
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.lifecycle.LifecycleCoroutineScope
import com.base.filerecoveryrecyclebin.R
import com.base.filerecoveryrecyclebin.activity.junkclean.ScanJunkActivity
import com.base.filerecoveryrecyclebin.ads.AdmobMaxHelper
import com.base.filerecoveryrecyclebin.ads.AdmobMaxHelper.admobMaxShowNativeAd
import com.base.filerecoveryrecyclebin.ads.AdmobMaxHelper.showBackInterAdSp
import com.base.filerecoveryrecyclebin.bean.ConstObject.SELECT_FILE_ALL
import com.base.filerecoveryrecyclebin.bean.ConstObject.SELECT_FILE_AUDIO
import com.base.filerecoveryrecyclebin.bean.ConstObject.SELECT_FILE_DOCUMENT
import com.base.filerecoveryrecyclebin.bean.ConstObject.SELECT_FILE_OTHER
import com.base.filerecoveryrecyclebin.bean.ConstObject.SELECT_FILE_PICTURE
import com.base.filerecoveryrecyclebin.bean.ConstObject.SELECT_FILE_VIDEO
import com.base.filerecoveryrecyclebin.bean.RecycleBinBean
import com.base.filerecoveryrecyclebin.databinding.DialogAppProcessExitBinding
import com.base.filerecoveryrecyclebin.databinding.DialogCameraSettingBinding
import com.base.filerecoveryrecyclebin.databinding.DialogDeletePermanentlyBinding
import com.base.filerecoveryrecyclebin.databinding.DialogExitAppBinding
import com.base.filerecoveryrecyclebin.databinding.DialogExitFunctionBinding
import com.base.filerecoveryrecyclebin.databinding.DialogImageTakeBinding
import com.base.filerecoveryrecyclebin.databinding.DialogLargeFileTypeBinding
import com.base.filerecoveryrecyclebin.databinding.DialogPermissonOpenBinding
import com.base.filerecoveryrecyclebin.databinding.DialogRecoveringBinding
import com.base.filerecoveryrecyclebin.databinding.DialogRecyclebinFileRestoreBinding
import com.base.filerecoveryrecyclebin.databinding.DialogRecyclebinFilterBinding
import com.base.filerecoveryrecyclebin.databinding.DialogRemoveFileTipBinding
import com.base.filerecoveryrecyclebin.databinding.DialogTittleDescExitBinding
import com.base.filerecoveryrecyclebin.help.KotlinExt.toFormatSize
import com.base.filerecoveryrecyclebin.help.KotlinExt.toFormatTime
import com.base.filerecoveryrecyclebin.utils.LogEx
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,
        desc: String? = null,
        denyText: String? = null,
        allowText: 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.tvTitle.text = it }
        desc?.let { binding.tvDesc.text = it }
        denyText?.let { binding.idDeny.text = it }
        allowText?.let { binding.idTvAllow.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()
        }
    }

    fun Context.showExitFunctionDialog(
        activity: Activity,
        mustShow: Boolean = true,
        exitAction: (showAd: Boolean) -> Unit
    ) {
        if (!mustShow) {
            if (!showBackInterAdSp()) {
                exitAction.invoke(false)
                return
            }
        }

        val dialog = Dialog(this)
        val binding = DialogExitFunctionBinding.inflate(LayoutInflater.from(this))
        dialog.requestWindowFeature(1)
        dialog.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        dialog.window?.setLayout(-1, -1)
        dialog.setContentView(binding.root)
        dialog.show()

//        dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
//        val params = dialog.window?.attributes
//        params?.width = resources.getDimensionPixelOffset(R.dimen.dp_345)
//        dialog.window?.attributes = params
        if (AdmobMaxHelper.showExitNativeSp()) {
            admobMaxShowNativeAd(activity, binding.idFlNative)
        }
        binding.tvN.setOnClickListener {
            dialog.dismiss()
            exitAction.invoke(showBackInterAdSp())
        }
        binding.tvY.setOnClickListener {
            dialog.dismiss()
        }
    }

    @SuppressLint("SetTextI18n")
    fun Context.showRecycleBinDetailDialog(bean: RecycleBinBean, binFile: File, binJsonFile: File, action: () -> Unit) {
        val binding = DialogRecyclebinFileRestoreBinding.inflate(LayoutInflater.from(this))
        val dialog = AlertDialog.Builder(this).create()
        dialog.setView(binding.root)
        dialog.show()
        dialog.setCanceledOnTouchOutside(false)
        dialog.setCancelable(false)

        val params = dialog.window?.attributes
        params?.gravity = Gravity.BOTTOM
        params?.y = resources.getDimensionPixelOffset(R.dimen.dp_35)
        params?.width = resources.getDimensionPixelOffset(R.dimen.dp_355)
        params?.dimAmount = 0f
        dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
        dialog.window?.attributes = params

        binding.tvName.text = bean.path
        binding.tvSize.text = bean.size.toFormatSize()
        binding.tvTime.text = "Delete time:${bean.deleteTime.toFormatTime()}"

        binding.tvRestore.setOnClickListener {
            dialog.dismiss()
            runCatching {
                binFile.copyTo(File(bean.path), true)
                binFile.delete()
                binJsonFile.delete()
            }
            action.invoke()
        }
    }

    fun Activity.showExitDialog() {
        val binding = DialogExitAppBinding.inflate(LayoutInflater.from(this))
        val dialog = AlertDialog.Builder(this).create()
        dialog.setView(binding.root)
//        dialog.setCanceledOnTouchOutside(false)
//        dialog.setCancelable(false)
        dialog.show()
        dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
        val lp: WindowManager.LayoutParams? = dialog.window?.attributes
        lp?.gravity = Gravity.BOTTOM
        lp?.width = ConstraintLayout.LayoutParams.MATCH_PARENT
//        lp?.alpha = 1f
//        lp?.dimAmount = 0.0f
        dialog.window?.setAttributes(lp)
        binding.tvExit.isEnabled = false
        val interval = 1000L
        lateinit var countDownTimer: CountDownTimer
        val countdownTime = 3000L // 倒计时总时间（毫秒）
        countDownTimer = object : CountDownTimer(countdownTime, interval) {
            override fun onTick(millisUntilFinished: Long) {
                // 每次倒计时更新
                val secondsRemaining = millisUntilFinished / 1000
                binding.tvExit.text = "Exit($secondsRemaining)"
            }

            override fun onFinish() {
                // 倒计时结束
                binding.tvExit.text = "Exit"
                binding.tvExit.isEnabled = true
            }
        }
        countDownTimer.start()
        admobMaxShowNativeAd(this, binding.idFlNative, 1)
        binding.tvY.setOnClickListener {
            countDownTimer.cancel()
            dialog.dismiss()
            startActivity(Intent(this, ScanJunkActivity::class.java))
        }


        binding.tvExit.setOnClickListener {
            countDownTimer.cancel()
            dialog.dismiss()
            this.finish()
        }

    }

    fun Context.showLargeFileTypeDialog(type: String, click: (type: String) -> Unit) {
        val binding = DialogLargeFileTypeBinding.inflate(LayoutInflater.from(this))
        val dialog = AlertDialog.Builder(this).create()
        dialog.setView(binding.root)
//        dialog.setCanceledOnTouchOutside(false)
//        dialog.setCancelable(false)
        dialog.show()

        dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
        val lp: WindowManager.LayoutParams? = dialog.window?.attributes
        lp?.gravity = Gravity.BOTTOM
        lp?.width = ConstraintLayout.LayoutParams.MATCH_PARENT
        dialog.window?.setAttributes(lp)

        when (type) {
            SELECT_FILE_ALL -> binding.flAllType.isSelected = true
            SELECT_FILE_PICTURE -> binding.flPicture.isSelected = true
            SELECT_FILE_VIDEO -> binding.flVideo.isSelected = true
            SELECT_FILE_AUDIO -> binding.flAudio.isSelected = true
            SELECT_FILE_DOCUMENT -> binding.flDocument.isSelected = true
            SELECT_FILE_OTHER -> binding.flOther.isSelected = true
        }
        binding.flAllType.setOnClickListener {
            dialog.dismiss()
            click.invoke(SELECT_FILE_ALL)
        }
        binding.flPicture.setOnClickListener {
            dialog.dismiss()
            click.invoke(SELECT_FILE_PICTURE)
        }
        binding.flVideo.setOnClickListener {
            dialog.dismiss()
            click.invoke(SELECT_FILE_VIDEO)
        }
        binding.flAudio.setOnClickListener {
            dialog.dismiss()
            click.invoke(SELECT_FILE_AUDIO)
        }
        binding.flDocument.setOnClickListener {
            dialog.dismiss()
            click.invoke(SELECT_FILE_DOCUMENT)
        }
        binding.flOther.setOnClickListener {
            dialog.dismiss()
            click.invoke(SELECT_FILE_OTHER)
        }
    }

    fun Context.showRecycleBinFilter(
        lifecycleScope: LifecycleCoroutineScope,
        filter: String?,
        filterAction: (filter: String) -> Unit
    ) {
        val binding = DialogRecyclebinFilterBinding.inflate(LayoutInflater.from(this))
        val dialog = AlertDialog.Builder(this).create()
        dialog.setView(binding.root)
        dialog.show()

        dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
        val lp: WindowManager.LayoutParams? = dialog.window?.attributes
        lp?.gravity = Gravity.TOP or Gravity.END
        lp?.x = 30
        lp?.width = this.resources.getDimensionPixelOffset(R.dimen.dp_205)
        dialog.window?.setAttributes(lp)
        when (filter) {
            "Photos" -> {
                binding.ivPhotos.visibility = View.VISIBLE
            }

            "Videos" -> {
                binding.ivVideos.visibility = View.VISIBLE
            }

            "Audios" -> {
                binding.ivAudios.visibility = View.VISIBLE
            }

            "Documents" -> {
                binding.ivDocuments.visibility = View.VISIBLE
            }
        }
        val action = {
            binding.ivPhotos.visibility = View.INVISIBLE
            binding.ivVideos.visibility = View.INVISIBLE
            binding.ivAudios.visibility = View.INVISIBLE
            binding.ivDocuments.visibility = View.INVISIBLE
        }
        binding.flPhotos.setOnClickListener {
            action.invoke()
            binding.ivPhotos.visibility = View.VISIBLE
            lifecycleScope.launch {
                delay(250)
                dialog.dismiss()
                filterAction.invoke("Photos")
            }
        }
        binding.flVideos.setOnClickListener {
            action.invoke()
            binding.ivVideos.visibility = View.VISIBLE
            lifecycleScope.launch {
                delay(250)
                dialog.dismiss()
                filterAction.invoke("Videos")
            }

        }
        binding.flAudios.setOnClickListener {
            action.invoke()
            binding.ivAudios.visibility = View.VISIBLE
            lifecycleScope.launch {
                delay(250)
                dialog.dismiss()
                filterAction.invoke("Audios")
            }

        }
        binding.flDocuments.setOnClickListener {
            action.invoke()
            binding.ivDocuments.visibility = View.VISIBLE
            lifecycleScope.launch {
                delay(250)
                dialog.dismiss()
                filterAction.invoke("Documents")
            }
        }
    }

    @SuppressLint("SetTextI18n")
    fun Context.showAppProcessExitDialog(percent: Int, action: () -> Unit) {
        val binding = DialogAppProcessExitBinding.inflate(LayoutInflater.from(this))
        val dialog = AlertDialog.Builder(this).create()
        dialog.setView(binding.root)
        dialog.show()
        val text = "RAM accounts for more than $percent%.\nAre you sure want to leave?"
        val spannableString = SpannableString(text)

        val start = text.indexOf("$percent%")
        val end = start + "$percent%".length
        spannableString.setSpan(ForegroundColorSpan(Color.RED), start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

        binding.tvTip.text = spannableString
        dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
        val lp: WindowManager.LayoutParams? = dialog.window?.attributes

        lp?.width = this.resources.getDimensionPixelOffset(R.dimen.dp_315)
//        lp?.height=

        dialog.window?.setAttributes(lp)
        binding.tvN.setOnClickListener {
            dialog.dismiss()
            action.invoke()
        }
        binding.tvY.setOnClickListener {
            dialog.dismiss()
        }
    }


    @SuppressLint("SetTextI18n")
    fun Context.showTittleDescExitDialog(tittle: String, desc: String, yBtn: String, nBtn: String, action: () -> Unit) {
        val binding = DialogTittleDescExitBinding.inflate(LayoutInflater.from(this))
        val dialog = AlertDialog.Builder(this).create()
        dialog.setView(binding.root)
        dialog.show()

        binding.tvTittle.text = tittle
        binding.tvTip.text = desc
        binding.tvY.text = yBtn
        binding.tvN.text = nBtn


        dialog.window?.setBackgroundDrawableResource(android.R.color.transparent)
        val lp: WindowManager.LayoutParams? = dialog.window?.attributes

        lp?.width = this.resources.getDimensionPixelOffset(R.dimen.dp_355)
//        lp?.height=

        dialog.window?.setAttributes(lp)
        binding.tvN.setOnClickListener {
            dialog.dismiss()
            action.invoke()
        }
        binding.tvY.setOnClickListener {
            dialog.dismiss()
        }
    }


}
