package com.zxhyis.tools.ui.`fun`


import android.Manifest
import android.animation.Animator
import android.annotation.SuppressLint
import android.content.ContentResolver
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.MediaStore
import android.provider.Settings
import android.text.format.Formatter
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.zxhyis.tools.R
import com.zxhyis.tools.base.TopActivity
import com.zxhyis.tools.databinding.ActivityAudioBinding
import com.zxhyis.tools.logic.AudioBean
import com.zxhyis.tools.logic.Counts
import com.zxhyis.tools.logic.Logic
import com.zxhyis.tools.logic.setOnClick
import com.zxhyis.tools.logic.setStatusBarTextDark
import com.zxhyis.tools.logic.shareAudio
import com.zxhyis.tools.logic.shareMultipleAudios
import com.zxhyis.tools.logic.shareMultipleImages
import com.zxhyis.tools.logic.showToast
import com.zxhyis.tools.logic.startActivity
import com.zxhyis.tools.logic.testLog
import com.zxhyis.tools.ui.adapter.AudioAdapter
import com.zxhyis.tools.ui.dialog.LoadingDialog
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.io.File
import java.nio.file.Files
import java.nio.file.Paths
import java.nio.file.attribute.BasicFileAttributes
import java.sql.Date
import java.text.SimpleDateFormat

class AudioActivity : TopActivity<ActivityAudioBinding>() {

    private val audioList = ArrayList<AudioBean>()
    private val selectList = ArrayList<AudioBean>()
    private val fileList = ArrayList<File>()
    private lateinit var audioAdapter: AudioAdapter
    private var allSize = 0L
    private var dialog: LoadingDialog? = null
    private val result =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {}
    private var needRefresh = false

    override fun getViewBinding1(): ActivityAudioBinding {
        return ActivityAudioBinding.inflate(layoutInflater)
    }

