package com.zxhy.hfilemanagermaster.internalstorage

import android.annotation.SuppressLint
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.util.Log
import android.view.KeyEvent
import android.view.KeyEvent.ACTION_UP
import android.view.MotionEvent
import android.view.View
import android.widget.PopupWindow
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 com.example.hfilemanagermaster.R
import com.example.hfilemanagermaster.databinding.ActivityInternalStorageBinding
import com.example.hfilemanagermaster.databinding.PopupwindowMoreOperationBinding
import com.zxhy.hfilemanagermaster.data.MediaDataC
import com.zxhy.hfilemanagermaster.data.file2MediaDataC
import com.zxhy.hfilemanagermaster.dialog.showFileDetailsDialog
import com.zxhy.hfilemanagermaster.dialog.showFileNameDialog
import com.zxhy.hfilemanagermaster.dialog.showOperationDialog
import com.zxhy.hfilemanagermaster.knife.Saf
import com.zxhy.hfilemanagermaster.knife.deleteDirectory
import com.zxhy.hfilemanagermaster.knife.fileProviderUri
import com.zxhy.hfilemanagermaster.knife.toast
import com.zxhy.hfilemanagermaster.permission.IntentLauncher
import com.zxhy.hfilemanagermaster.permission.PermissionLauncher
import com.zxhy.hfilemanagermaster.permission.requestStoreFollow
import com.zxhy.hfilemanagermaster.permission.settingManageExternalStorage
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.io.File

// 额外储存管理权限，读几个图片和视频
@SuppressLint("SetTextI18n")
class InternalStorageActivity : AppCompatActivity() {

