package com.base.datarecovery.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.datarecovery.adapter.FileFolderAdapter
import com.base.datarecovery.ads.AdmobMaxHelper
import com.base.datarecovery.ads.admob.AdmobInterstitialUtils
import com.base.datarecovery.bean.ConstObject.SCAN_DOCUMENTS
import com.base.datarecovery.bean.ConstObject.SCAN_PHOTOS
import com.base.datarecovery.bean.ConstObject.SCAN_VIDEOS
import com.base.datarecovery.bean.FolderBean
import com.base.datarecovery.bean.RecoveryBean
import com.base.datarecovery.bean.RecoveryBean.Companion.setType
import com.base.datarecovery.databinding.ActivityFileScanResultBinding
import com.base.datarecovery.help.BaseActivity
import com.base.datarecovery.help.FileHelp.loadFileByFilter
import com.base.datarecovery.help.PermissionHelp.checkStorePermission
import com.base.datarecovery.help.PermissionHelp.requestStorePermission
import com.base.datarecovery.utils.BarUtils
import com.base.datarecovery.utils.FileHexEx
import com.base.datarecovery.utils.LogEx
import com.base.datarecovery.view.DialogViews.showExitFunctionDialog
import com.base.datarecovery.view.DialogViews.showGerPermission
import com.base.datarecovery.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"
            }
        }
        fileFolderAdapter = FileFolderAdapter(scanType) { folderBean ->
            startActivity(Intent(this, FileRecoveryActivity::class.java).apply {
                putExtra("ScanType", scanType)
                putExtra("Data", Gson().toJson(folderBean))
            })
        }
        binding.rv.adapter = fileFolderAdapter

        if (checkStorePermission()) {
            beginScan()
        } else {
            showGerPermission() {
                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
            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"
                    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.setType()
        }
        hashMap[folder]?.add(recoveryBean)
        return isNewFolder
    }
}