package com.base.datarecovery.activity.recovery

import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import android.os.Environment
import androidx.activity.addCallback
import androidx.lifecycle.lifecycleScope
import com.base.datarecovery.R
import com.base.datarecovery.adapter.FileFolderAdapter
import com.base.datarecovery.ads.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.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.flow.collectLatest
import kotlinx.coroutines.launch
import java.io.File
import java.util.HashMap

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 {
            requestStorePermission(launcher, result = {
                if (it) beginScan() else finishToMain()
            })
        }
    }

    override fun initListener() {
        binding.flFanhui.setOnClickListener {
            onBackPressedDispatcher.onBackPressed()
        }
        onBackPressedDispatcher.addCallback {
            showExitFunctionDialog {
                AdmobInterstitialUtils.showInterstitialAd(this@FileScanResultActivity) {
                    finishToMain()
                }
            }
        }
    }

    private fun setAdapterData(pathList: ArrayList<String>) {
        val hashMap = HashMap<String, ArrayList<RecoveryBean>>()
        pathList.forEach { path ->
            val folder = File(path).parent ?: ""
            if (hashMap[folder] == null) {
                hashMap[folder] = arrayListOf()
            }
            hashMap[folder]?.add(RecoveryBean(path))
        }

        val list = hashMap.map {
            val folder = it.key.split("/").last()

            if (scanType == SCAN_DOCUMENTS) {
                it.value.forEach { bean -> bean.setType() }
            }
            FolderBean(folder, recoveryList = it.value)
        }
        binding.tvFolderNumber.text = list.size.toString()
        fileFolderAdapter.setData(list)
    }

    private fun beginScan() {
        if (scanOnce)
            return

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

        val filter = when (scanType) {
            SCAN_PHOTOS -> FileHexEx::isImage
            SCAN_DOCUMENTS -> FileHexEx::isDocument
            SCAN_VIDEOS -> FileHexEx::isVideo
            else -> FileHexEx::isImage
        }

        val pathList = ArrayList<String>()
        lifecycleScope.launch(Dispatchers.Main) {
            mFoundFlow.collectLatest {
                pathList.add(it.second)
                binding.tvFileNumber.text = pathList.size.toString()
                setAdapterData(pathList)
            }
        }

        var oneShowAd = false
        val root = Environment.getExternalStorageDirectory()
        lifecycleScope.loadFileByFilter(
            mPathFlow,
            mFoundFlow,
            root, filter = filter,
            onDo = { file ->
                LogEx.logDebug(TAG, "file =${file.absolutePath}")
                if (!oneShowAd) {
                    oneShowAd = true
                    lifecycleScope.launch(Dispatchers.Main) {
                        dialogClass.scanShowUI()
                        AdmobInterstitialUtils.showInterstitialAd(this@FileScanResultActivity, true, false) { }
                    }
                }
            },
            onFinish = {
                scanDialog.dismiss()
            }
        )


    }

}