package com.ccwangluo.accelerator.ui.gameList

import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.ccwangluo.accelerator.R
import com.ccwangluo.accelerator.adapter.KotlinDataAdapter
import com.ccwangluo.accelerator.databinding.FragmentGameListBinding
import com.ccwangluo.accelerator.manager.DownloadUtils
import com.ccwangluo.accelerator.manager.GameDownLoadManger
import com.ccwangluo.accelerator.manager.GameDownLoadManger.download
import com.ccwangluo.accelerator.manager.LoginUtils
import com.ccwangluo.accelerator.model.Announcement
import com.ccwangluo.accelerator.model.GameInfo
import com.ccwangluo.accelerator.ui.dialog.CommonDialog
import com.ccwangluo.accelerator.ui.dialog.GameDownloadDialog
import com.ccwangluo.accelerator.ui.home.AcceleratorFragment
import com.ccwangluo.accelerator.ui.home.NewsFragment
import com.ccwangluo.accelerator.ui.web.CommonWebViewFragment
import com.ccwangluo.accelerator.utils.*
import com.ccwangluo.accelerator.utils.datareport.DataRePortUtils
import com.github.shadowsocks.Core.activity
import com.github.shadowsocks.bg.AuthManager.gameId
import com.github.shadowsocks.bg.BaseService
import com.github.shadowsocks.http.HttpConfig
import com.umeng.socialize.utils.DeviceConfigInternal.context
import com.xuexiang.xpage.base.XPageFragment
import com.xuexiang.xpage.core.PageOption
import com.xuexiang.xpage.utils.TitleBar
import com.xuexiang.xui.widget.progress.CircleProgressView
import com.xuexiang.xutil.app.AppUtils
import com.xuexiang.xutil.tip.ToastUtils
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import java.util.*
import java.util.stream.Collectors


class GameListFragment : XPageFragment() {
    private lateinit var _binding: FragmentGameListBinding

    private lateinit var gameListModel: GameListModel

    private var page = 1;
    private var dataList = arrayListOf<GameInfo>()
    private val downloadInfoMap = mutableMapOf<Int, GameDownLoadManger.DownloadInfo>()

    var acctime = 0L
    var total = 0
    override fun initTitleBar(): TitleBar? {
        //不使用@Page标注的一定要注意覆盖这个方法
        return null
    }

    override fun inflateView(inflater: LayoutInflater?, container: ViewGroup?): View {
        _binding = FragmentGameListBinding.inflate(inflater!!, container, false)
        gameListModel = ViewModelProvider(this).get(GameListModel::class.java)
        return _binding.root
    }

