package com.zj365.health.act.binddevice

import android.annotation.SuppressLint
import android.graphics.Color
import android.graphics.DashPathEffect
import android.graphics.Matrix
import android.os.Build
import android.view.View
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.alibaba.android.arouter.facade.annotation.Route
import com.blankj.utilcode.util.TimeUtils
import com.github.mikephil.charting.components.XAxis
import com.github.mikephil.charting.components.YAxis
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.IFillFormatter
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet
import com.xty.base.act.BaseListAct
import com.xty.common.arouter.ARouterUrl
import com.xty.common.arouter.RouteManager
import com.xty.common.event.TZhongDataManageEvent
import com.zj365.health.R
import com.zj365.health.act.datamanage.DataManageTypeAct
import com.zj365.health.adapter.binddevice.BindDeviceHistoryAdapter
import com.zj365.health.databinding.ActXyChatDataBinding
import com.zj365.health.vm.DevicesChatVm
import com.zj365.health.weight.CustomXAxisRenderer
import com.zj365.health.weight.ICompareMarkView
import com.xty.network.model.BindDevHistoryBean
import com.xty.network.model.DataManageTendencyBean
import com.xty.network.model.RecentlyHealthBean
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Date
import java.util.Locale

@Route(path = ARouterUrl.BODY_BLOOD_MEASURE_CHAT)
class BloodMeasureAct : BaseListAct<DevicesChatVm>() {

    val binding by lazy { ActXyChatDataBinding.inflate(layoutInflater) }
    override fun setLayout() = binding.root

    private var titleStr = ""
    var pageType = ""

    private var dayDate = ""
    private var weekDate = ""
    private var mouthDate = ""
    private var yearDate = ""
    var id: String = ""

    //列表
    private var mBloodMeasureAdapter: BindDeviceHistoryAdapter = BindDeviceHistoryAdapter()

    private var lineList = arrayListOf<Entry>()  //曲线数据
    private var lineListCompare = arrayListOf<Entry>()  //曲线数据
    private lateinit var lineListData: MutableList<RecentlyHealthBean.ChartList>


    override fun initData() {
        super.initData()
        titleStr = intent.getStringExtra(DataManageTypeAct.exceptionKey).toString()
        pageType = intent.getStringExtra(DataManageTypeAct.dataType).toString()
        id = intent.getStringExtra("userId").toString()
        binding.title.mTvTitle.text = titleStr
    }

    override fun initView() {
        super.initView()
        //设置状态栏
        statusBar(binding.title.mView)
        binding.title.mIvBack.apply {
            this.setOnClickListener {
                finish()
            }
        }

        //初始化没数据显示的图表
        initChartNoData()

        val currentDay = Date()
        dayDate = TimeUtils.date2String(currentDay, "yyyy-MM-dd")
        weekDate = "${TimeUtils.date2String(getDateAdd(6), "yyyy-MM-dd")}至$dayDate"
        mouthDate = TimeUtils.date2String(currentDay, "yyyy-MM")
        yearDate = TimeUtils.date2String(currentDay, "yyyy")

        //初始化控件点击事件
        initOnClick()

    }

    /**
     * 初始化没数据显示的图表
     */
    private fun initChartNoData() {

        binding.mLineChartList.setNoDataText(getString(com.zj365.health.R.string.line_chart_not_data))
        binding.mLineChartList.setNoDataTextColor(
            ContextCompat.getColor(
                this,
                com.zj365.health.R.color.col_455
            )
        )
    }

    /**
     * 初始化控件点击事件
     */
    @SuppressLint("SimpleDateFormat")
    private fun initOnClick() {
        //点击跳转更多页面
        binding.tvDataContrastList.setOnClickListener {
            bundle.clear()
//            bundle.putString(DataManageTypeAct.dataType, pageType)
//            bundle.putString(DataManageTypeAct.exceptionKey, titleStr)
            bundle.putString("userId", id)
            //根据类型字段跳转不同数据页面。
            RouteManager.goAct(ARouterUrl.XUEYAJI_BIND_HISTORY, bundle)
        }

    }

    override fun initAdapter() {
        binding.mRecycle.layoutManager = LinearLayoutManager(this)
        binding.mRecycle.adapter = mBloodMeasureAdapter
        setRecycleRefresh(binding.mRecycle,binding.mRefresh,false)
    }

