package com.zxhy.solarmasterace.internalstorage

import android.os.Bundle
import android.os.Environment
import android.view.KeyEvent
import android.view.View
import androidx.activity.enableEdgeToEdge
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.lifecycleScope
import com.zxhy.solarmasterace.R
import com.zxhy.solarmasterace.data.toFileBean
import com.zxhy.solarmasterace.databinding.ActivityInternalStorageBinding
import com.zxhy.solarmasterace.dialog.showFolderDetailDialog
import com.zxhy.solarmasterace.dialog.showFolderDialog
import com.zxhy.solarmasterace.permission.requestStoreFollow
import com.zxhy.solarmasterace.popupwindow.showPopupMoreOperation
import com.zxhy.solarmasterace.quicktools.ActivityLauncher
import com.zxhy.solarmasterace.quicktools.FileHelper
import com.zxhy.solarmasterace.quicktools.storePermissionCheck
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.io.File

class InternalStorageActivity : AppCompatActivity() {
    private lateinit var binding: ActivityInternalStorageBinding
    private lateinit var fileDirectoryAdapter: FileDirectoryAdapter
    private val MODE_BROWSE = 0
    private val MODE_SELECT = 1
    private val MODE_SELECTED_OPERATION = 2
    private var currentMode = MODE_BROWSE //0普通浏览模式  1可选模式  2选中操作模式
    private lateinit var activityLauncher: ActivityLauncher

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        activityLauncher = ActivityLauncher(this)
        binding = ActivityInternalStorageBinding.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
        }
        if (storePermissionCheck()) {
            showContent()
        } else {
            isPermissionSet(true)
        }

        binding.clArrow.setOnClickListener {
            if (this::fileDirectoryAdapter.isInitialized) {
                val flag = fileDirectoryAdapter.beforePage()
                if (flag)
                    finish()
            }
        }
    }

    private fun showContent() {
        isPermissionSet(false)
        fileDirectoryAdapter = FileDirectoryAdapter(
            selectClick = { binding.ivAll.isSelected = it }, showEmpty = { flag ->
                if (flag) {
                    binding.rv.visibility = View.INVISIBLE
                    binding.ivEmpty.visibility = View.VISIBLE
                } else {
                    binding.rv.visibility = View.VISIBLE
                    binding.ivEmpty.visibility = View.INVISIBLE
                }
            }
        )
        binding.rv.adapter = fileDirectoryAdapter
        initData()

        switchBrowseMode()
    }

    private fun switchBrowseMode() {
        currentMode = MODE_BROWSE
        binding.ivAdd.visibility = View.VISIBLE
        fileDirectoryAdapter.toggleSelect(false)
        fileDirectoryAdapter.showSelect(false)
        fileDirectoryAdapter.setPageTurn(true)

        binding.llAll.visibility = View.GONE
        binding.ivWrite.visibility = View.VISIBLE
        binding.ivWrite.setOnClickListener {
//            showFolderDialog(tittle = "New Folder", newFolder = { name ->
//                val dir = fileDirectoryAdapter.getCurrentDir()
//                val file = File(dir, name)
//                if (!file.exists()) {
//                    file.mkdir()
//                }
//                fileDirectoryAdapter.notifyCurrentDir()
//            })

            switchSelectMode()
        }
        binding.ivAdd.setOnClickListener {
//            switchSelectMode()

            showFolderDialog(tittle = "New Folder", newFolder = { name ->
                val dir = fileDirectoryAdapter.getCurrentDir()
                val file = File(dir, name)
                if (!file.exists()) {
                    file.mkdir()
                }
                fileDirectoryAdapter.notifyCurrentDir()
            })
        }
        binding.ivMore.setOnClickListener {
            val fileBeanList = fileDirectoryAdapter.getSelectData()
            val fileList = fileBeanList.map { it.file() }
            val size = fileList.size
            if (size == 0) return@setOnClickListener
            showPopupMoreOperation(
                this, binding.clOperation, size,
                renameAction = {
                    val reNameFile = fileList.first()
                    showFolderDialog(reNameFile.name, "Rename", reName = { name ->
                        reNameFile.renameTo(File(reNameFile.parentFile, name))
                        fileDirectoryAdapter.notifyCurrentDir()
                        showCardTip("success renamed!")
                        switchBrowseMode()
                    })
                },
                detailAction = {
                    showFolderDetailDialog(this, fileBeanList.first())
                },
                shareAction = {}
            )
        }
        binding.clOperation.visibility = View.GONE
        binding.clConfirm.visibility = View.GONE
    }

    private fun switchSelectMode() {
        currentMode = MODE_SELECT
        binding.ivAdd.visibility = View.GONE
        binding.llAll.isSelected = false
        fileDirectoryAdapter.toggleSelect(false)
        fileDirectoryAdapter.showSelect(true)
        fileDirectoryAdapter.setPageTurn(false)

        binding.llAll.visibility = View.VISIBLE
        binding.ivWrite.visibility = View.GONE

        binding.llAll.setOnClickListener {
            it.isSelected = !it.isSelected
            fileDirectoryAdapter.toggleSelect(it.isSelected)
        }
        binding.clOperation.visibility = View.VISIBLE
        binding.clConfirm.visibility = View.GONE

        binding.ivDelete.setOnClickListener {
            val files = fileDirectoryAdapter.getSelectData().map { it.file() }
            deleteFiles(files) {
                showCardTip("Successfully deleted!")
                switchBrowseMode()
            }
        }
        binding.ivMove.setOnClickListener {
            val moveFile = arrayListOf<File>()
            val selectList = fileDirectoryAdapter.getSelectData()
            selectList.map { moveFile.add(it.file()) }
            fileDirectoryAdapter.notifyCannotSelect(selectList)
            switchSelectedOperationMode("Motion", moveFile)
        }
        binding.ivCopy.setOnClickListener {
            val copyFile = arrayListOf<File>()
            val selectList = fileDirectoryAdapter.getSelectData()
            selectList.map { copyFile.add(it.file()) }
            fileDirectoryAdapter.notifyCannotSelect(selectList)
            switchSelectedOperationMode("Copy", copyFile)
        }
    }

    private fun showCardTip(tips: String) = lifecycleScope.launch(Dispatchers.Main) {
        binding.tvTip.text = tips
        binding.cardSuccess.visibility = View.VISIBLE
        delay(1000)
        binding.cardSuccess.visibility = View.INVISIBLE
    }

    private fun switchSelectedOperationMode(function: String, files: List<File>) {
        currentMode = MODE_SELECTED_OPERATION
        binding.ivAll.isSelected = false
        fileDirectoryAdapter.toggleSelect(false)
        fileDirectoryAdapter.showSelect(false)
        fileDirectoryAdapter.setPageTurn(true)

        binding.clOperation.visibility = View.GONE
        binding.clConfirm.visibility = View.VISIBLE

        binding.tvDefine.text = function
        when (function) {
            "Motion" -> {
                binding.tvDefine.setOnClickListener {
                    moveFiles(files) {
                        showCardTip("Successfully moved!")
                        fileDirectoryAdapter.clearCannotSelect()
                        switchBrowseMode()
                    }
                }
            }

            "Copy" -> {
                binding.tvDefine.setOnClickListener {
                    copyFiles(files) {
                        fileDirectoryAdapter.clearCannotSelect()
                        showCardTip("Successfully copied!")
                        switchBrowseMode()
                    }
                }
            }
        }
        binding.tvCancel.setOnClickListener {
            fileDirectoryAdapter.clearCannotSelect()
            switchBrowseMode()
        }
    }

    private fun copyFiles(files: List<File>, finish: (() -> Unit)? = null) =
        lifecycleScope.launch(Dispatchers.Main) {
            async {
                val dir = fileDirectoryAdapter.getCurrentDir() ?: File("")
                files.forEach {
                    if (it.isFile) {
                        val destFile = File(dir, it.name)
                        if (!destFile.exists()) {
                            it.copyTo(destFile)
                        }
                    } else {
                        FileHelper.copyDirectory(it, File(dir, it.name))
                    }
                }
            }.await()

            fileDirectoryAdapter.notifyCurrentDir()
            finish?.invoke()
        }

    private fun moveFiles(files: List<File>, finish: (() -> Unit)? = null) =
        lifecycleScope.launch(Dispatchers.Main) {
            async(Dispatchers.IO) {
                val dir = fileDirectoryAdapter.getCurrentDir() ?: File("")
                files.map {
                    if (it.isFile) {
                        it.copyTo(File(dir, it.name))
                        it.delete()
                    } else {
                        FileHelper.copyDirectory(it, File(dir, it.name))
                        FileHelper.deleteDirectory(it)
                    }
                }
            }.await()
            fileDirectoryAdapter.notifyCurrentDir()
            finish?.invoke()
        }

    private fun deleteFiles(files: List<File>, finish: (() -> Unit)? = null) =
        lifecycleScope.launch(Dispatchers.Main) {
            async(Dispatchers.IO) {
                files.map {
                    try {
                        if (it.isFile) it.delete() else FileHelper.deleteDirectory(it)
                    } catch (e: Exception) {
                        e.printStackTrace()
                    }
                }
            }.await()
            fileDirectoryAdapter.notifyCurrentDir()
            finish?.invoke()
        }

    private fun initData() {
        val root = Environment.getExternalStorageDirectory()
        val list = root.listFiles()?.map { it.toFileBean() } ?: listOf()
        fileDirectoryAdapter.setData(list)
    }

    override fun dispatchKeyEvent(event: KeyEvent): Boolean {

        if (event.keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP) {
            when (currentMode) {
                MODE_BROWSE -> {
                    var flag = true
                    if (this::fileDirectoryAdapter.isInitialized) {
                        flag = fileDirectoryAdapter.beforePage()
                    }
                    return if (flag) super.dispatchKeyEvent(event) else false
                }

                MODE_SELECT -> {
                    switchBrowseMode()
                    return false
                }

                MODE_SELECTED_OPERATION -> {
                    val flag = fileDirectoryAdapter.beforePage()
                    return if (flag) super.dispatchKeyEvent(event) else false
                }
            }
        }
        return super.dispatchKeyEvent(event)
    }

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

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


