package com.zxhy.solarmasterace.filebrowser

import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.GridLayoutManager
import com.zxhy.solarmasterace.R
import com.zxhy.solarmasterace.data.FileBean
import com.zxhy.solarmasterace.databinding.ActivityFileBrowserBinding
import com.zxhy.solarmasterace.datastore.DUP_IMAGE_COUNTER_KEY
import com.zxhy.solarmasterace.datastore.EMPTY_FILE_COUNTER_KEY
import com.zxhy.solarmasterace.datastore.LARGE_FILES_COUNTER_KEY
import com.zxhy.solarmasterace.datastore.saveFileCount
import com.zxhy.solarmasterace.dialog.showLoadingDialog
import com.zxhy.solarmasterace.filedetails.FileDetailActivity
import com.zxhy.solarmasterace.permission.requestStoreFollow
import com.zxhy.solarmasterace.quicktools.ActivityLauncher
import com.zxhy.solarmasterace.quicktools.apkFile
import com.zxhy.solarmasterace.quicktools.audioFile
import com.zxhy.solarmasterace.quicktools.deleteFiles
import com.zxhy.solarmasterace.quicktools.documentFile
import com.zxhy.solarmasterace.quicktools.dupImage
import com.zxhy.solarmasterace.quicktools.emptyFile
import com.zxhy.solarmasterace.quicktools.excelFile
import com.zxhy.solarmasterace.quicktools.imageFile
import com.zxhy.solarmasterace.quicktools.largeFile
import com.zxhy.solarmasterace.quicktools.logFile
import com.zxhy.solarmasterace.quicktools.pdfFile
import com.zxhy.solarmasterace.quicktools.pptFile
import com.zxhy.solarmasterace.quicktools.storePermissionCheck
import com.zxhy.solarmasterace.quicktools.txtFile
import com.zxhy.solarmasterace.quicktools.videoFile
import com.zxhy.solarmasterace.quicktools.wordFile
import com.zxhy.solarmasterace.quicktools.zipFile
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch

class FileBrowserActivity : AppCompatActivity() {
    private lateinit var binding: ActivityFileBrowserBinding
    private var title: String = "title"
    private lateinit var dupImageAdapter: DupImageAdapter
    private lateinit var cardFileAdapter: CardFileAdapter
    private lateinit var fileGridAdapter: FileGridAdapter
    private lateinit var activityLauncher: ActivityLauncher

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        activityLauncher = ActivityLauncher(this)
        binding = ActivityFileBrowserBinding.inflate(layoutInflater)
        setContentView(binding.root)
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
            val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
            insets
        }
        title = intent.extras?.getString("tittle") ?: ""
        binding.tvTittle.text = title
        binding.clArrow.setOnClickListener {
            finish()
        }
        if (storePermissionCheck()) {
            showBrowser()
        } else {
            isPermissionSet(true)
        }
    }

    private fun showBrowser() {
        when (title) {
            "Image" -> imageMode()
            "Video" -> videoMode()

            "Audio" -> audioMode()//
            "Apk" -> apkMode()//
            "Zip" -> zipMode()//
            "Log file" -> logFileMode()//
            "Word" -> wordMode()//
            "Excel" -> excelMode()//
            "PPT" -> pptMode()//
            "PDF" -> pdfMode()//
            "TXT" -> txtMode()//
            "Documents" -> documentMode()//
            "Scan large files" -> largeFileMode()//
            "Scan empty file" -> emptyFileMode()//

            "Duplicate picture" -> dupImageMode()
        }

    }


    @SuppressLint("SetTextI18n")
    private fun loadImageFile() {
        val dialog = showLoadingDialog()
        fileGridAdapter.clearData()
        var doLaunch = false
        val waitList = ArrayList<FileBean>()
        imageFile(lifecycleScope,
            onDo = { data ->
                if (doLaunch) {
                    doLaunch = true
                    lifecycleScope.launch(Dispatchers.Main) {
                        dialog.dismiss()
                        fileGridAdapter.addData(data)
                    }
                } else {
                    waitList.addAll(data)
                }

            },
            onFinish = { data, count ->
                lifecycleScope.launch(Dispatchers.Main) {
                    dialog.dismiss()
                    waitList.addAll(data)
                    fileGridAdapter.addData(waitList)
                    binding.tvTip1.text = "$count items"
                    binding.ivAll.isSelected = false
                    showEmptyUi()
                }
            }
        )
    }


    private fun documentMode() {
        cardUi()
        loadDocumentFile()
    }

    private fun loadDocumentFile() {
        val dialog = showLoadingDialog()
        cardFileAdapter.clearData()
        var doLaunch = false
        val waitList = ArrayList<FileBean>()
        lifecycleScope.launch(Dispatchers.IO) {
            documentFile(
                onDo = { data ->
                    if (doLaunch) {
                        doLaunch = true
                        lifecycleScope.launch(Dispatchers.Main) {
                            dialog.dismiss()
                            cardFileAdapter.addData(data)
                        }
                    } else {
                        waitList.addAll(data)
                    }
                },
                onFinish = { data, count ->
                    lifecycleScope.launch(Dispatchers.Main) {
                        dialog.dismiss()
                        waitList.addAll(data)
                        cardFileAdapter.addData(waitList)
                        binding.tvTip1.text = "$count items"
                        binding.ivAll.isSelected = false
                        showEmptyUi()
                    }
                }
            )
        }
    }

    private fun txtMode() {
        cardUi()
        loadTxtFile()
    }

    private fun loadTxtFile() {
        val dialog = showLoadingDialog()
        cardFileAdapter.clearData()
        var doLaunch = false
        val waitList = ArrayList<FileBean>()
        lifecycleScope.launch(Dispatchers.IO) {
            txtFile(
                onDo = { data ->
                    if (doLaunch) {
                        doLaunch = true
                        lifecycleScope.launch(Dispatchers.Main) {
                            dialog.dismiss()
                            cardFileAdapter.addData(data)
                        }
                    } else {
                        waitList.addAll(data)
                    }
                },
                onFinish = { data, count ->
                    lifecycleScope.launch(Dispatchers.Main) {
                        dialog.dismiss()
                        waitList.addAll(data)
                        cardFileAdapter.addData(waitList)
                        binding.tvTip1.text = "$count items"
                        binding.ivAll.isSelected = false
                        showEmptyUi()
                    }
                }
            )
        }
    }

    private fun pdfMode() {
        cardUi()
        loadPdfFile()
    }

    private fun loadPdfFile() {
        val dialog = showLoadingDialog()
        cardFileAdapter.clearData()
        var doLaunch = false
        val waitList = ArrayList<FileBean>()
        lifecycleScope.launch(Dispatchers.IO) {
            pdfFile(
                onDo = { data ->
                    if (doLaunch) {
                        doLaunch = true
                        lifecycleScope.launch(Dispatchers.Main) {
                            dialog.dismiss()
                            cardFileAdapter.addData(data)
                        }
                    } else {
                        waitList.addAll(data)
                    }
                },
                onFinish = { data, count ->
                    lifecycleScope.launch(Dispatchers.Main) {
                        dialog.dismiss()
                        waitList.addAll(data)
                        cardFileAdapter.addData(waitList)
                        binding.tvTip1.text = "$count items"
                        binding.ivAll.isSelected = false
                        showEmptyUi()
                    }
                }
            )
        }
    }

    private fun pptMode() {
        cardUi()
        loadPptFile()
    }

    @SuppressLint("SetTextI18n")
    private fun loadPptFile() {
        val dialog = showLoadingDialog()
        cardFileAdapter.clearData()
        var doLaunch = false
        val waitList = ArrayList<FileBean>()
        lifecycleScope.launch(Dispatchers.IO) {
            pptFile(
                onDo = { data ->
                    if (doLaunch) {
                        doLaunch = true
                        lifecycleScope.launch(Dispatchers.Main) {
                            dialog.dismiss()
                            cardFileAdapter.addData(data)
                        }
                    } else {
                        waitList.addAll(data)
                    }
                },
                onFinish = { data, count ->
                    lifecycleScope.launch(Dispatchers.Main) {
                        dialog.dismiss()
                        waitList.addAll(data)
                        cardFileAdapter.addData(waitList)
                        binding.tvTip1.text = "$count items"
                        binding.ivAll.isSelected = false
                        showEmptyUi()
                    }
                }
            )
        }
    }

    fun gridUi() {
        binding.tvTip1.visibility = View.VISIBLE
        binding.tvTip2.visibility = View.GONE
        fileGridAdapter = FileGridAdapter(
            selectClick = {
                binding.ivAll.isSelected = it
            },
            itemClick = { path ->
                startActivity(Intent(this, FileDetailActivity::class.java).apply {
                    putExtra("Path", path)
                })
            }
        )
        binding.ivAll.setOnClickListener {
            it.isSelected = !it.isSelected
            fileGridAdapter.toggleSelect(it.isSelected)
        }
        binding.rv.visibility = View.INVISIBLE
        binding.rvWarp.visibility = View.VISIBLE
        binding.rvWarp.layoutManager = GridLayoutManager(this, 3)
        binding.rvWarp.adapter = fileGridAdapter
        binding.tvDelete.background =
            ContextCompat.getDrawable(this, R.drawable.bg_ff5c67e5_corners)
        binding.tvDelete.text = "Delete"
        binding.tvDelete.setTextColor(ContextCompat.getColor(this, R.color.white))
        binding.tvDelete.setOnClickListener {
            deleteGridUiFile(fileGridAdapter.getSelectData())
        }
    }

    fun cardUi() {
        binding.tvTip1.visibility = View.VISIBLE
        binding.tvTip2.visibility = View.INVISIBLE
        cardFileAdapter = CardFileAdapter {
            binding.ivAll.isSelected = it
        }
        binding.rv.adapter = cardFileAdapter
        binding.ivAll.setOnClickListener {
            it.isSelected = !it.isSelected
            cardFileAdapter.toggleSelect(it.isSelected)
        }
        binding.tvDelete.background =
            ContextCompat.getDrawable(this, R.drawable.bg_ff5c67e5_corners)
        binding.tvDelete.text = "Delete"
        binding.tvDelete.setTextColor(ContextCompat.getColor(this, R.color.white))
        binding.tvDelete.setOnClickListener {
            deleteCardFile(cardFileAdapter.getSelectData())
        }
    }

    private fun excelMode() {
        cardUi()
        loadExcelFile()
    }

    @SuppressLint("SetTextI18n")
    private fun loadExcelFile() {
        val dialog = showLoadingDialog()
        cardFileAdapter.clearData()
        var doLaunch = false
        val waitList = ArrayList<FileBean>()
        lifecycleScope.launch(Dispatchers.IO) {
            excelFile(
                onDo = { data ->
                    if (doLaunch) {
                        doLaunch = true
                        lifecycleScope.launch(Dispatchers.Main) {
                            dialog.dismiss()
                            cardFileAdapter.addData(data)
                        }
                    } else {
                        waitList.addAll(data)
                    }
                },
                onFinish = { data, count ->
                    lifecycleScope.launch(Dispatchers.Main) {
                        dialog.dismiss()
                        waitList.addAll(data)
                        cardFileAdapter.addData(waitList)
                        binding.tvTip1.text = "$count items"
                        binding.ivAll.isSelected = false
                        showEmptyUi()
                    }
                }
            )
        }
    }

    private fun wordMode() {
        cardUi()
        loadWordFile()
    }

    private fun logFileMode() {
        cardUi()
        loadLogFile()
    }

    private fun zipMode() {
        cardUi()
        loadZipFile()
    }

    private fun apkMode() {
        cardUi()
        loadApkFile()
    }

    private fun audioMode() {
        cardUi()
        loadAudioFile()
    }

    private fun videoMode() {
        gridUi()
        loadVideoFile()
    }

    private fun imageMode() {
        gridUi()
        loadImageFile()
    }


    @SuppressLint("SetTextI18n")
    private fun loadLargeFile() {
        val dialog = showLoadingDialog()
        cardFileAdapter.clearData()
        var doLaunch = false
        val waitList = ArrayList<FileBean>()
        largeFile(
            lifecycleScope,
            onDo = { data ->
                if (doLaunch) {
                    doLaunch = true
                    lifecycleScope.launch(Dispatchers.Main) {
                        dialog.dismiss()
                        cardFileAdapter.addData(data)
                    }
                } else {
                    waitList.addAll(data)
                }
            },
            onFinish = { data, count ->
                lifecycleScope.launch(Dispatchers.Main) {
                    dialog.dismiss()
                    waitList.addAll(data)
                    cardFileAdapter.addData(waitList)
                    binding.tvTip1.text = "$count items"
                    binding.ivAll.isSelected = false
                    showEmptyUi()
                    saveFileCount(LARGE_FILES_COUNTER_KEY, count)
                }
            }
        )

    }

    @SuppressLint("SetTextI18n")
    private fun loadWordFile() {
        val dialog = showLoadingDialog()
        cardFileAdapter.clearData()
        var doLaunch = false
        val waitList = ArrayList<FileBean>()
        lifecycleScope.launch(Dispatchers.IO) {
            wordFile(
                onDo = { data ->
                    if (doLaunch) {
                        doLaunch = true
                        lifecycleScope.launch(Dispatchers.Main) {
                            dialog.dismiss()
                            cardFileAdapter.addData(data)
                        }
                    } else {
                        waitList.addAll(data)
                    }
                },
                onFinish = { data, count ->
                    lifecycleScope.launch(Dispatchers.Main) {
                        dialog.dismiss()
                        waitList.addAll(data)
                        cardFileAdapter.addData(waitList)
                        binding.tvTip1.text = "$count items"
                        binding.ivAll.isSelected = false
                        showEmptyUi()
                    }
                }
            )
        }
    }


    @SuppressLint("SetTextI18n")
    private fun loadVideoFile() {
        val dialog = showLoadingDialog()
        fileGridAdapter.clearData()
        var doLaunch = false
        val waitList = ArrayList<FileBean>()
        lifecycleScope.launch(Dispatchers.IO) {
            videoFile(
                onDo = { data ->
                    if (doLaunch) {
                        doLaunch = true
                        lifecycleScope.launch(Dispatchers.Main) {
                            dialog.dismiss()
                            fileGridAdapter.addData(data)
                        }
                    } else {
                        waitList.addAll(data)
                    }
                },
                onFinish = { data, count ->
                    lifecycleScope.launch(Dispatchers.Main) {
                        dialog.dismiss()
                        waitList.addAll(data)
                        fileGridAdapter.addData(waitList)
                        binding.tvTip1.text = "$count items"
                        binding.ivAll.isSelected = false
                        showEmptyUi()
                    }
                }
            )
        }
    }

    private fun largeFileMode() {
        cardUi()
        loadLargeFile()
    }


    private fun deleteCardFile(files: List<FileBean>) = lifecycleScope.launch(Dispatchers.Main) {
        asyDeleteFiles(files).await()
        cardFileAdapter.removeData(files)
        binding.ivAll.isSelected = false
        cardFileAdapter.toggleSelect(false)
    }

    private fun deleteGridUiFile(files: List<FileBean>) = lifecycleScope.launch(Dispatchers.Main) {
        asyDeleteFiles(files).await()
        fileGridAdapter.removeData(files)
        binding.ivAll.isSelected = false
        fileGridAdapter.toggleSelect(false)
    }

    private fun asyDeleteFiles(files: List<FileBean>) = lifecycleScope.async(Dispatchers.IO) {
        deleteFiles(files.map { it.file() })
    }


    @SuppressLint("SetTextI18n")
    private fun loadAudioFile() {
        val dialog = showLoadingDialog()
        cardFileAdapter.clearData()
        var doLaunch = false
        val waitList = ArrayList<FileBean>()
        lifecycleScope.launch(Dispatchers.IO) {
            audioFile(
                onDo = { data ->
                    if (doLaunch) {
                        doLaunch = true
                        lifecycleScope.launch(Dispatchers.Main) {
                            dialog.dismiss()
                            cardFileAdapter.addData(data)
                        }
                    } else {
                        waitList.addAll(data)
                    }
                },
                onFinish = { data, count ->
                    lifecycleScope.launch(Dispatchers.Main) {
                        dialog.dismiss()
                        waitList.addAll(data)
                        cardFileAdapter.addData(waitList)
                        binding.tvTip1.text = "$count items"
                        binding.ivAll.isSelected = false
                        showEmptyUi()
                    }
                }
            )
        }
    }

    @SuppressLint("SetTextI18n")
    private fun loadApkFile() {
        val dialog = showLoadingDialog()
        cardFileAdapter.clearData()
        var doLaunch = false
        val waitList = ArrayList<FileBean>()
        lifecycleScope.launch(Dispatchers.IO) {
            apkFile(
                onDo = { data ->
                    if (doLaunch) {
                        doLaunch = true
                        lifecycleScope.launch(Dispatchers.Main) {
                            dialog.dismiss()
                            cardFileAdapter.addData(data)
                        }
                    } else {
                        waitList.addAll(data)
                    }
                },
                onFinish = { data, count ->
                    lifecycleScope.launch(Dispatchers.Main) {
                        dialog.dismiss()
                        waitList.addAll(data)
                        cardFileAdapter.addData(waitList)
                        binding.tvTip1.text = "$count items"
                        binding.ivAll.isSelected = false
                        showEmptyUi()
                    }
                }
            )
        }
    }

    @SuppressLint("SetTextI18n")
    private fun loadZipFile() {
        val dialog = showLoadingDialog()
        cardFileAdapter.clearData()
        var doLaunch = false
        val waitList = ArrayList<FileBean>()
        lifecycleScope.launch(Dispatchers.IO) {
            zipFile(
                onDo = { data ->
                    if (doLaunch) {
                        doLaunch = true
                        lifecycleScope.launch(Dispatchers.Main) {
                            dialog.dismiss()
                            cardFileAdapter.addData(data)
                        }
                    } else {
                        waitList.addAll(data)
                    }
                },
                onFinish = { data, count ->
                    lifecycleScope.launch(Dispatchers.Main) {
                        dialog.dismiss()
                        waitList.addAll(data)
                        cardFileAdapter.addData(waitList)
                        binding.tvTip1.text = "$count items"
                        binding.ivAll.isSelected = false
                        showEmptyUi()
                    }
                }
            )
        }
    }

    @SuppressLint("SetTextI18n")
    private fun loadLogFile() {
        val dialog = showLoadingDialog()
        cardFileAdapter.clearData()
        var doLaunch = false
        val waitList = ArrayList<FileBean>()
        lifecycleScope.launch(Dispatchers.IO) {
            logFile(
                onDo = { data ->
                    if (doLaunch) {
                        doLaunch = true
                        lifecycleScope.launch(Dispatchers.Main) {
                            dialog.dismiss()
                            Log.e("TAG", data.toString())
                            cardFileAdapter.addData(data)
                        }
                    } else {
                        waitList.addAll(data)
                    }
                },
                onFinish = { data, count ->
                    lifecycleScope.launch(Dispatchers.Main) {
                        dialog.dismiss()
                        waitList.addAll(data)
                        cardFileAdapter.addData(waitList)
                        binding.tvTip1.text = "$count items"
                        binding.ivAll.isSelected = false
                        showEmptyUi()
                    }
                }
            )
        }
    }

    private fun emptyFileMode() {
        cardUi()
        loadEmptyFile()
    }

    @SuppressLint("SetTextI18n")
    private fun loadEmptyFile() {
        val dialog = showLoadingDialog()
        cardFileAdapter.clearData()
        var doLaunch = false
        val waitList = ArrayList<FileBean>()
        lifecycleScope.launch(Dispatchers.IO) {
            emptyFile(
                onDo = { data ->
                    if (doLaunch) {
                        doLaunch = true
                        lifecycleScope.launch(Dispatchers.Main) {
                            dialog.dismiss()
                            cardFileAdapter.addData(data)
                        }
                    } else {
                        waitList.addAll(data)
                    }
                },
                onFinish = { data, count ->
                    lifecycleScope.launch(Dispatchers.Main) {
                        dialog.dismiss()
                        waitList.addAll(data)
                        cardFileAdapter.addData(waitList)
                        binding.tvTip1.text = "$count items"
                        binding.ivAll.isSelected = false
                        showEmptyUi()
                        saveFileCount(EMPTY_FILE_COUNTER_KEY, count)
                    }
                }
            )
        }
    }

    private fun dupImageMode() {
        binding.tvTip1.visibility = View.GONE
        binding.tvTip2.visibility = View.GONE
        binding.llAll.setOnClickListener {
            it.isSelected = !it.isSelected
            dupImageAdapter.toggleSelect(it.isSelected)
        }
        dupImageAdapter = DupImageAdapter(
            selectClick = { binding.ivAll.isSelected = it },
            itemClick = { path ->
                startActivity(Intent(this, FileDetailActivity::class.java).apply {
                    putExtra("Path", path)
                })
            }
        )
        binding.rv.adapter = dupImageAdapter
        binding.tvDelete.background =
            ContextCompat.getDrawable(this, R.drawable.bg_ff5c67e5_corners)
        binding.tvDelete.text = "Delete"
        binding.tvDelete.setTextColor(ContextCompat.getColor(this, R.color.white))
        binding.tvDelete.setOnClickListener {
            val files = dupImageAdapter.getSelectFile()
            lifecycleScope.launch(Dispatchers.Main) {
                async {
                    deleteFiles(files)
                }.await()
                loadDupImage()
            }
        }

        loadDupImage()
    }

    private fun loadDupImage() {
        val dialog = showLoadingDialog()
        lifecycleScope.launch(Dispatchers.IO) {
            val data = dupImage()
            launch(Dispatchers.Main) {
                dialog.dismiss()
                dupImageAdapter.setData(data)
                binding.ivAll.isSelected = false
                showEmptyUi()

                saveFileCount(DUP_IMAGE_COUNTER_KEY, data.sumOf { it.dupData.size })
            }
        }
    }

    private fun showEmptyUi() {
        var show = false
        if (this::dupImageAdapter.isInitialized) {
            show = dupImageAdapter.itemCount == 0
        }
        if (this::cardFileAdapter.isInitialized) {
            show = cardFileAdapter.itemCount == 0
        }
        if (this::fileGridAdapter.isInitialized) {
            show = fileGridAdapter.itemCount == 0
        }
        if (show) {
            binding.rv.visibility = View.INVISIBLE
            binding.ivEmpty.visibility = View.VISIBLE

            binding.llAll.visibility = View.INVISIBLE
            binding.tvDelete.visibility = View.INVISIBLE
        } else {
            binding.rv.visibility = View.VISIBLE
            binding.ivEmpty.visibility = View.INVISIBLE

            binding.llAll.visibility = View.VISIBLE
            binding.tvDelete.visibility = View.VISIBLE
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        finish()
    }

    override fun onRestart() {
        super.onRestart()
        if (storePermissionCheck()) {
            isPermissionSet(false)
            showBrowser()
        }
    }

    private fun isPermissionSet(show: Boolean) {
        if (show) {
            binding.clPermission.visibility = View.VISIBLE
            binding.clContent.visibility = View.INVISIBLE
            binding.llAll.visibility = View.INVISIBLE
            binding.tvSet.setOnClickListener {
                requestStoreFollow(activityLauncher,
                    disAgreeAction = {

                    }, agreeAction = {
                        showBrowser()
                    })
            }
        } else {
            binding.clPermission.visibility = View.GONE
            binding.clContent.visibility = View.VISIBLE
            binding.llAll.visibility = View.VISIBLE
        }
    }
}