package com.test.basd.supercleanermax.fragment

import android.annotation.SuppressLint
import android.app.AppOpsManager
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.provider.Settings
import android.view.View
import com.test.basd.supercleanermax.activity.AppManagerActivity
import com.test.basd.supercleanermax.adapter.AppListAdapter
import com.test.basd.supercleanermax.bean.AppBean
import com.test.basd.supercleanermax.databinding.FragmentAppListBinding
import com.test.basd.supercleanermax.helps.ActivityLauncher
import com.test.basd.supercleanermax.helps.BaseFragment
import com.test.basd.supercleanermax.helps.LogEx
import com.test.basd.supercleanermax.view.AppDetailDialog.showAppDetailDialog
import net.sourceforge.pinyin4j.PinyinHelper
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination

/**
 */
class AppListFragment : BaseFragment<FragmentAppListBinding>() {

    private val TAG = "AppListFragment"
    private var adapter: AppListAdapter? = null
    private var list = arrayListOf<AppBean>()
    private var isRefreshData = false//是否需要更新数据

    private lateinit var launcher: ActivityLauncher
    private var type: Int = 0
    var isAsc: Boolean = true
    private var needPermission: Boolean = false

    override val binding: FragmentAppListBinding by lazy {
        FragmentAppListBinding.inflate(layoutInflater)
    }

    fun setInitData(
        launcher: ActivityLauncher,
        type: Int = 0,
        isAsc: Boolean = true,
        needPermission: Boolean = false
    ) {
        this.launcher = launcher
        this.type = type
        this.isAsc = isAsc
        this.needPermission = needPermission
    }

    override fun setView() {
        if (needPermission && !checkUsageAccessSettings(requireContext())) {
            binding.flContent.visibility = View.GONE
            binding.flPermission.visibility = View.VISIBLE
        } else {
            if (isRefreshData) {
                binding.progressbar.visibility = View.GONE
            }
            initRv()
            initData()
        }
    }

