package com.zxhy.fastfilemanagerpro.kokoInternalstorage

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.os.Environment
import android.view.KeyEvent
import android.view.View
import androidx.activity.enableEdgeToEdge
import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.content.FileProvider
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.lifecycleScope
import com.zxhy.fastfilemanagerpro.R
import com.zxhy.fastfilemanagerpro.databinding.ActivityKoInternalkoBinding
import com.zxhy.fastfilemanagerpro.kokodata.KoFileDatako.Companion.koFileDatako
import com.zxhy.fastfilemanagerpro.kokodata.KoFileDatako.Companion.toFile
import com.zxhy.fastfilemanagerpro.kokodialog.FileNameDialog.showFileNameDialog
import com.zxhy.fastfilemanagerpro.kokotools.ActivityLauncher
import com.zxhy.fastfilemanagerpro.kokotools.permission.PermissionCheck.storePermissionCheck
import com.zxhy.fastfilemanagerpro.kokotools.permission.StorePermissionEx.requestStoreFollow
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.io.File

class KoInternalkoActivity : AppCompatActivity() {

    private lateinit var binding: ActivityKoInternalkoBinding
    private val viewModel: KoInternalkoViewModel by viewModels()
    private lateinit var adapter: KoInternalkoAdapter
    private lateinit var activityLauncher: ActivityLauncher
    private lateinit var context: Context
    private var currentMode = BROWSER_MODE
    private var showEmpty: Boolean = false

