package com.base.filerecoveryrecyclebin.activity.recovery

import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import android.os.Environment
import android.view.View
import androidx.activity.addCallback
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import com.base.filerecoveryrecyclebin.adapter.FileFolderAdapter
import com.base.filerecoveryrecyclebin.ads.AdmobMaxHelper
import com.base.filerecoveryrecyclebin.ads.admob.AdmobInterstitialUtils
import com.base.filerecoveryrecyclebin.bean.ConstObject.SCAN_AUDIOS
import com.base.filerecoveryrecyclebin.bean.ConstObject.SCAN_DOCUMENTS
import com.base.filerecoveryrecyclebin.bean.ConstObject.SCAN_PHOTOS
import com.base.filerecoveryrecyclebin.bean.ConstObject.SCAN_VIDEOS
import com.base.filerecoveryrecyclebin.bean.FolderBean
import com.base.filerecoveryrecyclebin.bean.RecoveryBean
import com.base.filerecoveryrecyclebin.bean.RecoveryBean.Companion.setAudioType
import com.base.filerecoveryrecyclebin.bean.RecoveryBean.Companion.setDocumentType
import com.base.filerecoveryrecyclebin.databinding.ActivityFileScanResultBinding
import com.base.filerecoveryrecyclebin.help.BaseActivity
import com.base.filerecoveryrecyclebin.help.FileHelp.loadFileByFilter
import com.base.filerecoveryrecyclebin.help.PermissionHelp.checkStorePermission
import com.base.filerecoveryrecyclebin.help.PermissionHelp.requestStorePermission
import com.base.filerecoveryrecyclebin.utils.BarUtils
import com.base.filerecoveryrecyclebin.utils.FileHexEx
import com.base.filerecoveryrecyclebin.utils.LogEx
import com.base.filerecoveryrecyclebin.view.DialogViews.showExitFunctionDialog
import com.base.filerecoveryrecyclebin.view.DialogViews.showGerPermission
import com.base.filerecoveryrecyclebin.view.FileScanDialog
import com.google.gson.Gson
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.launch
import java.io.File

class FileScanResultActivity : BaseActivity<ActivityFileScanResultBinding>() {

    private val TAG = "FileScanResultActivity"
    private var scanOnce: Boolean = false
    private var scanType = 0
    override val binding: ActivityFileScanResultBinding by lazy {
        ActivityFileScanResultBinding.inflate(layoutInflater)
    }

    private lateinit var fileFolderAdapter: FileFolderAdapter


    @SuppressLint("SetTextI18n")
    override fun initView() {
        BarUtils.setStatusBarLightMode(this, true)
        BarUtils.setStatusBarColor(this, Color.TRANSPARENT)

        scanType = intent.extras?.getInt("ScanType") ?: 0

        LogEx.logDebug(TAG, "scanType=$scanType")
        when (scanType) {
            SCAN_PHOTOS -> {
                binding.tvTittle.text = "Photo Recovery"
                binding.tvFileType.text = "Photos"
            }

            SCAN_DOCUMENTS -> {
                binding.tvTittle.text = "Document Recovery"
                binding.tvFileType.text = "Documents"
            }

            SCAN_VIDEOS -> {
                binding.tvTittle.text = "Video Recovery"
                binding.tvFileType.text = "Videos"
            }

            SCAN_AUDIOS -> {
                binding.tvTittle.text = "Audio Recovery"
                binding.tvFileType.text = "Audios"
            }
        }
        fileFolderAdapter = FileFolderAdapter(scanType) { folderBean ->
            FileRecoveryActivity.folderBean = null
            FileRecoveryActivity.folderBean = folderBean
            startActivity(Intent(this, FileRecoveryActivity::class.java).apply {
                putExtra("ScanType", scanType)
            })
        }
        binding.rv.adapter = fileFolderAdapter

        if (checkStorePermission()) {
            beginScan()
        } else {
            showGerPermission(
                desc = "In order to scan and recover your lost photos, videos, and documents, we need to access your device storage. This permission is essential for our app to locate and restore your files.",
                deny = { finishToMain() },
                allow = {
                    requestStorePermission(launcher, result = {
                        if (it) beginScan() else finishToMain()
                    })
                })
        }
    }

    override fun initListener() {
        binding.flFanhui.setOnClickListener {
            onBackPressedDispatcher.onBackPressed()
        }
        onBackPressedDispatcher.addCallback {
            showExitFunctionDialog {
                if (it) {
                    AdmobMaxHelper.admobMaxShowInterstitialAd(this@FileScanResultActivity) {
                        finishToMain()
                    }
                } else {
                    finishToMain()
                }
            }
        }
    }


    @SuppressLint("SetTextI18n")
    private fun beginScan() {
        if (scanOnce)
            return

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

        //符合条件Flow
        val mFoundFlow = MutableSharedFlow<Pair<Int, String>>(
            replay = 5,
            extraBufferCapacity = 5,
            onBufferOverflow = BufferOverflow.SUSPEND
        )
        val foundFlow: SharedFlow<Pair<Int, String>> = mFoundFlow


        val dialogClass = FileScanDialog(this)
        val scanDialog = dialogClass.showFileScanDialog(pathFlow, foundFlow) {

            pathList.add(it)
            binding.tvFileNumber.text = pathList.size.toString()
            setAdapterData(it)
        }

        val filter = when (scanType) {
            SCAN_PHOTOS -> FileHexEx::isImage
            SCAN_DOCUMENTS -> FileHexEx::isDocument
            SCAN_VIDEOS -> FileHexEx::isVideo
            SCAN_AUDIOS -> FileHexEx::isAudio
            else -> FileHexEx::isImage
        }
        val root = Environment.getExternalStorageDirectory()
        lifecycleScope.loadFileByFilter(
            mPathFlow,
            mFoundFlow,
            root, filter = filter,
            onDo = { file ->
                LogEx.logDebug(TAG, "file =${file.absolutePath}")
            },
            onFinish = {
                lifecycleScope.launch(Dispatchers.Main) {
                    binding.ivWancheng.visibility = View.VISIBLE
                    binding.tvScanning.text = "Completed"
                    lifecycleScope.launchWhenResumed {
                        AdmobMaxHelper.admobMaxShowInterstitialAd(this@FileScanResultActivity)
                    }
                    binding.flEmpty.isVisible = pathList.isEmpty()
                    setAdapterData(null)
                    dialogClass.finishScan {
                        scanDialog.dismiss()
                    }
                }
            }
        )
    }

    private val pathList = ArrayList<String>()
    private val hashMap = HashMap<String, ArrayList<RecoveryBean>>()
    private fun setAdapterData(path: String? = null) {
        val flag = path?.let { addMapFolder(it) } ?: true
        if (flag) {
            binding.tvFolderNumber.text = hashMap.keys.size.toString()
            val mapList = hashMap.map {
                FolderBean(it.key, recoveryList = it.value)
            }
            fileFolderAdapter.setData(mapList)
        }
    }

    private fun addMapFolder(path: String): Boolean {
        var isNewFolder = false
        val folder = File(path).parent?.split("/")?.last() ?: ""
        if (hashMap[folder] == null) {
            hashMap[folder] = arrayListOf()
            isNewFolder = true
        }
        val recoveryBean = RecoveryBean(path)
        if (scanType == SCAN_DOCUMENTS) {
            recoveryBean.setDocumentType()
        }
        if (scanType == SCAN_AUDIOS) {
            recoveryBean.setAudioType()
        }
        hashMap[folder]?.add(recoveryBean)
        return isNewFolder
    }


}