    override fun init() {
        vb.inAudio.tvTitle.text = getString(R.string.tv_audio)
        vb.inAudio.ivBack.setOnClick {
            finish()
        }

        vb.tvSet.setOnClick {
            vb.tvSet.setBackgroundResource(R.drawable.bg_shape_set_click)
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                result.launch(Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION))
            } else {
                ActivityCompat.requestPermissions(
                    this,
                    arrayOf(
                        Manifest.permission.WRITE_EXTERNAL_STORAGE,
                        Manifest.permission.READ_EXTERNAL_STORAGE
                    ), Counts.REQUEST_ALL_FILE
                )
            }
        }

        vb.inAudio.imageSelectAll.setOnClick {
            fileList.clear()
            selectList.clear()
            vb.inAudio.imageSelectAll.isSelected = !vb.inAudio.imageSelectAll.isSelected
            if (vb.inAudio.imageSelectAll.isSelected) {
                audioAdapter.selectAll()
                for (audio in audioList) {
                    fileList.add(audio.file)
                    selectList.add(audio)
                }
                vb.ivShare.setImageResource(R.drawable.ic_share_selected)
                vb.ivDelete.setImageResource(R.drawable.ic_delete_selected)
            } else {
                audioAdapter.deselectAll()
                for (audio in audioList) {
                    fileList.remove(audio.file)
                    selectList.remove(audio)
                }
                vb.ivShare.setImageResource(R.drawable.ic_share)
                vb.ivDelete.setImageResource(R.drawable.ic_delete)
            }
            testLog("${fileList.size}")
        }

        vb.inAudio.tvMenu.setOnClick {
            needRefresh = true
            if (audioList.size > 0) {
                vb.inAudio.ivBack.visibility = View.GONE
                vb.inAudio.tvMenu.visibility = View.GONE
                vb.inAudio.imageSelectAll.visibility = View.VISIBLE
                vb.inAudio.tvAll.visibility = View.VISIBLE
                vb.llBottom.visibility = View.VISIBLE
                vb.inAudio.tvTitle.text = getString(R.string.select_audio)
                audioAdapter.setShow()
            } else {
                getString(R.string.file_not_found).showToast()
            }
        }

        vb.ivDelete.setOnClick {
            if (isCanDelete()) {
                CoroutineScope(Dispatchers.IO).launch {
                    delay(500)
                    deleteFiles()
                    launch(Dispatchers.Main) {
                        updateUI()
                    }
                }
            } else {
                "Please select at least one".showToast()
            }
        }

        vb.ivShare.setOnClick {
            when {
                selectList.size in 1..3 -> {
                    shareAudios()
                }

                selectList.size > 3 -> {
                    "Select up to three".showToast()
                }

                else -> {
                    "Select at least one".showToast()
                }
            }
        }

        vb.imageLoad.addAnimatorListener(object : Animator.AnimatorListener {
            override fun onAnimationStart(animation: Animator) {}

            override fun onAnimationEnd(animation: Animator) {
                lifecycleScope.launch {
                    delay(500)
                    startActivity<ResultActivity>("from" to "audio")
                    finish()
                }
            }

            override fun onAnimationCancel(animation: Animator) {}

            override fun onAnimationRepeat(animation: Animator) {}

        })

    }

    @SuppressLint("UseCompatLoadingForDrawables")
    private fun initDatasource(context: Context) {
        CoroutineScope(Dispatchers.IO).launch {
            delay(500)
            val contentResolver: ContentResolver = context.contentResolver
            val uri: Uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
            val projection = arrayOf(MediaStore.Audio.AudioColumns.DATA)
            val sortOrder = "${MediaStore.Audio.AudioColumns.TITLE} ASC"
            val cursor: Cursor? = contentResolver.query(uri, projection, null, null, sortOrder)

            if (cursor != null && cursor.moveToFirst()) {
                val dataIndex = cursor.getColumnIndexOrThrow(MediaStore.Audio.AudioColumns.DATA)
                do {
                    val audioPath = cursor.getString(dataIndex)
                    val file = File(audioPath)
                    allSize += file.length()
                    audioList.add(
                        AudioBean(
                            audioPath,
                            file.absoluteFile.name,
                            Uri.parse(audioPath),
                            file,
                            file.length(),
                            apkTime = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) getFileCreationTime(
                                file.absolutePath
                            )
                            else "",
                            needRefresh
                        )
                    )
                } while (cursor.moveToNext())
                cursor.close()

                audioAdapter = AudioAdapter(audioList, this@AudioActivity, object : Logic {
                    override fun doLogic() {
                        remove()
                        if (fileList.size > 0) {
                            vb.ivShare.setImageResource(R.drawable.ic_share_selected)
                            vb.ivDelete.setImageResource(R.drawable.ic_delete_selected)
                        } else {
                            vb.ivShare.setImageResource(R.drawable.ic_share)
                            vb.ivDelete.setImageResource(R.drawable.ic_delete)
                        }
                    }

                })
            }

            launch(Dispatchers.Main) {
                if (audioList.size > 0) {
                    val linearLayoutManager = LinearLayoutManager(this@AudioActivity)
                    linearLayoutManager.initialPrefetchItemCount = 10
                    vb.rvAudio.apply {
                        layoutManager = linearLayoutManager
                        setHasFixedSize(true)
                        setItemViewCacheSize(20)
                        adapter = audioAdapter
                    }
                    vb.apply {
                        rvAudio.visibility = View.VISIBLE
                        icNoFile.visibility = View.GONE
                        tvNoFile.visibility = View.GONE
                        totalSize.text = Formatter.formatFileSize(this@AudioActivity, allSize)
                    }
                } else {
                    vb.apply {
                        rvAudio.visibility = View.GONE
                        icNoFile.visibility = View.VISIBLE
                        tvNoFile.visibility = View.VISIBLE
                        totalSize.visibility = View.GONE
                    }
                }
                dialog?.dismiss()
            }
        }
    }

    private fun updateUI() {
        vb.imageLoad.visibility = View.VISIBLE
        vb.tvLoad.visibility = View.VISIBLE
        vb.imageLoad.playAnimation()
        vb.rvAudio.visibility = View.GONE
        vb.inAudio.clInclude.visibility = View.GONE
        vb.llBottom.visibility = View.GONE
        vb.totalSize.visibility = View.GONE
    }

    @RequiresApi(Build.VERSION_CODES.O)
    fun getFileCreationTime(filePath: String): String? {
        try {
            val path = Paths.get(filePath)
            val attr = Files.readAttributes(path, BasicFileAttributes::class.java)
            val creationTime = attr.creationTime()
            val date = Date(creationTime.toMillis())
            val format = SimpleDateFormat("yyyy-MM-dd HH:mm")
            return format.format(date)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return null
    }

    private fun isCanDelete(): Boolean {
        testLog("de:${fileList.size}")
        return fileList.size > 0
    }

    private fun remove() {
        fileList.clear()
        selectList.clear()
        for (audio in audioList) {
            if (audio.isSelected) {
                fileList.add(audio.file)
                selectList.add(audio)
            } else {
                fileList.remove(audio.file)
                selectList.remove(audio)
            }
        }
    }

    private fun deleteFiles() {
        for (file in fileList) {
            file.delete()
        }
    }

    private fun shareAudios() {
//        val uriList = ArrayList<Uri>()
//        for (audio in selectList) {
//            uriList.add(audio.audioUri)
//            testLog("${Uri.parse(audio.audioPath)}")
//        }
        shareMultipleAudios(fileList, this)
    }

    override fun onResume() {
        super.onResume()
        setStatusBarTextDark(this)
        allSize = 0
        audioList.clear()
        fileList.clear()
        audioList.clear()
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            if (Environment.isExternalStorageManager()) {
                vb.apply {
                    imagePer.visibility = View.GONE
                    tvDes.visibility = View.GONE
                    tvSet.visibility = View.GONE
                    rvAudio.visibility = View.VISIBLE
                    totalSize.visibility = View.VISIBLE
                    initDatasource(this@AudioActivity)
                    dialog = LoadingDialog()
                    dialog?.isCancelable = false
                    dialog?.showNow(supportFragmentManager, "loading")
                }
            } else {
                vb.apply {
                    imagePer.visibility = View.VISIBLE
                    tvDes.visibility = View.VISIBLE
                    tvSet.visibility = View.VISIBLE
                    vb.tvSet.setBackgroundResource(R.drawable.bg_shape_set)
                    rvAudio.visibility = View.GONE
                    totalSize.visibility = View.GONE
                }
            }
        } else {
            if (ContextCompat.checkSelfPermission(
                    this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE
                ) != PackageManager.PERMISSION_GRANTED
            ) {
                vb.apply {
                    imagePer.visibility = View.VISIBLE
                    tvDes.visibility = View.VISIBLE
                    tvSet.visibility = View.VISIBLE
                    vb.tvSet.setBackgroundResource(R.drawable.bg_shape_set)
                    rvAudio.visibility = View.GONE
                    totalSize.visibility = View.GONE
                }
            } else {
                vb.apply {
                    imagePer.visibility = View.GONE
                    tvDes.visibility = View.GONE
                    tvSet.visibility = View.GONE
                    rvAudio.visibility = View.VISIBLE
                    totalSize.visibility = View.VISIBLE
                    initDatasource(this@AudioActivity)
                    dialog = LoadingDialog()
                    dialog?.isCancelable = false
                    dialog?.showNow(supportFragmentManager, "loading")
                }
            }
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        audioList.clear()
        fileList.clear()
        selectList.clear()
        if (dialog != null) {
            dialog?.dismiss()
        }
    }

}