package com.zj365.health.act.exception

import android.content.Context
import android.graphics.Matrix
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.fragment.BaseVmFrag
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.FragmentExceptionDataBinding
import com.zj365.health.fragment.BaseSleepStatisticFrag
import com.zj365.health.vm.ExceptionVm
import com.xty.network.model.ExceptionBean
import java.text.SimpleDateFormat


/**
 *  异常数据.f
 */

open abstract class BaseExceptionDataFragment<V : ExceptionVm> : BaseVmFrag<ExceptionVm>(),
    OnChartValueSelectedListener {
    val binding by lazy { FragmentExceptionDataBinding.inflate(layoutInflater) }
    val adapter by lazy { ExceptionAdapter() }
    var clickPosition = 0

    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 = arguments?.getString(exceptionKey).toString()
        list = arguments?.getStringArrayList(exceptionList)
        listTime = arguments?.getStringArrayList(exceptionListTime)
        Log.e("mData",list?.size.toString())
        Log.e("mData",listTime?.size.toString())
        binding.tvListTitle.text = stringExtra
        listTime?.reverse()
        result.clear()
        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()
        initRecycle()
        initBarChart()
    }

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

            chart.getDescription().setEnabled(false)

            // if more than 60 entries are displayed in the chart, no values will be
            // drawn

            // if more than 60 entries are displayed in the chart, no values will be
            // drawn
            chart.setMaxVisibleValueCount(10)

            // scaling can now only be done on x- and y-axis separately

            // scaling can now only be done on x- and y-axis separately
            chart.setPinchZoom(false)

            chart.setDrawGridBackground(false)
            chart.setDrawBarShadow(false)

            chart.setDrawValueAboveBar(false)
            chart.setHighlightFullBarEnabled(true)

            // change the position of the y-labels

            // change the position of the y-labels
            val leftAxis: YAxis = chart.getAxisLeft()
//            leftAxis.valueFormatter = MyAxisValueFormatter()
//            leftAxis.setAxisLineWidth(dp2px(5).toFloat())
            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)
        }
//        values.reverse()

        val m = Matrix()
        m.postScale(
            values.size / 7f, 0f
        )
        binding.mBarChart.viewPortHandler.refresh(m, binding.mBarChart, false)
        binding.mBarChart.apply {
//
            val dataSet = BarDataSet(values, "")
//            dataSet.setColors(getColors())
            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(1f, 1.0f);
            }

            setData(barData)
            xAxis.position = XAxis.XAxisPosition.BOTTOM
            xAxis.setDrawGridLines(false)
            xAxis.labelCount = values.size
//            xAxis.enableGridDashedLine(10f, 10f, 0f);
//            xAxis.setGridColor(R.color.col_0F2);
//            xAxis.yOffset = -10f
            val leftAxis: YAxis = getAxisLeft()
            leftAxis.axisMinimum = 0f // 将Y轴最小值设置为
            leftAxis.setGridColor(resources.getColor(R.color.col_0F2));
            leftAxis.setDrawAxisLine(false);  // 隐藏左侧Y轴线
            leftAxis.setDrawLabels(true);     // 显示左侧Y轴标签文字
            leftAxis.textColor = resources.getColor(R.color.col_c7c)
            leftAxis.setGranularity(2f);
            setLabelCount(leftAxis)

            initYAxis(leftAxis)

            dataSet.setValueFormatter(BaseSleepStatisticFrag.MyYAxisValueFormatter(context))
//            xAxis.labelRotationAngle = getRotate()
            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 ""
                }
            xAxis.granularity = 1f

            val markerView = getMarkView()

            setMarker(markerView)

            setScaleYEnabled(false)

            setPinchZoom(false); // 禁止缩放
            setDoubleTapToZoomEnabled(false); // 禁止双击缩放

            // 创建一个 LimitLine 对象，并设置正常范围的值和样式
            // 创建一个 LimitLine 对象，并设置正常范围的值和样式
            val normalRange = LimitLine(getRangeMinmum(), "")
            normalRange.lineColor = resources.getColor(R.color.col_02c) // 设置线的颜色
            normalRange.lineWidth = SizeUtil.dp2px(this@BaseExceptionDataFragment.requireContext(),0.4f).toFloat() // 设置线的宽度
//            normalRange.enableDashedLine(10f, 10f, 40f) // 设置虚线样式
            getAxisLeft().addLimitLine(normalRange)

            val normalRange1 = LimitLine(getRangeMaxmum(), "")
            normalRange1.lineColor = resources.getColor(R.color.col_02c) // 设置线的颜色
            normalRange1.lineWidth =SizeUtil.dp2px(this@BaseExceptionDataFragment.requireContext(),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@BaseExceptionDataFragment.requireContext(),
            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) // 显
        }

    }

    override fun setViewModel() = ExceptionVm()

    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.requireContext(), 30))
        binding.mRecycle.layoutManager = LinearLayoutManager(this.requireContext())
        binding.mRecycle.adapter = adapter
        var data = mutableListOf<ExceptionBean>()
        data.addAll(result)
        adapter.setNewInstance(data)

    }

    override fun onNothingSelected() {

    }

    override fun observer() {
    }
}