package com.gh.gamecenter.video.data

import android.content.Context
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.core.utils.NumberUtils
import com.gh.gamecenter.core.utils.SpanBuilder
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.common.view.CustomMarkerView
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.databinding.ItemVideoDataChartBinding
import com.gh.gamecenter.databinding.ItemVideoDataOverviewBinding
import com.gh.gamecenter.entity.VideoDataItem
import com.github.mikephil.charting.charts.LineChart
import com.github.mikephil.charting.components.Description
import com.github.mikephil.charting.components.Legend
import com.github.mikephil.charting.components.XAxis
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.data.LineData
import com.github.mikephil.charting.data.LineDataSet
import com.github.mikephil.charting.formatter.ValueFormatter
import com.halo.assistant.HaloApp
import kotlin.math.ceil

class VideoDataAdapter(context: Context) : ListAdapter<VideoDataItem>(context) {

    public override fun setListData(updateData: MutableList<VideoDataItem>?) {
        super.setListData(updateData)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return when (viewType) {
            DATA_OVERVIEW -> VideoDataOverviewViewHolder(parent.toBinding())
            FANS_COUNT -> VideoDataFansChartViewHolder(parent.toBinding())
            else -> VideoDataPlayCountChartViewHolder(parent.toBinding())
        }
    }

    override fun getItemCount(): Int {
        return mEntityList.size
    }