    @SuppressLint("SetTextI18n")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        enableEdgeToEdge()
        context = this
        activityLauncher = ActivityLauncher(this)
        binding = ActivityKoInternalkoBinding.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
        }
        adapter = KoInternalkoAdapter(context,
            allSelect = {
                binding.ivAllSelector.isSelected = it
                enableOperationItem()
            },
            pageCount = {
                binding.tvItems.text = "total:$it items"
                if (it == 0) {
                    showEmptyList(true)
                }
            }
        )
        binding.rv.adapter = adapter
        binding.ivAllSelector.setOnClickListener {
            it.isSelected = !it.isSelected
            adapter.toggleSelect(it.isSelected)
            enableOperationItem()
        }

        if (storePermissionCheck()) {
            showPermissionSet(false)
            loadInternalStorage()
        } else {
            showPermissionSet(true)
        }
    }

    @SuppressLint("SetTextI18n")
    private fun loadInternalStorage() {
        val root = Environment.getExternalStorageDirectory()
        val data = root.listFiles()?.map { it.koFileDatako(context) } ?: listOf()
        adapter.setData(data)
        browserMode()
        binding.tvItems.text = "total:${adapter.itemCount} items"
    }

    private fun browserMode() {
        currentMode = BROWSER_MODE
        adapter.setCanPage(true)
        binding.llEditSelect.visibility = View.VISIBLE
        binding.tvEdit.visibility = View.VISIBLE
        binding.ivAllSelector.visibility = View.GONE
        binding.tvAll.visibility = View.GONE
        binding.clOperation.visibility = View.GONE
        binding.tvEdit.setOnClickListener {
            operationMode()
        }
        binding.ivAllSelector.isSelected = false
        adapter.showSelectMode(false)
    }

    private fun operationMode() {
        currentMode = OPERATION_MODE
        adapter.setCanPage(false)
        binding.llEditSelect.visibility = View.VISIBLE
        binding.tvEdit.visibility = View.GONE
        binding.ivAllSelector.visibility = View.VISIBLE
        binding.ivAllSelector.isSelected = false
        binding.tvAll.visibility = View.VISIBLE

        binding.clOperation.visibility = View.VISIBLE
        binding.llOperation.visibility = View.VISIBLE
        binding.clOperationConfirm.visibility = View.GONE

        adapter.showSelectMode(true)
        enableOperationItem()
        binding.llShare.setOnClickListener {
            val list = adapter.getSelectData()
            val arrayList = ArrayList<Uri>()
            list.forEach {
                val uri =
                    FileProvider.getUriForFile(context, "$packageName.provider", File(it.path))
                arrayList.add(uri)
            }
            val intent = Intent().apply {
                action = "android.intent.action.SEND_MULTIPLE"
                type = "image/*"
                putExtra("android.intent.extra.STREAM", arrayList)
                flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
            }
            startActivity(Intent.createChooser(intent, null))
        }
        binding.llRename.setOnClickListener {
            val list = adapter.getSelectData()
            if (list.isNotEmpty()) {
                val selectFile = list.first().toFile()
                showFileNameDialog(selectFile) { name ->
                    viewModel.renameFile(selectFile, name) {
                        lifecycleScope.launch(Dispatchers.Main) {
                            showOperationResult("Rename successful!")
                            adapter.clearCannotDir()
                            adapter.notifyCurrentDir()
                            browserMode()
                        }
                    }
                }
            }

        }
        binding.llDelete.setOnClickListener {
            val list = adapter.getSelectData().map { it.toFile() }
            viewModel.deleteFileOrDir(list) {
                lifecycleScope.launch(Dispatchers.Main) {
                    showOperationResult()
                    adapter.notifyCurrentDir()
                    browserMode()
                }
            }
        }
        binding.llCopy.setOnClickListener {
            val data = adapter.getSelectData().map { it.toFile() }
            operationConfirmMode(OPERATION_COPY, data)
        }
        binding.llMove.setOnClickListener {
            val data = adapter.getSelectData().map { it.toFile() }
            operationConfirmMode(OPERATION_MOVE, data)
        }
    }

    @SuppressLint("SetTextI18n")
    private fun operationConfirmMode(operation: String, data: List<File>) {
        currentMode = OPERATION_CONFIRM_MODE
        binding.llEditSelect.visibility = View.GONE
        adapter.setCanPage(true)

        binding.clOperation.visibility = View.VISIBLE
        binding.llOperation.visibility = View.GONE
        binding.clOperationConfirm.visibility = View.VISIBLE

        adapter.showSelectMode(false, false)
        adapter.setCannotDir(data)
        adapter.pageRoot()
        binding.tvConfirmItems.text = "${data.size} items"

        when (operation) {
            OPERATION_COPY -> {
                binding.tvConfirm.text = "Copy"
                binding.tvConfirm.setOnClickListener {
                    val destDir = adapter.getCurrentDir()
                    viewModel.copyFiles(data, destDir) {
                        lifecycleScope.launch(Dispatchers.Main) {
                            showOperationResult("Copy successful!")
                            adapter.clearCannotDir()
                            adapter.notifyCurrentDir()
                            browserMode()
                        }
                    }
                }
            }

            OPERATION_MOVE -> {
                binding.tvConfirm.text = "Motion"
                binding.tvConfirm.setOnClickListener {
                    val destDir = adapter.getCurrentDir()
                    viewModel.moveFiles(data, destDir) {
                        lifecycleScope.launch(Dispatchers.Main) {
                            showOperationResult("Move successful!")
                            adapter.clearCannotDir()
                            adapter.notifyCurrentDir()
                            browserMode()
                        }
                    }
                }
            }
        }
        binding.tvCancel.setOnClickListener {
            adapter.clearCannotDir()
            browserMode()
        }
    }

    override fun dispatchKeyEvent(event: KeyEvent): Boolean {

        if (event.keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP) {

            if (showEmpty) {
                showEmptyList(false)
            }

            when (currentMode) {
                BROWSER_MODE -> {
                    if (adapter.pageBefore()) super.dispatchKeyEvent(event) else return false
                }

                OPERATION_MODE -> {
                    browserMode()
                    return false
                }

                OPERATION_CONFIRM_MODE -> {
                    if (adapter.pageBefore()) super.dispatchKeyEvent(event) else return false
                }
            }
        }
        return super.dispatchKeyEvent(event)
    }

    //region 公共代码
    private fun showPermissionSet(show: Boolean) {
        if (show) {
            binding.clContent.visibility = View.GONE
            binding.clPermissionSet.visibility = View.VISIBLE
            window.statusBarColor = ContextCompat.getColor(context, R.color.color_b3000000)
            binding.tvSet.setOnClickListener {
                requestStoreFollow(activityLauncher, disAgreeAction = {
                    showPermissionSet(true)
                }, agreeAction = {
                    showPermissionSet(false)
                    loadInternalStorage()
                })
            }
        } else {
            binding.clContent.visibility = View.VISIBLE
            binding.clPermissionSet.visibility = View.GONE
            window.statusBarColor = ContextCompat.getColor(context, R.color.white)
        }

    }

    private fun showOperationResult(tips: String = "Delete successful!") =
        lifecycleScope.launch(Dispatchers.Main) {
            binding.tvOperationResult.text = tips
            binding.llResult.visibility = View.VISIBLE
            delay(500)
            binding.llResult.visibility = View.GONE
        }

    private fun showEmptyList(show: Boolean) {
        showEmpty = show
        if (show) {
            binding.clEmpty.visibility = View.VISIBLE
            binding.clShowContent.visibility = View.GONE
            binding.llEditSelect.visibility = View.GONE
        } else {
            binding.clEmpty.visibility = View.GONE
            binding.clShowContent.visibility = View.VISIBLE
            if (currentMode == BROWSER_MODE) {
                binding.llEditSelect.visibility = View.VISIBLE
            }
        }
    }

    private fun enableOperationItem() {
        val selectData = adapter.getSelectData()
        if (selectData.isEmpty()) {
            binding.llShare.isEnabled = false
            binding.llDelete.isEnabled = false
            binding.llCopy.isEnabled = false
            binding.llMove.isEnabled = false
            binding.llRename.isEnabled = false
        } else if (selectData.size == 1) {
            binding.llShare.isEnabled = true
            binding.llDelete.isEnabled = true
            binding.llCopy.isEnabled = true
            binding.llMove.isEnabled = true
            binding.llRename.isEnabled = true
            binding.llRename.visibility = View.VISIBLE
        } else {
            binding.llShare.isEnabled = true
            binding.llDelete.isEnabled = true
            binding.llCopy.isEnabled = true
            binding.llMove.isEnabled = true
            binding.llRename.isEnabled = false
            binding.llRename.visibility = View.GONE
        }
    }

    //endregion


    companion object {
        const val OPERATION_COPY = "operation_copy"
        const val OPERATION_MOVE = "operation_move"
        const val BROWSER_MODE = "browser_mode"
        const val OPERATION_MODE = "operation_mode"
        const val OPERATION_CONFIRM_MODE = "operation_confirm_mode"
    }
}