    override fun initViews() {
        gameListModel.clearList.observe(this) {
            if (it) {
                dataList.clear()
            }
        }
        DataRePortUtils.report("st_app_open")
        gameListModel.gameModel.observe(this) {
            total = it.total
            it.list?.let { it1 -> dataList.addAll(it1) }
            _binding.refreshGame.isRefreshing = false
            _binding.gameList.adapter?.notifyDataSetChanged()
        }
        val layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
        _binding.gameList.setLayoutManager(layoutManager)
        _binding.gameList.itemAnimator = null
        _binding.gameList.adapter = KotlinDataAdapter.Builder<GameInfo>()
            .setData(dataList)
            .setLayoutId(R.layout.item_game)
            .addBindView { itemView, itemData ->
                val game_img = itemView.findViewById<ImageView>(R.id.game_img)
                val game_name = itemView.findViewById<TextView>(R.id.game_name)
                val btn_uninstall = itemView.findViewById<View>(R.id.btn_uninstall)
                val is_free = itemView.findViewById<View>(R.id.is_free)
                val btn_acc = itemView.findViewById<View>(R.id.btn_acc)
                val open_acc = itemView.findViewById<View>(R.id.open_acc)
                val btn_acc_stop = itemView.findViewById<View>(R.id.btn_acc_stop)
                val tx_game_update_notice = itemView.findViewById<View>(R.id.tx_game_update_notice)
                val tx_download_status = itemView.findViewById<View>(R.id.tx_download_status)
                val btn_download_status = itemView.findViewById<View>(R.id.btn_download_status)
                val progress_download =
                    itemView.findViewById<CircleProgressView>(R.id.progress_download)
                val tx_download_size = itemView.findViewById<TextView>(R.id.tx_download_size)
                val tx_status = itemView.findViewById<TextView>(R.id.tx_status)
                //公告
                val game_notice_area_1 = itemView.findViewById<View>(R.id.game_notice_area_1)
                val game_notice_area_2 = itemView.findViewById<View>(R.id.game_notice_area_2)
                val game_notice_2_1 = itemView.findViewById<TextView>(R.id.game_notice_2_1)
                val game_notice_1_1 = itemView.findViewById<TextView>(R.id.game_notice_1_1)
                val game_notice_1_2 = itemView.findViewById<TextView>(R.id.game_notice_1_2)
                val game_notice_1_3 = itemView.findViewById<TextView>(R.id.game_notice_1_3)
                val announcement1 = itemData.announcementList?.stream()?.filter { it.addrType == 3 }
                    ?.sorted { o1, o2 -> o1.position.compareTo(o2.position) }
                    ?.collect(Collectors.toList())

                if (announcement1 == null || announcement1.size == 0) {
                    game_notice_area_1.visibility = View.GONE
                } else {
                    game_notice_area_1.visibility = View.VISIBLE
                    game_notice_1_1.setText(announcement1.get(0).title)
                    game_notice_1_1.setOnClickListener {
                        DataRePortUtils.report(
                            "st_loc_one_clk",
                            mapOf("gameid" to itemData.id.toString(), "scene" to 1)
                        )
                        openNoticePage(itemData, announcement1.get(0))
                    }
                    if (announcement1.size > 1) {
                        game_notice_1_2.visibility = View.VISIBLE
                        game_notice_1_2.setText(announcement1.get(1).title)
                        game_notice_1_2.setOnClickListener {
                            DataRePortUtils.report(
                                "st_loc_one_clk",
                                mapOf("gameid" to itemData.id.toString(), "scene" to 2)
                            )
                            openNoticePage(itemData, announcement1.get(1))
                        }
                    } else {
                        game_notice_1_2.visibility = View.GONE
                    }
                    if (announcement1.size > 2) {
                        game_notice_1_3.visibility = View.VISIBLE
                        game_notice_1_3.setText(announcement1.get(2).title)
                        game_notice_1_3.setOnClickListener {
                            DataRePortUtils.report(
                                "st_loc_one_clk",
                                mapOf("gameid" to itemData.id.toString(), "scene" to 3)
                            )
                            openNoticePage(itemData, announcement1.get(2))
                        }
                    } else {
                        game_notice_1_3.visibility = View.GONE
                    }
                }

                val announcement2 = itemData.announcementList?.stream()?.filter { it.addrType == 4 }
                    ?.collect(Collectors.toList())

                if (announcement2 == null || announcement2.size == 0) {
                    game_notice_area_2.visibility = View.GONE
                } else {
                    game_notice_area_2.visibility = View.VISIBLE
                    game_notice_2_1.setText(HtmlUtil.getTextFromHtml(announcement2.get(0).content))
                    game_notice_area_2.setOnClickListener {
                        DataRePortUtils.report(
                            "st_loc_two_clk",
                            mapOf("gameid" to itemData.id.toString())
                        )
                        openNoticePage(itemData, announcement2.get(0))
                    }
                }

                Glide.with(this@GameListFragment)
                    .load(itemData.icon)
                    .into(game_img)
                game_name.setText(itemData.gameName)
                if (itemData.type == 1) {
                    is_free.visibility = View.VISIBLE
                } else {
                    is_free.visibility = View.GONE
                }
                context?.let {
                    //1.应用是否安装//2.应用是否更新 //3.应用是否加速 //4,应用下载
                    if (downloadInfoMap.containsKey(itemData.id)) {
                        btn_uninstall.visibility = View.GONE
                        btn_acc.visibility = View.GONE
                        btn_acc_stop.visibility = View.GONE
                        tx_game_update_notice.visibility = View.GONE
                        tx_download_status.visibility = View.VISIBLE
                        btn_download_status.visibility = View.VISIBLE
                        tx_download_size.visibility = View.VISIBLE
                        val downloadIndo = downloadInfoMap.get(itemData.id)
                        downloadIndo?.let {
                            tx_status.setText("${ByteUtils.bytesToDisplay(it.speed / 2)}/s")
                            tx_status.visibility = View.VISIBLE
                            tx_download_size.setText(
                                "${ByteUtils.bytesToDisplay(it.download_so_far)}/${
                                    ByteUtils.bytesToDisplay(
                                        it.download_all
                                    )
                                }"
                            )
                            progress_download.progress = it.progress
                        }

                    }
                    //应用未安装
                    else if (!SysUtils.isPackageInstall(it, itemData.packageName)) {
                        btn_uninstall.visibility = View.VISIBLE
                        btn_acc.visibility = View.GONE
                        btn_acc_stop.visibility = View.GONE
                        tx_game_update_notice.visibility = View.GONE
                        tx_download_status.visibility = View.GONE
                        btn_download_status.visibility = View.GONE

                    }
                    //应用加速中
                    else if (AcceleratorUtils.state == BaseService.State.Connected && AcceleratorUtils.game?.id == itemData.id) {
                        btn_uninstall.visibility = View.GONE
                        btn_acc.visibility = View.GONE
                        btn_acc_stop.visibility = View.VISIBLE
                        tx_game_update_notice.visibility = View.GONE
                        tx_download_status.visibility = View.VISIBLE
                        btn_download_status.visibility = View.GONE
                        tx_download_size.visibility = View.GONE
                        tx_status.setText(SysUtils.getAccTimeString(acctime))
                    }
                    //应用升级
                    else if (!SysUtils.compareVersionTo(
                            AppUtils.getAppVersionName(itemData.packageName),
                            itemData.version
                        ) || !SysUtils.compareVersionTo(
                            AppUtils.getAppVersionName(itemData.packageName),
                            itemData.versionTools
                        )
                    ) {
                        btn_uninstall.visibility = View.GONE
                        btn_acc.visibility = View.VISIBLE
                        btn_acc_stop.visibility = View.GONE
                        tx_game_update_notice.visibility = View.VISIBLE
                        tx_download_status.visibility = View.GONE
                        btn_download_status.visibility = View.GONE
                    } else {
                        btn_uninstall.visibility = View.GONE
                        btn_acc.visibility = View.VISIBLE
                        btn_acc_stop.visibility = View.GONE
                        tx_game_update_notice.visibility = View.GONE
                        tx_download_status.visibility = View.GONE
                        btn_download_status.visibility = View.GONE
                    }


                }

                btn_uninstall.setOnClickListener {
                    DataRePortUtils.report(
                        "st_ic_noinstl_clk",
                        mapOf("gameid" to itemData.id.toString())
                    )
                    download(itemData)
                }

                btn_acc_stop.setOnClickListener {
                    AcceleratorUtils.setGameInfo(itemData)
                    openPage(AcceleratorFragment::class.java)
                }

                btn_acc.setOnClickListener {
                    DataRePortUtils.report(
                        "st_speed_start_clk",
                        mapOf("scene" to "1", "gameid" to itemData.id.toString())
                    )
                    startAccBtn(itemData)
                }

                game_img.setOnClickListener {
                    openWebviewForResult(HttpConfig.UI_GAME_URL, itemData)
                }

                game_name.setOnClickListener {
                    openWebviewForResult(HttpConfig.UI_GAME_URL, itemData)
                }

                tx_game_update_notice.setOnClickListener {
                    download(itemData)
                }
                progress_download.setOnClickListener {
                    context?.let {
                        CommonDialog(it)
                            .setContent("确定要关闭下载任务吗？ ")
                            .setBtnLeft("取消") {
                            }.setBtnRight("关闭") {
                                GameDownLoadManger.cancellDownload(itemData)
                            }.show<CommonDialog>()
                    }
                }
            }
            .create()
        gameListModel.freshData(this, page)