    override fun setListener() {
        binding.tvAuthorization.setOnClickListener {
            val intent = Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS)
            intent.addCategory("android.intent.category.DEFAULT")
            intent.data = Uri.parse("package:${requireActivity().packageName}")
            launcher.launch(intent) {
                LogEx.logDebug(TAG, "launcher callback")
                (requireActivity() as AppManagerActivity).refreshUsageAccessData()
            }
        }
    }


    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)


    }

    override fun onResume() {
        super.onResume()
        if (checkUsageAccessSettings(requireContext())) {
            binding.flPermission.visibility = View.GONE
            binding.flContent.visibility = View.VISIBLE
        }
    }


    private fun initData() {
        orderList()
        adapter?.setData(list)
    }

    /**
     * 更新数据不刷洗
     */
    fun setData(dataList: List<AppBean>) {
        list.clear()
        list.addAll(dataList)
        orderList()
    }

    /**
     * 更新数据刷新
     */
    @SuppressLint("NotifyDataSetChanged")
    fun setDataRefresh(dataList: List<AppBean>) {

        list.clear()
        list.addAll(dataList)
        orderList()
        if (isVisible) {
            if (adapter == null) {
                initRv()
            }
            if (isRefreshData) {
                binding.progressbar.visibility = View.GONE
            }
            adapter?.setData(list)
        }
    }

    /**
     * 刷洗fragment数据
     */
    @SuppressLint("NotifyDataSetChanged")
    fun refreshFragmentData(dataList: List<AppBean>, isRefresh: Boolean = false, index: Int = 0) {
        isRefreshData = true
        LogEx.logDebug(TAG, "isRefresh=$isRefresh isVisible=$isVisible index=$index")
        if (isRefresh && isVisible) {
            binding.flPermission.visibility = View.GONE
            binding.progressbar.visibility = View.GONE
            setDataRefresh(dataList)
        } else {
            setData(dataList)
        }

    }

    fun showContent(isRefresh: Boolean = false) {
        if (isRefresh) {
            binding.flContent.visibility = View.VISIBLE
        }
    }

    private fun initRv() {
        adapter = AppListAdapter(itemClick = {
            if (!(requireActivity() as AppManagerActivity).animationFinish) {
                return@AppListAdapter
            }
            requireActivity().showAppDetailDialog(it, launcher) { unInstalled ->
                if (unInstalled) {
                    adapter?.removeData(it)
                    otherAppRemove(it)
                }
            }
        }, itemSelect = { selectList ->
            showUnInstall(selectList)
        })
        binding.rv.adapter = adapter
    }


    private fun showUnInstall(selectList: List<AppBean>) {
        (requireActivity() as AppManagerActivity).showUnInstall(selectList)
    }

    private fun orderList() {
        when (type) {
            APP_LIST_TYPE_NAME -> {
                list.forEach {
                    it.pinYin = getPinyin(it.appName)
                }
                if (isAsc) {
                    list.sortBy { it.pinYin }
                } else {
                    list.sortByDescending { it.pinYin }
                }
            }

            APP_LIST_TYPE_INSTALL -> {
                if (isAsc) {
                    list.sortBy { it.installTime }
                } else {
                    list.sortByDescending { it.installTime }
                }
            }

            APP_LIST_TYPE_SIZE -> {
                if (isAsc) {
                    list.sortBy { it.appSize }
                } else {
                    list.sortByDescending { it.appSize }
                }

            }

            APP_LIST_TYPE_LAST_USE -> {
                if (isAsc) {
                    list.sortBy { it.lastUsedTime }
                } else {
                    list.sortByDescending { it.lastUsedTime }
                }
            }
        }
    }

    /**
     * 翻转顺序
     */
    fun reverseOrder() {
        isAsc = !isAsc
        orderList()
        adapter?.setData(list)
    }

    private fun otherAppRemove(appBean: AppBean) {
        (requireActivity() as AppManagerActivity).otherPageRemove(appBean, this)
    }


    companion object {
        const val APP_LIST_TYPE_NAME = 12
        const val APP_LIST_TYPE_INSTALL = 15
        const val APP_LIST_TYPE_SIZE = 19
        const val APP_LIST_TYPE_LAST_USE = 123
    }

    /**
     * 汉字转为拼音
     * https://cloud.tencent.com/developer/article/1731852
     * @return
     */
    fun getPinyin(str: String): String {

        val format = HanyuPinyinOutputFormat()
        format.caseType = HanyuPinyinCaseType.UPPERCASE
        format.toneType = HanyuPinyinToneType.WITHOUT_TONE
        val sb = StringBuilder()

        val strNoSpace = str.replace("\\s".toRegex(), "").trim()
//        LogEx.logDebug(TAG, "strNoSpace=$strNoSpace")
        val charArray = strNoSpace.toCharArray()
        for (i in charArray.indices) {
            val c = charArray[i]
            // 如果是空格, 跳过
            if (Character.isWhitespace(c)) {
                continue
            }
//            LogEx.logDebug(TAG, "c.code=${c.code}")
            if (c.code == -127 || c.code < 128) {
                // 肯定不是汉字
                sb.append(c)
            } else {
                var s: String? = ""
                try {
//                    LogEx.logDebug(TAG, "c=$c")
                    // 通过char得到拼音集合. 单 -  dan, shan
                    val array = PinyinHelper.toHanyuPinyinStringArray(c, format)
                    if (array.isNotEmpty()) {
                        s = array.first()
                        sb.append(s)
                    }
                } catch (e: BadHanyuPinyinOutputFormatCombination) {
                    e.printStackTrace()
                    sb.append(s)
                }
            }
        }
//        LogEx.logDebug(TAG, "ping str=$sb")
        return sb.toString()
    }


    private fun checkUsageAccessSettings(context: Context): Boolean {
        val appOpsManager = context.getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager

        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            appOpsManager.unsafeCheckOpNoThrow(
                AppOpsManager.OPSTR_GET_USAGE_STATS,
                android.os.Process.myUid(),
                context.packageName
            ) == AppOpsManager.MODE_ALLOWED
        } else {
            appOpsManager.checkOpNoThrow(
                AppOpsManager.OPSTR_GET_USAGE_STATS,
                android.os.Process.myUid(),
                context.packageName
            ) == AppOpsManager.MODE_ALLOWED
        }
    }
}