    @SuppressLint("SimpleDateFormat")
    override fun loadData() {
        //获取最近趋势图数据
        mViewModel.getChatData(
            id,
            pageType
        )

        mViewModel.getDeviceHistory(id, BaseDeviceBindListAct.DeviceType.XUEYA.type,null,page)

    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun tizhongHealthUpdate(event: TZhongDataManageEvent) {
        loadData()
    }

    @SuppressLint("SetTextI18n")
    override fun liveObserver() {

        mViewModel.bindOk.observe(this) {
            if (it.data.records.size > 2) {
                val twoData = mutableListOf<BindDevHistoryBean>()
                twoData.add(it.data.records[0])
                twoData.add(it.data.records[1])
                setDate(mBloodMeasureAdapter, twoData)
            } else {
                setDate(mBloodMeasureAdapter, it.data.records)
            }
        }

        mViewModel.getRecentyHealthReturnData.observe(this) {
            val data = it.data
            if (data.list.size == 0) {

            } else {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    val dateTime = SimpleDateFormat("HH:mm", Locale.getDefault())
                    val dateMonth = SimpleDateFormat("MM-dd", Locale.getDefault())
                    for (chartList in data.list) {
                        val time = chartList.time
                        chartList.date = dateTime.format(Date(time.toLong() * 1000))
                        chartList.time = dateMonth.format(Date(time.toLong() * 1000))
                    }

                    setRecentyHealthData(it.data)
                }
            }
        }
    }

    private fun setRecentyHealthData(data: RecentlyHealthBean) {
        lineListData = data.list
        lineList.clear()
        lineListCompare.clear()

        for ((i, chartList) in lineListData.withIndex()) {
            val listTipG = mutableListOf<String>()
            listTipG.add(chartList.time)
            listTipG.add(chartList.date)
            listTipG.add(chartList.high.toString())
            listTipG.add(chartList.low.toString())
            lineList.add(
                Entry(
                    i.toFloat(),
                    chartList.high,
                    listTipG
                )
            )
            lineListCompare.add(
                Entry(
                    i.toFloat(),
                    chartList.low,
                    listTipG
                )
            )
        }
        binding.mLineChartList.clear()

        var max = if (data.maxHigh > data.maxLow) data.maxHigh else data.maxLow
        var min = if (data.minHigh < data.minLow) data.minHigh else data.minLow
        max = if (max >= 0) max + 10 else max
        min = if (min - 10 < 0) min else min - 10
        //设置趋势图
        initLineChartList(
            max,
            min
        )
    }

