package com.zj365.health.act.exception

import android.content.Context
import android.graphics.RectF
import android.util.Log
import android.view.View
import android.widget.TextView
import androidx.recyclerview.widget.LinearLayoutManager
import com.github.mikephil.charting.components.*
import com.github.mikephil.charting.data.BarData
import com.github.mikephil.charting.data.BarDataSet
import com.github.mikephil.charting.data.BarEntry
import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.formatter.IAxisValueFormatter
import com.github.mikephil.charting.highlight.Highlight
import com.github.mikephil.charting.listener.OnChartValueSelectedListener
import com.tamsiree.rxkit.RxTimeTool
import com.xty.base.act.BaseVmAct
import com.xty.common.SizeUtil
import com.xty.common.recycleUtils.RecycleItem
import com.zj365.health.R
import com.zj365.health.adapter.ExceptionAdapter
import com.zj365.health.databinding.ActExceptionDataBinding
import com.zj365.health.fragment.BaseSleepStatisticFrag
import com.zj365.health.vm.ExceptionVm
import com.xty.network.model.ExceptionBean
import java.text.SimpleDateFormat


/**
 *  异常数据
 */

open abstract class BaseExceptionDataAct<V : ExceptionVm> : BaseVmAct<ExceptionVm>(),
    OnChartValueSelectedListener {
    val binding by lazy { ActExceptionDataBinding.inflate(layoutInflater) }
    val adapter by lazy { ExceptionAdapter() }
    var clickPosition = 0
    var sex = "1"

    companion object {
        var exceptionKey: String = "exception_title"
        var exceptionList: String = "exception_data"
        var exceptionListTime: String = "exception_time"
    }

    override fun setLayout() = binding.root
    var list: ArrayList<String>? = null
    var listTime: ArrayList<String>? = null
    var result = mutableListOf<ExceptionBean>()
    override fun initData() {
        super.initData()
        val stringExtra = intent.getStringExtra(exceptionKey)
        list = intent.getStringArrayListExtra(exceptionList)
        listTime = intent.getStringArrayListExtra(exceptionListTime)
        sex = intent.getStringExtra("sex").toString()
        Log.e("mData",list?.size.toString())
        Log.e("mData",listTime?.size.toString())

        binding.tvListTitle.text =  if ("尿酸异常数据" == stringExtra){
            "高尿酸"
        }else{
            stringExtra
        }

        binding.title.mTvTitle.text = stringExtra
        listTime?.reverse()
        list?.let {
            it.reverse()
            for (indexOf in it!!.indices) {
                if (!listTime.isNullOrEmpty()) {
                    var data = ExceptionBean(indexOf, list!!.get(indexOf), listTime!!.get(indexOf))
                    result.add(data)
                }
            }
        }
        binding.tvListSize.text = "（共${result.size}次）"
        binding.tvUnit.text = getUnit()
        binding.tvHint.text = getHint()
    }

    abstract fun getUnit(): String

    abstract fun getHint(): String
    override fun initView() {
        super.initView()
        statusBar(binding.title.mView)

        binding.title.mIvBack.apply {
            this.setOnClickListener {
                finish()
            }
        }
        initRecycle()
        initBarChart()
    }

    open fun initBarChart() {
        binding.mBarChart.let { chart ->

            // 设置柱状图选中监听器
            chart.setOnChartValueSelectedListener(this)

            // 禁用图表描述
            chart.getDescription().setEnabled(false)

            // 设置最大可见值数量
            chart.setMaxVisibleValueCount(40)

            // 禁用缩放
            chart.setPinchZoom(false)

            // 禁用网格背景
            chart.setDrawGridBackground(false)

            // 禁用柱子阴影
            chart.setDrawBarShadow(false)

            // 设置柱子值在柱子上方显示
            chart.setDrawValueAboveBar(false)

            // 高亮整个柱子
            chart.setHighlightFullBarEnabled(true)

            // 获取左侧Y轴
            val leftAxis: YAxis = chart.getAxisLeft()

            // 禁用右侧Y轴
            chart.getAxisRight().setEnabled(false)
        }

        // 创建柱状图数据集
        val values = java.util.ArrayList<BarEntry>()

        // 反转数据列表
        result.reverse()

        // 循环遍历结果数据并添加到柱状图数据集中
        for (i in 0 until result.size) {
            var sleepStatistcBean = result.get(i)
            var data = BarEntry(i.toFloat(), sleepStatistcBean.data.toFloat())
            values.add(data)
        }

        // 应用图表设置
        binding.mBarChart.apply {

            // 创建柱状图数据集
            val dataSet = BarDataSet(values, "")

            // 设置柱子颜色
            dataSet.color = resources.getColor(R.color.col_96D)

            // 不显示柱子值
            dataSet.setDrawValues(false)

            // 获取图例
            var legend = getLegend()

            // 隐藏图例
            legend.setEnabled(false)

            // 创建柱状图数据对象
            val barData = BarData(dataSet)

            // 设置柱子宽度
            barData.barWidth = 0.1f

            // 判断柱子数量，根据数量设置缩放倍率
            if (values.size > 7) {
                setScaleMinima(3.5f, 1.0f)
            } else {
                setScaleMinima(0.5f, 1.0f)
            }

            // 应用柱状图数据
            setData(barData)

            // 设置X轴位置为底部
            xAxis.position = XAxis.XAxisPosition.BOTTOM

            // 禁用X轴网格线
            xAxis.setDrawGridLines(false)

            // 设置X轴标签数量
            xAxis.labelCount = values.size

            // 获取左侧Y轴
            val leftAxis: YAxis = getAxisLeft()

            // 设置Y轴最小值
            leftAxis.axisMinimum = 0f

            // 设置Y轴网格线颜色
            leftAxis.setGridColor(resources.getColor(R.color.col_0F2))

            // 隐藏Y轴线
            leftAxis.setDrawAxisLine(false)

            // 显示Y轴标签文字
            leftAxis.setDrawLabels(true)

            // 设置Y轴标签文字颜色
            leftAxis.textColor = resources.getColor(R.color.col_c7c)

            // 设置Y轴标签最小间隔
            leftAxis.setGranularity(2f)

            // 调用抽象方法设置Y轴标签数量
            setLabelCount(leftAxis)

            // 设置柱状图数据格式化器
            dataSet.setValueFormatter(BaseSleepStatisticFrag.MyYAxisValueFormatter(context))

            // 设置X轴值格式化器
            xAxis.valueFormatter =
                IAxisValueFormatter { value, axis ->
                    val index = value.toInt()
                    if (index >= 0 && index < result.size) {
                        var data =  RxTimeTool.milliseconds2String(
                            result.get(index).time.toLong() * 1000,
                            SimpleDateFormat("HH:mm")
                        )+" " +
                                RxTimeTool.milliseconds2String(
                                    result.get(index).time.toLong() * 1000,
                                    SimpleDateFormat("MM-dd"))
                        return@IAxisValueFormatter data
                    } else ""
                }

            // 设置X轴标签最小间隔
            xAxis.granularity = 1f

            // 获取标记视图
            val markerView = getMarkView()

            // 设置标记视图
            setMarker(markerView)

            // 禁用Y轴缩放
            setScaleYEnabled(false)

            // 禁用缩放和双击缩放
            setPinchZoom(false)
            setDoubleTapToZoomEnabled(false)

            // 创建正常范围线
            val normalRange = LimitLine(getRangeMinmum(), "")
            normalRange.lineColor = resources.getColor(R.color.col_02c)
            normalRange.lineWidth = SizeUtil.dp2px(this@BaseExceptionDataAct,0.4f).toFloat()
            getAxisLeft().addLimitLine(normalRange)

            // 创建正常范围线
            val normalRange1 = LimitLine(getRangeMaxmum(), "")
            normalRange1.lineColor = resources.getColor(R.color.col_02c)
            normalRange1.lineWidth =SizeUtil.dp2px(this@BaseExceptionDataAct,0.4f).toFloat()
            getAxisLeft().addLimitLine(normalRange1)

            // 设置额外偏移量
            setExtraOffsets(0f,0f,0f,20f)

            // 刷新图表
            invalidate()
        }
    }

    abstract fun setLabelCount(leftAxis: YAxis)

    abstract fun getRangeMinmum():Float

     open fun initYAxis(leftAxis:YAxis) {

     }

    abstract fun getRangeMaxmum():Float
    open fun getMarkView(): IMarker? {
        return CustomMarkerView(
            this@BaseExceptionDataAct,
            R.layout.custom_marker_view1,result)
    }

    fun getColors(): List<Int> {

        val colors =
            arrayOf(resources.getColor(R.color.col_9BDd), resources.getColor(R.color.col_3EA))
        return colors.toList()
    }

    override fun onValueSelected(entry: Entry?, h: Highlight?) {
        entry?.let {
            val barEntry = it as BarEntry
            val bounds: RectF = binding.mBarChart.getBarBounds(barEntry)
            val y = bounds.bottom - 10f // 在柱状图顶部留出一点空隙
            if (y == 0f) {
                return
            }
            binding.mBarChart.highlightValue(h, false) // 显
        }

    }

    class CustomMarkerView(context: Context?, layoutResource: Int,var result:MutableList<ExceptionBean>) :
        MarkerView(context, layoutResource) {
        private val mData: TextView
        private val mTime: TextView
        override fun refreshContent(e: Entry, highlight: Highlight) {
            // 在 refreshContent 方法中设置需要显示的内容。
            val barEntry = e as BarEntry
            val deepData = barEntry.y.toInt()
            val x = barEntry.x
            val get = result.get(x.toInt()).time
            mData.setText(deepData.toString())
            mTime.setText(    RxTimeTool.milliseconds2String(
                get.toLong() * 1000,
                SimpleDateFormat("HH :mm")))
            setOffset((-getWidth() / 2).toFloat(), (-getHeight()).toFloat() - 10f);
        }

        init {
            // 在构造函数中获取 MarkerView 中的 TextView。
            mData = findViewById<View>(R.id.tvData) as TextView
            mTime = findViewById<View>(R.id.tvTime) as TextView
        }
    }

    fun initRecycle() {
        binding.mRecycle.addItemDecoration(RecycleItem(this, 30))
        binding.mRecycle.layoutManager = LinearLayoutManager(this)
        binding.mRecycle.adapter = adapter
        var data = mutableListOf<ExceptionBean>()
        data.addAll(result)
        adapter.setNewInstance(data)

    }

    override fun onNothingSelected() {

    }

    override fun liveObserver() {

    }
}