    private lateinit var binding: ActivityInternalStorageBinding
    private lateinit var saf: Saf
    private lateinit var intentLauncher: IntentLauncher
    private lateinit var permissionLauncher: PermissionLauncher
    private lateinit var fileAdapter: FileAdapter
    private val browseMode = 0
    private val selectMode = 1
    private val selectedOperationMode = 2
    private val lockMode = -1
    private var currentMode = lockMode //0普通浏览模式  1可选模式  2选中操作模式 -1无权限锁功能模式

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        saf = Saf(this)
        permissionLauncher = PermissionLauncher(this)
        intentLauncher = IntentLauncher(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
        }
        window.statusBarColor = ContextCompat.getColor(this, R.color.color_C2F300)
        binding.ivArrow.setOnClickListener {
            finish()
        }
        binding.tvSet.setOnClickListener {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                if (!Environment.isExternalStorageManager()) {
                    val uri = Uri.parse("package:$packageName")
                    val intent = settingManageExternalStorage(uri)
                    intentLauncher.launch(intent) {
                        val flag = Environment.isExternalStorageManager()
                        if (flag) {
                            fileMode()
                        } else {
                            lockMode()
                        }
                    }
                } else {
                    fileMode()
                }
            } else {
                requestStoreFollow(permissionLauncher, intentLauncher) { fileMode() }
            }
        }

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            if (Environment.isExternalStorageManager()) {
                fileMode()
            } else {
                lockMode()
            }
        } else {
            requestStoreFollow(
                permissionLauncher,
                intentLauncher
            ) {
                fileMode()
            }
        }
    }

    private fun fileMode() {
        binding.clLock.visibility = View.GONE
        binding.clShow.visibility = View.VISIBLE
        fileAdapter =
            FileAdapter(
                selectAction = { binding.ivAll.isSelected = it },
                nextPageAction = {
                    binding.tvDir.text = it.absolutePath
                    isEmptyUi()
                },
                beforePageAction = {
                    binding.tvDir.text = it.absolutePath
                    isEmptyUi()
                }
            )

        binding.ivAll.setOnClickListener {
            if (currentMode == selectMode) {
                it.isSelected = fileAdapter.setToggleSelect()
            }
        }
        binding.ivNewFolder.setOnClickListener {
            showFileNameDialog("New Folder",
                sureAction = { name ->
                    val currentDir = fileAdapter.getCurrentDir()
                    val file = File(currentDir, name)
                    if (file.exists()) {
                        toast("can't create exists folder")
                    } else {
                        val flag = file.mkdirs()
                        if (flag) {
                            fileAdapter.notifyCurrentDir(this)
                            isEmptyUi()
                        } else {
                            toast("create folder failed!")
                            browseMode()
                        }
                    }
                },
                dismissAction = {})
        }
        binding.rv.adapter = fileAdapter
        browseMode()
        loadFile()
    }

    private fun loadFile() {
        lifecycleScope.launch(Dispatchers.IO) {
            val rootList = Environment.getExternalStorageDirectory().listFiles()
            val list = rootList?.map {
                it.file2MediaDataC(this@InternalStorageActivity)
            } ?: listOf()

            lifecycleScope.launch(Dispatchers.Main) {
                val dir = File(list.first().path).parentFile ?: File("")
                if (dir.exists() && dir.isDirectory) {
                    binding.tvDir.text = dir.absolutePath
                }
                fileAdapter.setData(list)
            }
        }
    }

    private fun lockMode() {
        currentMode = lockMode
        binding.clLock.visibility = View.VISIBLE
        binding.clShow.visibility = View.GONE

        binding.ivAll.visibility = View.GONE
        binding.tvAll.visibility = View.GONE
        binding.ivWrite.visibility = View.GONE
        binding.ivNewFolder.visibility = View.GONE
    }

    //可选择模式
    @SuppressLint("IntentReset")
    private fun selectMode() {
        currentMode = selectMode
        binding.ivWrite.visibility = View.GONE
        binding.ivNewFolder.visibility = View.VISIBLE

        binding.ivAll.visibility = View.VISIBLE
        binding.tvAll.visibility = View.VISIBLE

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

        binding.ivMove.setOnClickListener {
            val selectList = fileAdapter.getSelectFile()
            if (selectList.isEmpty()) return@setOnClickListener
            fileAdapter.showNoSelect()
            moveOperation(selectList)
        }
        binding.ivCopy.setOnClickListener {
            val selectList = fileAdapter.getSelectFile()
            if (selectList.isEmpty()) return@setOnClickListener
            fileAdapter.showNoSelect()
            copyOperation(selectList)
        }
        binding.ivShare.setOnClickListener {
            val selectList = fileAdapter.getSelectFile()
            if (selectList.size == 1) {
                Intent().apply {
                    val file = File(selectList.first().path)
                    if (file.exists()) {
                        if (file.isFile) {
                            action = Intent.ACTION_SEND
                            val uri = fileProviderUri(this@InternalStorageActivity, file)
                            setDataAndType(uri, "*/*")
                            startActivity(this)
                        } else {
                            toast("can't share Directory")
                        }
                    } else {
                        toast("share file don't exists")
                    }
                }
            } else {
                toast("Please select only one file!")
            }
        }
        binding.ivMore.setOnClickListener {
            if (fileAdapter.getSelectSize() == 0) return@setOnClickListener
            showPopupMoreOperation()
        }
    }

    //普通浏览模式
    private fun browseMode() {
        currentMode = browseMode
        binding.ivWrite.visibility = View.VISIBLE
        binding.ivNewFolder.visibility = View.VISIBLE

        binding.ivAll.visibility = View.GONE
        binding.tvAll.visibility = View.GONE

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

        binding.ivWrite.setOnClickListener {
            fileAdapter.showSelect()
            selectMode()
        }
        fileAdapter.notifyItemNoSelect()
    }

    private fun moveOperation(selectList: List<MediaDataC>) {
        currentMode = selectedOperationMode
        binding.clOperation.visibility = View.GONE
        binding.clConfirm.visibility = View.VISIBLE
        binding.ivAll.visibility = View.GONE
        binding.tvAll.visibility = View.GONE
        binding.tvDefine.text = "Motion"
        binding.tvCancel.setOnClickListener {
            browseMode()
        }
        binding.tvDefine.setOnClickListener {
            val dir = fileAdapter.getCurrentDir()
            moveFile(selectList, dir)
        }
    }

    private fun copyOperation(selectList: List<MediaDataC>) {
        currentMode = selectedOperationMode
        binding.clOperation.visibility = View.GONE
        binding.clConfirm.visibility = View.VISIBLE
        binding.ivAll.visibility = View.GONE
        binding.tvAll.visibility = View.GONE
        binding.tvDefine.text = "Copy"
        binding.tvCancel.setOnClickListener {
            browseMode()
        }
        binding.tvDefine.setOnClickListener {
            val dir = fileAdapter.getCurrentDir()
            copyFile(selectList, dir)
        }
    }

    @SuppressLint("NotifyDataSetChanged")
    private fun moveFile(selectList: List<MediaDataC>, dir: File) = Thread {

        try {
            selectList.forEach {
                val file = File(it.path)
                val fileName = file.name
                if (file.exists()) {
                    file.copyTo(File(dir, fileName))
                    file.delete()
                }
            }
            runOnUiThread {
                lifecycleScope.launch(Dispatchers.Main) {
                    val dialog = showOperationDialog(R.mipmap.er_89875, "motion success!") {}
                    delay(200)
                    dialog.dismiss()
                    fileAdapter.notifyCurrentDir(this@InternalStorageActivity)
                }
            }
        } catch (e: Exception) {
            runOnUiThread {
                this.toast("motion failed ")
                browseMode()
            }
        } finally {
            runOnUiThread { browseMode() }
        }
    }.start()

    private fun copyFile(selectList: List<MediaDataC>, dir: File) = Thread {
        try {
            selectList.forEach {
                val file = File(it.path)
                val fileName = file.name
                if (file.exists()) {
                    file.copyTo(File(dir, fileName))
                }
            }
            runOnUiThread {
                lifecycleScope.launch(Dispatchers.Main) {
                    val dialog = showOperationDialog(R.mipmap.qw_8796, "copy success!") {}
                    delay(200)
                    dialog.dismiss()
                    fileAdapter.notifyCurrentDir(this@InternalStorageActivity)
                }
            }
        } catch (e: Exception) {
            runOnUiThread {
                this.toast("copy failed ")
                browseMode()
            }
        } finally {
            runOnUiThread {
                browseMode()
            }
        }
    }.start()

    @SuppressLint("ClickableViewAccessibility", "InflateParams")
    private fun showPopupMoreOperation() {
        var yOff = 0
        var height = 0
        val size = fileAdapter.getSelectFile().size
        val popupWindowView = layoutInflater.inflate(R.layout.popupwindow_more_operation, null)
        val popupBinding = PopupwindowMoreOperationBinding.bind(popupWindowView)

        if (size == 1) {
            yOff = resources.getDimensionPixelSize(R.dimen.dp_160)
            height = resources.getDimensionPixelSize(R.dimen.dp_118)
        } else {
            popupBinding.llRename.visibility = View.GONE
            popupBinding.llDetails.visibility = View.GONE
            yOff = resources.getDimensionPixelSize(R.dimen.dp_90)
            height = resources.getDimensionPixelSize(R.dimen.dp_46)
        }

        val width =
            resources.getDimensionPixelSize(R.dimen.dp_118)
        val popupWindow = PopupWindow(popupWindowView, width, height, true)
        popupWindow.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        popupWindow.isOutsideTouchable = true
        popupWindow.isTouchable = true

        popupBinding.apply {
            llRename.setOnTouchListener { _, event ->

                when (event.action) {
                    MotionEvent.ACTION_DOWN -> {
                        popupBinding.ivRename.isSelected = true
                        popupBinding.tvRename.isSelected = true
                    }

                    MotionEvent.ACTION_UP -> {
                        popupBinding.ivRename.isSelected = false
                        popupBinding.tvRename.isSelected = false
                    }

                    else -> {}
                }
                false
            }
            tvRename.setOnClickListener {
                val list = fileAdapter.getSelectFile()
                if (list.size == 1) {
                    val file = File(list.first().path)
                    popupWindow.dismiss()
                    renameFile(file)
                } else {
                    toast("Please select only one file!")
                }
            }
            llDelete.setOnTouchListener { _, event ->
                when (event.action) {
                    MotionEvent.ACTION_DOWN -> {
                        popupBinding.ivDelete.isSelected = true
                        popupBinding.tvDelete.isSelected = true
                    }

                    MotionEvent.ACTION_UP -> {
                        popupBinding.ivDelete.isSelected = false
                        popupBinding.tvDelete.isSelected = false
                    }

                    else -> {}
                }
                false
            }
            tvDelete.setOnClickListener {
                val list = fileAdapter.getSelectFile()
                if (list.isEmpty()) return@setOnClickListener
                popupWindow.dismiss()
                deleteFiles(list)
            }
            llDetails.setOnTouchListener { _, event ->
                when (event.action) {
                    MotionEvent.ACTION_DOWN -> {
                        popupBinding.ivDetails.isSelected = true
                        popupBinding.tvDetails.isSelected = true
                    }

                    MotionEvent.ACTION_UP -> {
                        popupBinding.ivDetails.isSelected = false
                        popupBinding.tvDetails.isSelected = false
                    }

                    else -> {}
                }
                false
            }
            tvDetails.setOnClickListener {

                val list = fileAdapter.getSelectFileIndex()
                if (list.size == 1) {
                    val data = list.first()
                    val file = File(data.path)
                    if (file.exists()) {
                        popupWindow.dismiss()
                        showFileDetailsDialog("File details", file,
                            cancelAction = {
                                fileAdapter.notifyItemIndex(data)
                            }, dismissAction = {})
                    } else {
                        toast("file don't exist!")
                    }
                } else {
                    toast("Please select only one file!")
                }
            }

            popupWindow.showAsDropDown(binding.ivPlaceholder, 0, -yOff)

        }
    }

    private fun renameFile(file: File) {

        val dir = file.parentFile ?: File("")
        if (file.exists() && dir.exists()) {
            showFileNameDialog("Rename", sureAction = {
                try {
                    file.renameTo(File(dir, it))
                } catch (e: Exception) {
                    e.printStackTrace()
                    toast("Can't rename file!")
                }
                fileAdapter.notifyCurrentDir(this)
            }, dismissAction = {})
        } else {
            lifecycleScope.launch(Dispatchers.Main) {
                toast("Can't rename file!")
            }
        }
    }

    private fun deleteFiles(files: List<MediaDataC>) = Thread {
        try {
            files.forEach {
                val file = File(it.path)
                if (file.exists()) {
                    if (file.isFile) file.delete() else deleteDirectory(file)
                }
            }
            lifecycleScope.launch(Dispatchers.Main) {
                val dialog = showOperationDialog(R.mipmap.dads_889562, "delete success!") {}
                delay(200)
                dialog.dismiss()
                fileAdapter.removeData(files)
            }
        } catch (e: Exception) {
            e.printStackTrace()
            runOnUiThread {
                loadFile()
//                toast("delete failed")
            }
        }
    }.start()

    override fun dispatchKeyEvent(event: KeyEvent): Boolean {

        if (event.keyCode == KeyEvent.KEYCODE_BACK && event.action == ACTION_UP) {
            when (currentMode) {
                browseMode -> {
                    Log.e("dispatchKeyEvent", "currentMode=$browseMode")
                    var flag = false
                    if (event.keyCode == KeyEvent.KEYCODE_BACK && event.action == ACTION_UP) {
                        flag = fileAdapter.beforePage(this)
                    }
                    return if (flag) {
                        false
                    } else {
                        super.dispatchKeyEvent(event)
                    }
                }

                selectMode -> {
                    Log.e("dispatchKeyEvent", "currentMode=$selectMode")
                    browseMode()
                    fileAdapter.showNoSelect()
                    return false
                }

                selectedOperationMode -> {
                    Log.e("dispatchKeyEvent", "currentMode=$selectedOperationMode")
                    val flag = fileAdapter.beforePage(this)
                    return if (flag) {
                        false
                    } else {
                        super.dispatchKeyEvent(event)
                    }
                }

                lockMode -> {}
            }
        }

        return super.dispatchKeyEvent(event)

    }

    private fun isEmptyUi() {
        if (currentMode == selectedOperationMode) return
        val count = fileAdapter.itemCount
        if (count == 0) {
            binding.ivEmpty.visibility = View.VISIBLE
            binding.rv.visibility = View.INVISIBLE
            binding.clOperation.visibility = View.GONE
            binding.clConfirm.visibility = View.GONE
        } else {
            binding.ivEmpty.visibility = View.GONE
            binding.rv.visibility = View.VISIBLE
        }

    }

}