        GameDownLoadManger.registerLisener(object : GameDownLoadManger.GameDownloadListener {
            override fun onStart(gameInfo: GameInfo?) {
                println("onStart$gameInfo")
            }

            override fun onFinish(gameInfo: GameInfo?) {
                println("onFinish$gameInfo")
                if (gameInfo != null) {
                    downloadInfoMap.remove(gameInfo.id)
                    _binding.gameList.adapter?.notifyItemChanged(
                        dataList.indexOf(
                            gameInfo
                        )
                    )
                }
            }

            override fun onProgress(
                gameInfo: GameInfo?,
                downloadInfo: GameDownLoadManger.DownloadInfo
            ) {
                if (gameInfo != null && dataList.contains(gameInfo)) {
                    val lastInfo = downloadInfoMap.get(gameInfo.id)
                    downloadInfo.speed =
                        (downloadInfo.download_so_far - if (lastInfo == null) 0 else lastInfo.download_so_far)
                    if (lastInfo != null) {
                        if (downloadInfo.speed == 0L && lastInfo.speed != 0L) {
                            downloadInfo.speed = lastInfo.speed
                        }
                    }
                    downloadInfoMap.put(gameInfo.id, downloadInfo)
                    _binding.gameList.adapter?.notifyItemChanged(
                        dataList.indexOf(
                            gameInfo
                        )
                    )
                }
            }


        })
    }

    var gameInfo: GameInfo? = null

    private val CLICK_START_ACC_REQUEST_CODE: Int = 100;
    private fun openWebviewForResult(url: String, itemData: GameInfo) {
        gameInfo = itemData
        PageOption.to(CommonWebViewFragment::class.java)
            .putString(CommonWebViewFragment.WEBVIEW_URL_KEY, HttpConfig.UI_MAIN_URL + url)
            .putInt(CommonWebViewFragment.GAME_ID, itemData.id)
            .setRequestCode(CLICK_START_ACC_REQUEST_CODE)
            .open(this)

    }

    override fun onFragmentResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onFragmentResult(requestCode, resultCode, data)
        if (requestCode == CLICK_START_ACC_REQUEST_CODE) {
            Handler(Looper.getMainLooper()).post {
                gameInfo?.let {
                    if (AcceleratorUtils.state == BaseService.State.Connected && AcceleratorUtils.game?.id == it.id) {
                        context?.let {
                            CommonDialog(it).setTitle("加速停止确认")
                                .setContent("停止加速可能会导致游戏断线，是否确认停止？")
                                .setBtnLeft("取消") {
                                    DataRePortUtils.report("st_speed_stop_pop_cancel_clk")
                                }.setBtnRight("停止加速") {
                                    DataRePortUtils.report("st_speed_stop_pop_ok_clk")
                                    AcceleratorUtils.stopAccelerator({})
                                }.show<CommonDialog>()
                            DataRePortUtils.report("st_speed_stop_pop_show")
                        }
                    } else {
                        DataRePortUtils.report(
                            "st_speed_start_clk",
                            mapOf("scene" to "6", "gameid" to gameInfo?.id.toString())
                        )
                        startAccBtn(it)
                    }
                }
            }
        }
    }

    private fun startAccBtn(itemData: GameInfo) {
        LoginUtils.token?.let {
            startAccPage(itemData)
        } ?: let {
            DataRePortUtils.report("st_speed_result", mapOf("result" to 0, "cause" to "4"))
            context?.let { it1 ->
                LoginUtils.login(it1) {
                    if (it) {
                        startAccPage(itemData)
                    }
                }
            }
        }

    }


    private fun startAccPage(itemData: GameInfo) {
        if (AcceleratorUtils.state == BaseService.State.Connected) {
            context?.let {
                CommonDialog(it)
                    .setContent("当前${AcceleratorUtils.game?.gameName}应用正在加速,是否取消")
                    .setBtnLeft("取消") {
                    }.setBtnRight("确定") {
                        AcceleratorUtils.stopAccelerator {
                            AcceleratorUtils.setGameInfo(itemData)
                            openPage(AcceleratorFragment::class.java)
                        }
                    }.show<CommonDialog>()
            }

        } else {
            DataRePortUtils.report("st_ic_game_clk", mapOf("gameid" to itemData.id.toString()))
            AcceleratorUtils.setGameInfo(itemData)
            openPage(AcceleratorFragment::class.java)
        }
    }

    private fun openNoticePage(itemData: GameInfo, ann: Announcement) {
        if (ann.type == 2) {
            val params = Bundle()
            params.putString(
                CommonWebViewFragment.WEBVIEW_URL_KEY,
                HttpConfig.UI_MAIN_URL + "/notice?noticeId=${ann.id}"
            )
            params.putInt(CommonWebViewFragment.GAME_ID, itemData.id)
            openPage(CommonWebViewFragment::class.java, params)
        } else if (ann.type == 1) {
            val params = Bundle()
            params.putInt(NewsFragment.GAME_ID, itemData.id)
            params.putString(NewsFragment.GAME_NAME, itemData.gameName)
            openPage(NewsFragment::class.java, params)
        }
    }


    override fun initListeners() {
        _binding.accShare.setOnClickListener {
            DataRePortUtils.report("st_share_clk", mapOf("scene" to "3"))
            activity?.let { it1 -> ShareUtils().share(it1) }
        }
        _binding.refreshGame.setOnRefreshListener {
            page = 1
            gameListModel.freshData(this, page)
            _binding.refreshGame.postDelayed({
                _binding.refreshGame.isRefreshing = false
            }, 2000)
        }
        _binding.gameList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
            override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
                super.onScrollStateChanged(recyclerView, newState)
            }

            override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
                super.onScrolled(recyclerView, dx, dy)
                if (isSlideToBottom(recyclerView)) {
                    if (dataList.size < total) {
                        page++
                        gameListModel.freshData(this@GameListFragment, page)
                    }
                }
            }
        })
        registerListener()
    }

    protected fun isSlideToBottom(recyclerView: RecyclerView?): Boolean {
        if (recyclerView == null) return false
        return if (recyclerView.computeVerticalScrollExtent() + recyclerView.computeVerticalScrollOffset() >= recyclerView.computeVerticalScrollRange()) true else false
    }


    override fun onHiddenChanged(hidden: Boolean) {
        super.onHiddenChanged(hidden)
        if (!hidden) {
            registerListener()
            _binding.gameList.adapter?.notifyDataSetChanged()
        }
    }

    fun registerListener() {
        AcceleratorUtils.registerStateListener { state, l, net ->
            acctime = l
            Handler(Looper.getMainLooper()).post {
                if (state == BaseService.State.Connected) {
                    AcceleratorUtils.game?.let {
                        if (dataList.indexOf(AcceleratorUtils.game) == 0) {
                            _binding.gameList.adapter?.notifyItemChanged(
                                0
                            )
                        } else {
                            dataList.remove(it)
                            dataList.add(0, it)
                            _binding.gameList.adapter?.notifyDataSetChanged()
                        }
                    }
                } else {
                    _binding.gameList.adapter?.notifyDataSetChanged()
                }
            }
        }
    }

    fun download(itemData: GameInfo) {
        //
        if (itemData.downloadType != 0) {
            ToastUtils.toast("暂不提供下载功能，请前往游戏官网下载～")
            return
        }
        activity?.let {
            var downloadUrl = itemData.downloadUrl
            if (SysUtils.compareVersionTo(itemData.versionTools, itemData.version)) {
                itemData.downloadUrlTools?.let {
                    downloadUrl = it
                }
            }
            if (downloadUrl?.endsWith(".apk") == true) {
                GameDownloadDialog(
                    itemData,
                    this@GameListFragment
                ).show<GameDownloadDialog>().download(downloadUrl)
            } else {
                CommonDialog(it)
                    .setContent("TT不提供下载功能，有需要浏览游戏资讯，可前往Qooapp等途径获取。")
                    .setBtnLeft("取消") {
                    }.setBtnRight("去找找") {
                        val intent = Intent(
                            Intent.ACTION_VIEW,
                            Uri.parse(downloadUrl)
                        )
                        startActivity(intent)
                    }.show<CommonDialog>()
            }
        }
    }

    companion object {
        fun newInstance(): GameListFragment {
            val fragment = GameListFragment()
            return fragment
        }
    }
}