package com.base.easyfilemanager.activity

import android.annotation.SuppressLint
import android.graphics.Color
import android.os.Environment
import android.view.View
import androidx.activity.addCallback
import androidx.core.view.isVisible
import androidx.lifecycle.lifecycleScope
import com.base.easyfilemanager.adapter.FileManagerAdapter
import com.base.easyfilemanager.bean.FileBean
import com.base.easyfilemanager.databinding.ActivityFileManagerBinding
import com.base.easyfilemanager.helps.BaseActivity
import com.base.easyfilemanager.helps.FileHelps.deleteDirectory
import com.base.easyfilemanager.helps.ads.AdmobUtils
import com.base.easyfilemanager.utils.BarUtils
import com.base.easyfilemanager.view.AdPreparationPop
import com.base.easyfilemanager.view.FileDeleteDialog.showFileDeleteDialog
import com.base.easyfilemanager.view.SimpleFileDialog.showSimpleFileDialog
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.launch
import java.io.File

class FileManagerActivity : BaseActivity<ActivityFileManagerBinding>() {

    private var currentMode: Int = BROWSER_MODE

    companion object {
        const val BROWSER_MODE = 12
        const val OPERATION_MODE = 13
        const val CONFIRM_MODE = 18
    }

    override val binding: ActivityFileManagerBinding by lazy {
        ActivityFileManagerBinding.inflate(layoutInflater)
    }
    private val adapter by lazy {
        FileManagerAdapter(
            allSelect = {
                binding.ivAll.isSelected = it
            },
            showEmpty = {
                showEmpty(isEmpty = it, showWrite = !it)
            }
        )
    }

    override fun initView() {
        initStatusBar()
        binding.rv.adapter = adapter
        loadStorage()

        AdPreparationPop(this) {
            AdmobUtils.showInterstitialAd(this) {}
        }.show()

        AdmobUtils.showNativeAd(null, binding.flAd)
    }

    private fun initStatusBar() {
        BarUtils.setStatusBarLightMode(this, true)
        BarUtils.setStatusBarColor(this, Color.TRANSPARENT)
    }

    override fun initListener() {
        binding.ivAll.setOnClickListener {
            it.isSelected = !it.isSelected
            adapter.toggleSelect(it.isSelected)
        }
        binding.ivWrite.setOnClickListener {
            operationMode()
        }
        binding.ivNewFile.setOnClickListener {
            showSimpleFileDialog { name ->
                val file = File(adapter.getCurrentDir(), name)
                if (file.isFile) return@showSimpleFileDialog
                if (!file.exists()) {
                    file.mkdirs()
                    adapter.notifyCurrentDir()
                }
            }
        }
        onBackPressedDispatcher.addCallback {
            if (currentMode == BROWSER_MODE) {
                val isRoot = adapter.beforePage()
                if (isRoot) {
                    AdPreparationPop(this@FileManagerActivity) {
                        finish()
                    }.show()
                }
            }
            if (currentMode == OPERATION_MODE) {
                browserMode()
            }

            if (currentMode == CONFIRM_MODE) {
                adapter.beforePage()
            }
        }
        binding.flBack.setOnClickListener {
            onBackPressedDispatcher.onBackPressed()
        }
    }

    private fun loadStorage() {
        val root = Environment.getExternalStorageDirectory().listFiles()
        val dataList = root?.map { FileBean(it.name, it.path, it.length()) } ?: listOf()
        showEmpty(isEmpty = dataList.isEmpty(), showWrite = true)
        adapter.setData(dataList)
    }

    private fun showEmpty(isEmpty: Boolean = false, showAll: Boolean = false, showWrite: Boolean = false) {

        binding.llEmpty.isVisible = isEmpty

        if (isEmpty) {
            binding.flAllWrite.visibility = View.GONE
        } else {
            binding.flAllWrite.visibility = View.VISIBLE
            binding.ivAll.isVisible = showAll
            binding.ivWrite.isVisible = showWrite
        }

    }


    private fun operationMode() {
        currentMode = OPERATION_MODE
        binding.flConfirm.visibility = View.GONE
        binding.llOperation.visibility = View.VISIBLE
        adapter.changeSelect(true, canNext = false)
        binding.ivAll.isSelected = false
        showEmpty(showAll = true)
        binding.llMove.setOnClickListener {
            confirmMode("Move")
        }
        binding.llCopy.setOnClickListener {
            confirmMode("Copy")
        }
        binding.llRename.setOnClickListener {
            val files = adapter.getSelectData().map { File(it.path) }
            if (files.size == 1) {
                renameFile(files.first())
            }
        }
        binding.llDelete.setOnClickListener {
            val files = adapter.getSelectData().map { File(it.path) }
            if (files.isNotEmpty()) {
                showFileDeleteDialog {
                    lifecycleScope.launch(Dispatchers.Main) {
                        async {
                            files.forEach { if (it.isFile) it.delete() else deleteDirectory(it) }
                        }.await()
                        browserMode()
                        adapter.notifyCurrentDir()
                    }
                }
            }

        }
    }

    private fun renameFile(file: File) {
        val dir = file.parentFile
        showSimpleFileDialog(file.name, nameAction = {
            runCatching { file.renameTo(File(dir, it)) }
            operationFinish()
        })
    }

    @SuppressLint("SetTextI18n")
    private fun confirmMode(operation: String) {
        val selectFile = adapter.getSelectData()
        if (selectFile.isEmpty())
            return
        currentMode = CONFIRM_MODE
        binding.llOperation.visibility = View.GONE
        binding.ivAll.isSelected = false
        binding.ivAll.visibility = View.GONE
        binding.flConfirm.visibility = View.VISIBLE
        adapter.changeSelect(false, isAddCannotNext = true)
        binding.tvCancel.setOnClickListener {
            browserMode()
        }

        binding.tvConfirm.setOnClickListener {
            val files = adapter.getOperationList()
            val currentDir = adapter.getCurrentDir()
            when (operation) {
                "Move" -> {
                    binding.tvConfirm.text = "Motion"
                    moveFiles(files, currentDir, ::operationFinish)
                }

                "Copy" -> {
                    binding.tvConfirm.text = "Paste"
                    copyFiles(files, currentDir, ::operationFinish)
                }
            }
        }
    }


    private fun moveFiles(
        files: List<File>, currentDir: File,
        finish: () -> Unit
    ) = lifecycleScope.launch(Dispatchers.IO) {
        runCatching {
            files.forEach {
                it.copyRecursively(File(currentDir, it.name), true)
                it.deleteRecursively()
            }
        }
        finish.invoke()
    }

    fun copyFiles(
        files: List<File>, currentDir: File,
        finish: () -> Unit
    ) = lifecycleScope.launch(Dispatchers.IO) {
        runCatching {
            files.forEach {
                it.copyRecursively(File(currentDir, it.name), true)
            }
        }
        finish.invoke()
    }

    private fun operationFinish() = lifecycleScope.launch(Dispatchers.Main) {
        browserMode()
        adapter.notifyCurrentDir()
    }

    private fun browserMode() {
        currentMode = BROWSER_MODE
        binding.ivAll.visibility = View.GONE
        binding.ivWrite.visibility = View.VISIBLE
        adapter.changeSelect(false, isRemoveCannotNext = true)
        binding.llOperation.visibility = View.GONE
        binding.flConfirm.visibility = View.GONE
    }


}