    override fun getItemViewType(position: Int): Int {
        val videoDataItem = mEntityList[position]
        return when {
            videoDataItem.videoDataOverView != null -> DATA_OVERVIEW
            videoDataItem.videoFans != null -> FANS_COUNT
            else -> PLAY_COUNT
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val videoDataItem = mEntityList[position]
        when (holder) {
            is VideoDataOverviewViewHolder -> {
                bindVideoDataOverviewViewHolder(videoDataItem, holder)
            }
            is VideoDataFansChartViewHolder -> {
                holder.binding.chartTitleTv.text = "粉丝量"
                val fansData = transformChartData(videoDataItem.videoFans!!)
                initLineChart(holder.binding.lineChart, fansData.first, fansData.second)
            }
            is VideoDataPlayCountChartViewHolder -> {
                holder.binding.chartTitleTv.text = "日播放量"
                val playData = transformChartData(videoDataItem.videoPlay!!)
                initLineChart(holder.binding.lineChart, playData.first, playData.second)
            }
        }
    }

    private fun bindVideoDataOverviewViewHolder(
        videoDataItem: VideoDataItem,
        holder: VideoDataOverviewViewHolder
    ) {
        val entity = videoDataItem.videoDataOverView
        if (entity != null) {
            val updateTime = "每天 10:00 更新昨日数据"
            holder.binding.run {
                updateTimeTv.text =
                    SpanBuilder(updateTime).color(HaloApp.getInstance().application, 3, 8, R.color.text_FEDD26).build()
                fansCountTv.text = NumberUtils.transSimpleLetterCount(entity.fan)
                increaseFansCountTv.text = entity.yesterdayFan.toString()
                videoPlayCountTv.text = NumberUtils.transSimpleLetterCount(entity.play)
                increaseVideoPlayCountTv.text = entity.yesterdayPlay.toString()
                voteTv.text = NumberUtils.transSimpleLetterCount(entity.vote)
                increaseVoteTv.text = entity.yesterdayVote.toString()
                commentCountTv.text = NumberUtils.transSimpleLetterCount(entity.comment)
                increaseCommentCountTv.text = entity.yesterdayComment.toString()
                shareCountTv.text = NumberUtils.transSimpleLetterCount(entity.share)
                increaseShareCountTv.text = entity.yesterdayShare.toString()
                collectTv.text = NumberUtils.transSimpleLetterCount(entity.favorite)
                increaseCollectTv.text = entity.yesterdayFavorite.toString()
            }
        }
    }

    private fun initLineChart(lineChart: LineChart, datasX: ArrayList<String>, datasY: ArrayList<Int>) {
        lineChart.clear()
        //设置数据
        val entries = arrayListOf<Entry>()
        datasY.forEachIndexed { index, i ->
            entries.add(Entry(index.toFloat(), i.toFloat()))
        }
        val lineDataSet = LineDataSet(entries, "")
        //线颜色
        lineDataSet.color = ContextCompat.getColor(mContext, R.color.text_2E96FF)
        //线宽度
        lineDataSet.lineWidth = 2f
        //是否显示圆点
        lineDataSet.setDrawCircles(true)
        lineDataSet.setDrawCircleHole(true)
        lineDataSet.circleHoleRadius = 1.5f
        lineDataSet.circleRadius = 4f
        lineDataSet.setCircleColor(ContextCompat.getColor(mContext, R.color.text_FFB84F))
        //线条平滑
        lineDataSet.mode = LineDataSet.Mode.HORIZONTAL_BEZIER
        lineDataSet.setDrawHorizontalHighlightIndicator(false)
        lineDataSet.enableDashedHighlightLine(20f, 10f, 0f)
        lineDataSet.highLightColor = ContextCompat.getColor(mContext, R.color.text_FFEACC)
        lineDataSet.highlightLineWidth = 1f
        //必须设置为true，否则无法填充
        lineDataSet.setDrawFilled(true)
        lineDataSet.fillDrawable = ContextCompat.getDrawable(mContext, R.drawable.bg_chart_fill)

        //得到X轴
        val xAxis = lineChart.xAxis
        //设置X轴的位置（默认在上方)
        xAxis.position = XAxis.XAxisPosition.BOTTOM
        //设置X轴坐标之间的最小间隔
        xAxis.granularity = 1f
        //设置X轴的刻度数量
        xAxis.labelCount = datasX.size
        //不显示网格线
        xAxis.setDrawGridLines(false)
        xAxis.textColor = ContextCompat.getColor(mContext, R.color.text_subtitleDesc)
        xAxis.textSize = 10f
        //设置此属性必须要设置[lineChart.extraBottomOffset]，否则底部会被裁剪
        xAxis.yOffset = 14f
        xAxis.axisLineWidth = 2f
        xAxis.axisLineColor = ContextCompat.getColor(mContext, R.color.background)
        xAxis.valueFormatter = object : ValueFormatter() {
            override fun getFormattedValue(value: Float): String {
                val date = datasX[(value % datasX.size).toInt()]
                val split = date.split("/")
                return "${split[0].toInt()}/${split[1].toInt()}"
            }
        }

        //得到Y轴
        val yAxis = lineChart.axisLeft
        val rightYAxis = lineChart.axisRight
        //设置Y轴是否显示
        rightYAxis.isEnabled = false //右侧Y轴不显示
        yAxis.setDrawAxisLine(false)//不显示左侧Y轴

        yAxis.setDrawGridLines(true)
        yAxis.gridColor = ContextCompat.getColor(mContext, R.color.background)
        yAxis.gridLineWidth = 1f
        //设置Y轴坐标之间的最小间隔
        val maxValue = datasY.maxOrNull() ?: 0
        val transformNum = transformNum(maxValue)
        //最小间隔(不能为0)
        yAxis.granularity = if (transformNum == 0) 1f else transformNum.toFloat()
        //设置y轴的刻度数量
        yAxis.setLabelCount(3, true)
        //最小值不能设置为0，否则线会被裁剪
        //https://stackoverflow.com/questions/48060395/mpandroidchart-line-graph-line-gets-cut-inbetween
        yAxis.axisMinimum = -0.01f
        yAxis.axisMaximum = if (transformNum == 0) 2f else transformNum * 2f
        yAxis.textColor = ContextCompat.getColor(mContext, R.color.text_subtitleDesc)
        yAxis.textSize = 11f
        yAxis.xOffset = 8f
        yAxis.valueFormatter = object : ValueFormatter() {
            override fun getFormattedValue(value: Float): String {
                return ceil(value.toDouble()).toInt().toString()
            }
        }

        val data = LineData(lineDataSet)
        //折线图不显示数值
        data.setDrawValues(false)
        //图例：得到Lengend
        val legend: Legend = lineChart.legend
        //隐藏Lengend
        legend.isEnabled = false
        //隐藏描述
        val description = Description()
        description.isEnabled = false
        lineChart.description = description
        val markerView = CustomMarkerView(mContext)
        markerView.chartView = lineChart
        lineChart.marker = markerView
        //显示边界
        lineChart.setDrawBorders(false)
        //禁止缩放
        lineChart.setScaleEnabled(false)
        //无数据时显示的文字
        lineChart.setNoDataText("暂无数据")
        lineChart.extraBottomOffset = 1f
        //设置数据
        lineChart.data = data
        //图标刷新
        lineChart.animateXY(500, 500)

    }

    private fun transformChartData(data: LinkedHashMap<String, Int>): Pair<ArrayList<String>, ArrayList<Int>> {
        val keys = arrayListOf<String>()
        val values = arrayListOf<Int>()
        data.forEach {
            keys.add(it.key)
            values.add(it.value)
        }
        return Pair(keys, values)
    }

    private fun transformNum(num: Int): Int {
        val mCharArray = num.toString().toCharArray()
        val sb = StringBuffer()
        mCharArray.forEachIndexed { index, c ->
            if (index == 0) {
                sb.append(c)
            } else {
                sb.append("0")
            }
        }
        return sb.toString().toInt()
    }

    companion object {
        const val DATA_OVERVIEW = 0
        const val FANS_COUNT = 1
        const val PLAY_COUNT = 2
    }

    class VideoDataOverviewViewHolder(var binding: ItemVideoDataOverviewBinding) : RecyclerView.ViewHolder(binding.root)
    class VideoDataFansChartViewHolder(var binding: ItemVideoDataChartBinding) : RecyclerView.ViewHolder(binding.root)
    class VideoDataPlayCountChartViewHolder(var binding: ItemVideoDataChartBinding) :
        RecyclerView.ViewHolder(binding.root)
}