    //设置趋势图
    private fun initLineChartList(max: Float, min: Float) {
        binding.mLineChartList.let {
            it.clear()
            it.setNoDataText(getString(com.zj365.health.R.string.line_chart_not_data))
            it.setNoDataTextColor(ContextCompat.getColor(this, com.zj365.health.R.color.col_455))
            it.setLayerType(View.LAYER_TYPE_SOFTWARE, null)

            it.setBackgroundColor(Color.WHITE) ///color
            it.description.isEnabled = false
            it.setTouchEnabled(true)

            it.setScaleEnabled(true)
            it.setPinchZoom(false)

            val minScale = 2f // 最小缩放比例
            val maxScale = 10f // 最大缩放比例
            it.setVisibleXRangeMaximum(maxScale)
            it.setVisibleXRangeMinimum(minScale)
            it.setDrawGridBackground(false)
            it.maxHighlightDistance = 300f

            it.isDragEnabled = true
            val m = Matrix()
            if (lineListData.size > 10) {
                m.postScale(2.8f, 1f)
            } else {
                m.postScale(0.5f, 1f)
            }
            it.viewPortHandler.refresh(m, it, false)
            it.isScaleXEnabled = true                 //支持x轴缩放
            it.isScaleYEnabled = false

            //注释显示x轴换行显示
            it.extraBottomOffset = 3 * 9f
            it.setXAxisRenderer(
                CustomXAxisRenderer(
                    it.viewPortHandler,
                    it.xAxis,
                    it.getTransformer(YAxis.AxisDependency.LEFT)
                )
            )

            val x = it.xAxis
            x.granularity = 1f  //精准设置
            x.textColor = ContextCompat.getColor(this, com.zj365.health.R.color.col_92a)
            x.isEnabled = true
            x.setDrawGridLines(false)  //不绘制y
            x.setDrawAxisLine(false)
            x.position = XAxis.XAxisPosition.BOTTOM
            x.setAvoidFirstLastClipping(false)
            x.setValueFormatter { value, axis ->
                val index = value.toInt()
                //Log.e("x轴", "$value")
                if (index < 0 || index >= lineList.size) {
                    ""
                } else {
                    "${(lineList[value.toInt()].data as MutableList<String>)[0]}\n${(lineList[value.toInt()].data as MutableList<String>)[1]}"
                }
            }
            //y轴
            //y轴
            val y = it.axisLeft
            y.setLabelCountAndMaxMinValue(6, false, min - 10, max + 10)
            y.textColor = ContextCompat.getColor(this, com.zj365.health.R.color.col_92a)
            y.setDrawAxisLine(false)
            y.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART)
            y.gridColor = ContextCompat.getColor(this, com.zj365.health.R.color.col_92a)
            y.setGridDashedLine(DashPathEffect(floatArrayOf(5f, 5f), 0f))
            y.setDrawGridLines(true)  //绘制横者的x轴
            y.setDrawZeroLine(true)

            val markerView = ICompareMarkView(
                this,
                R.layout.mark_view_compare,
                "mmHg",
                ICompareMarkView.MarkPage.XYa
            )
            it.marker = markerView
            markerView.chartView = it
            it.axisRight.isEnabled = false
            it.legend.isEnabled = false

            //   it.animateXY(2000, 2000)  //设置xy轴进入的动画
            it.invalidate()
            if (lineList.isNotEmpty()) {

                val barsetsNew: java.util.ArrayList<ILineDataSet> = java.util.ArrayList()

                var segments = splitDataIntoSegmentsLineList(lineListData)
                val dataSets = segments.mapNotNull { segment ->
                    if (segment.isEmpty()) return@mapNotNull null

                    val entries = segment.mapIndexed { index, model ->
                        Entry(
                            index.toFloat(),
                            model.high,
                            lineList[index].data
                        )
                    }

                    return@mapNotNull setLineListData(entries)
                }
                var segmentsCompare = splitDataIntoSegmentsLineList(lineListData)
                val dataSetsCompare = segmentsCompare.mapNotNull { segment ->
                    if (segment.isEmpty()) return@mapNotNull null

                    val entries = segment.mapIndexed { index, model ->
                        Entry(
                            index.toFloat(),
                            model.low,
                            lineListCompare[index].data
                        )
                    }
                    return@mapNotNull setLineListData2(entries)
                }
                barsetsNew.addAll(dataSetsCompare)
                barsetsNew.addAll(dataSets)
                val lineData = LineData(barsetsNew)
                lineData.setValueTextSize(9f)
                lineData.setDrawValues(false)
                it.data = lineData

                it.moveViewToX(lineList[lineList.size - 1].x)
            }
        }
    }

    private fun setLineListData(values: List<Entry>?): LineDataSet {
        val set1: LineDataSet
        if (binding.mLineChartList.data != null && binding.mLineChartList.data.dataSetCount > 0) {
            set1 = binding.mLineChartList.data.getDataSetByIndex(0) as LineDataSet
            set1.values = values
            binding.mLineChartList.data.notifyDataChanged()
            binding.mLineChartList.notifyDataSetChanged()
        } else {
            // create a dataset and give it a type
            set1 = LineDataSet(values, values.toString())
            set1.mode = LineDataSet.Mode.LINEAR
            set1.cubicIntensity = 0.2f
            set1.setDrawFilled(false)
            set1.lineWidth = 2.5f
            set1.setDrawCircleHole(false)
            set1.circleRadius = 3.5f
            set1.highLightColor =
                ContextCompat.getColor(this, com.zj365.health.R.color.col_e0b)  //设置点后高亮颜色
            set1.enableDashedHighlightLine(10f, 5f, 0f)
            set1.setCircleColor(
                ContextCompat.getColor(
                    this,
                    com.zj365.health.R.color.col_41c
                )
            )    //#41C4AF
            set1.color =
                ContextCompat.getColor(this, com.zj365.health.R.color.col_9BDd) //xian de yanse
            //set1.setFillColor(Color.WHITE);
//            set1.fillAlpha = 100
            set1.setDrawHorizontalHighlightIndicator(false)
            set1.fillFormatter =
                IFillFormatter { _, _ -> binding.mLineChartList.axisLeft.axisMinimum }
            set1.setValueFormatter { value, _, _, _ ->
                "$value"
            }

        }
        return set1
    }

    private fun setLineListData2(values: List<Entry>?): LineDataSet {
        val set1: LineDataSet
        if (binding.mLineChartList.data != null && binding.mLineChartList.data.dataSetCount > 0) {
            set1 = binding.mLineChartList.data.getDataSetByIndex(0) as LineDataSet
            set1.values = values
            binding.mLineChartList.data.notifyDataChanged()
            binding.mLineChartList.notifyDataSetChanged()
        } else {
            // create a dataset and give it a type
            set1 = LineDataSet(values, values.toString())
            set1.mode = LineDataSet.Mode.LINEAR
            set1.cubicIntensity = 0.2f
            set1.setDrawFilled(false)
            set1.lineWidth = 2.5f
            set1.setDrawCircleHole(false)
            set1.circleRadius = 3.5f
            set1.highLightColor =
                ContextCompat.getColor(this, com.zj365.health.R.color.col_e0b)  //设置点后高亮颜色
            set1.enableDashedHighlightLine(10f, 5f, 0f)
            set1.setCircleColor(
                ContextCompat.getColor(
                    this,
                    com.zj365.health.R.color.col_9BD
                )
            )    //#41C4AF
            set1.color =
                ContextCompat.getColor(this, com.zj365.health.R.color.col_9BD) //xian de yanse
            //set1.setFillColor(Color.WHITE);
//            set1.fillAlpha = 100
            set1.setDrawHorizontalHighlightIndicator(false)
            set1.fillFormatter =
                IFillFormatter { _, _ -> binding.mLineChartList.axisLeft.axisMinimum }
            set1.setValueFormatter { value, _, _, _ ->
                "$value"
            }

        }
        return set1
    }

    fun splitDataIntoSegments(dataList: MutableList<DataManageTendencyBean.Model>):
            MutableList<MutableList<DataManageTendencyBean.Model>> {
        val segments = mutableListOf<MutableList<DataManageTendencyBean.Model>>()
        var currentSegment = mutableListOf<DataManageTendencyBean.Model>()

        for (model in dataList) {
            if (model.high.isNaN()) {
                // 遇到 Float.NaN，如果当前线段不为空，则添加到结果中，并开始新的线段
                if (currentSegment.isNotEmpty()) {
                    segments.add(currentSegment)
                    currentSegment = mutableListOf()
                }
            } else {
                // 遇到有效数据，将其添加到当前线段中
                currentSegment.add(model)
            }
        }

        // 将最后一个线段添加到结果中
        if (currentSegment.isNotEmpty()) {
            segments.add(currentSegment)
        }

        return segments
    }

    fun convertTimeToIndex(time: String): Int {
        // 将时间格式转换为小时和分钟
        val parts = time.split(":")
        val hours = parts[0].toInt()
        val minutes = parts[1].toInt()

        // 计算对应的分钟数
        val totalMinutes = hours * 60 + minutes

        // 计算对应的索引值
        val index = totalMinutes / 10

        return index
    }

    private fun getDateAdd(days: Int): Date? {
        val c = Calendar.getInstance()
        c.add(Calendar.DAY_OF_MONTH, -days)
        return c.time
    }

    private fun getdateMunise(int: Int): Date {
        val calendar = Calendar.getInstance()
        calendar.add(Calendar.DAY_OF_YEAR, int)
        return calendar.time
    }

    /**
     * 获取上周的礼拜 周数
     */
    fun getPreviousWeekDateRange(weekCount: Int): String {
        val calendar = Calendar.getInstance()
        calendar.firstDayOfWeek = Calendar.MONDAY

        val currentDate = calendar.time

        val startOfWeek = calendar.clone() as Calendar
        startOfWeek.add(Calendar.WEEK_OF_YEAR, -weekCount)
        startOfWeek.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY)

        val endOfWeek = calendar.clone() as Calendar
        endOfWeek.add(Calendar.WEEK_OF_YEAR, -weekCount)
        endOfWeek.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY)

        val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
        val startDate = dateFormat.format(startOfWeek.time)
        val endDate = dateFormat.format(endOfWeek.time)

        return startDate + "至$endDate"
    }

    /**
     * 获取上个月  monthCount 月数
     */
    fun getPreviousMonthDateRange(monthCount: Int): String {
        val calendar = Calendar.getInstance()
        calendar.add(Calendar.MONTH, -monthCount)

        val dateFormat = SimpleDateFormat("yyyy-MM", Locale.getDefault())

        return dateFormat.format(calendar.time)
    }

    private fun splitDataIntoSegmentsLineList(dataList: MutableList<RecentlyHealthBean.ChartList>):
            MutableList<MutableList<RecentlyHealthBean.ChartList>> {
        val segments = mutableListOf<MutableList<RecentlyHealthBean.ChartList>>()
        var currentSegment = mutableListOf<RecentlyHealthBean.ChartList>()

        for (model in dataList) {
            if (model.dataValue.isNaN()) {
                // 遇到 Float.NaN，如果当前线段不为空，则添加到结果中，并开始新的线段
                if (currentSegment.isNotEmpty()) {
                    segments.add(currentSegment)
                    currentSegment = mutableListOf()
                }
            } else {
                // 遇到有效数据，将其添加到当前线段中
                currentSegment.add(model)
            }
        }

        // 将最后一个线段添加到结果中
        if (currentSegment.isNotEmpty()) {
            segments.add(currentSegment)
        }

        return segments
    }
}