package com.zj365.health.fragment

import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.drawable.GradientDrawable
import android.media.MediaPlayer
import android.os.Build
import android.view.View
import androidx.annotation.RequiresApi
import androidx.core.content.ContextCompat
import androidx.lifecycle.MutableLiveData
import com.xty.base.fragment.BaseVmFrag
import com.xty.common.bracelet.YCBBlueConnectHelper
import com.xty.common.bracelet.YCBManager
import com.xty.common.bracelet.YCBOrder
import com.xty.common.FileUtils
import com.xty.common.LogUtils
import com.xty.common.arouter.ARouterUrl
import com.xty.common.arouter.RouteManager
import com.xty.common.picture.PictureUtils
import com.xty.common.util.CommonToastUtils
import com.zj365.health.R
import com.zj365.health.databinding.FragXdBinding
import com.zj365.health.vm.XdVm
import com.zj365.health.weight.XdDialog
import com.yucheng.ycbtsdk.AITools
import kotlinx.coroutines.*
import java.io.File
import java.io.FileNotFoundException
import java.io.FileOutputStream
import java.io.IOException

/**
 * 心电
 */
class XdFrag : BaseVmFrag<XdVm>() {

    private val binding by lazy { FragXdBinding.inflate(layoutInflater) }
    override fun setLayout(): View = binding.root
    override fun setViewModel() = XdVm()

    //声音播放
    val mMediaPlay by lazy { MediaPlayer.create(requireContext(), R.raw.vidio); }
    var audioInterval = false// 是否到心电声音播放的时间点
    val intervalLive by lazy { MutableLiveData<String>() }

    val liveHeart by lazy { MutableLiveData<Array<String>>() } //心率血压数据

    //    val liveHrv by lazy { MutableLiveData<String>() } //HRV数据
    val listGet by lazy { MutableLiveData<MutableList<Integer>>() }
    val status by lazy { MutableLiveData<Int>() }
    private val mEcgMeasureList = mutableListOf<Integer>() // 心电测量数据
    private var isSpeeded = false
    var isStart = false
    private var index = 0 // 遍历 心电测量数据 mEcgMeasureList
    var count = 0
    private val drawLists = mutableListOf<Int>()
    var showStartDate = 0 //第一个可见数据
    private var isProgressBar = true
    var job: Job? = null
    var listBitmap = mutableListOf<Bitmap>()  //截图数据
    var savePath = "" //保存地址
    var id = ""

    var typeName = ""
    private val dialog by lazy {
        XdDialog(requireContext()) {
            YCBManager.settingHandWear(it) {
                mainScope.launch {
                    CommonToastUtils.showToast("设置成功")
                    binding.cardiographView.keepScreenOn = true //开启常亮
                    openEcg()

                }
            }
        }
    }

    override fun initData() {
        super.initData()
        id = arguments?.getString("id").toString()
    }

    @RequiresApi(Build.VERSION_CODES.M)
    override fun initView() {
        super.initView()

        binding.mStart.setOnClickListener {
            if (!it.isSelected) {
                if (YCBBlueConnectHelper.getBlueStatus()) {
                    dialog.showHand(YCBOrder.LEFT_HAND)
                }
            } else {
                endEcg()
            }
        }
        binding.mTvHistory.setOnClickListener {
            bundle.putString("id", id)
            RouteManager.goAct(ARouterUrl.XD_HISTORY, bundle)
        }

        liveHeart.observe(requireActivity()) {
            binding.mTvStatus.visibility = View.VISIBLE
            binding.mTv1.text = it[0]
            binding.mTv1.tag = it[0]

            binding.mTv3.text = it[1]
            binding.mTv3.tag = it[1]
        }
//        liveHrv.observe(requireActivity()) {
//            binding.mTv2.text = AITools.getInstance().getHRV().toString()
//            binding.mTv2.tag = AITools.getInstance().getHRV().toString()
//        }
        listGet.observe(requireActivity()) {
            mEcgMeasureList.addAll(it)
            var index = 0
            it.forEach { v ->
                if (index % 3 == 0) {
                    val value = v.toInt() / 40
                    drawLists.add(if (value > 500) 500 else value)
                }
                index++
                // drawLists.add(v.toInt())
            }
        }
        status.observe(requireActivity()) {
            binding.mTvStatus.visibility = View.VISIBLE
            when (it) {
                0 -> {
                    binding.mTvStatus.text = getString(R.string.fall_on)
                    var bg = binding.mTvStatus.background as GradientDrawable
                    bg.setColor(ContextCompat.getColor(requireContext(), R.color.col_41c))
                    bg.mutate()
                    binding.mTvStatus.setCompoundDrawables(null, null, null, null)
                }

                else -> {
                    binding.mTvStatus.text = getString(R.string.fall_off)
                    var bg = binding.mTvStatus.background as GradientDrawable
                    bg.setColor(ContextCompat.getColor(requireContext(), R.color.col_e0b))
                    bg.mutate()
                    var leftDraw = ContextCompat.getDrawable(requireContext(), R.mipmap.ic_fall_off)
                    leftDraw!!.setBounds(0, 0, leftDraw.minimumWidth, leftDraw.minimumHeight)
                    binding.mTvStatus.setCompoundDrawables(leftDraw, null, null, null)
                }

            }
        }
        intervalLive.observe(this) {
            audioInterval = true
            if (isStart) {
                edgAudio()
            }
        }

        endEcg()
    }

    /**
     * 开启监测
     */
    private fun openEcg() {
        isProgressBar = true
        binding.cardiographView.plist.clear()
        binding.cardiographView.initList()
        binding.cardiographView.invalidate()
        binding.mProgress!!.progress = count
        isStart = true
        edgAudio()

        mEcgMeasureList.clear()
        mainScope.launch {
            YCBManager.startEcg(
                { list ->
                    listGet.postValue(list)
//                    var sb = StringBuilder()
//                    list!!.forEach {
//                        sb.append("$it\n")
//                    }
                    //   saveFile(sb.toString())

                }, /*{
                    liveHrv.postValue(it)
                },*/ {
                    status.postValue(it)
                }, {
                    binding.mStart.isSelected = it
                    if (it) {
                        binding.mStart.text = getString(R.string.end_test)
                    }
                }, { heart, dbp, sbp, hrv ->
                    var array = arrayOf(heart, "$sbp/$dbp", hrv)
                    liveHeart.postValue(array)

                }) {
                if (isStart) {
                    if (mMediaPlay != null) {
                        LogUtils.d("XD日志:长度:${drawLists.size}")
                        /*if (drawLists.size > 200&&audioInterval) {
                            audioInterval=false
                            mMediaPlay.start()
                        }*/
                        if (audioInterval) {
                            audioInterval = false
                            mMediaPlay.start()
                        }
                    }
                }
            }
        }

        MainScope().launch(Dispatchers.IO) {
            while (isStart) {
                try {
                    if (binding.cardiographView!!.plist.size > binding.cardiographView!!.WidthDots + 23) {
                        isSpeeded = true
                    } else if (binding.cardiographView!!.plist.size < binding.cardiographView!!.WidthDots + 3) {
                        isSpeeded = false
                    }
                    if (isSpeeded) {
                        delay(6)//1
                    } else {
                        delay(13)//3
                    }
                } catch (e: InterruptedException) {
                    e.stackTrace
                }
                withContext(Dispatchers.Main) {
                    if (index < drawLists!!.size) {
                        if (binding.cardiographView!!.plist.size > binding.cardiographView!!.WidthDots) {
                            //第一个数据是否要被移除屏幕
                            if (showStartDate == binding.cardiographView!!.plist[0]) {
                                LogUtils.i("心电旧数据:${showStartDate}")
                                saveBitmap()
                                //将最新数据赋值
                                showStartDate =
                                    binding.cardiographView!!.plist[binding.cardiographView!!.plist.size - 1]
                                LogUtils.i("心电新数据:$showStartDate ")
                            }
                            binding.cardiographView!!.plist.removeAt(0)
                        }
                        if (index == 0) {
                            listBitmap.clear()
                            //将第一个数据保存
                            showStartDate = drawLists[0]
                        }
                        binding.cardiographView!!.plist.add(drawLists[index])
                        index++
                        binding.cardiographView!!.invalidate()
                    }
                    if (0 == drawLists.size) {
                    } else {
                        if (isProgressBar) {
                            oldRunable()
                            isProgressBar = false
                        }
                    }
                }
            }
        }

    }

    /**
     * 心电声音的时间间隔
     */
    private fun edgAudio() {
        mainScope.launch(Dispatchers.IO) {
            delay(3000)
            intervalLive.postValue("")

        }
    }

    //应该是开启循环刷新 产生连续的心电图标表信息
    fun oldRunable() {
        job = MainScope().launch {
            if (count == 0) {
                //  tvStartFinish!!.text = "开始"
            }
            //如果进度小于100,则延迟1000毫秒之后重复执行runnable
            if (count < 100 && isStart) {
                count++
                binding.mProgress!!.progress = count
                delay(600)
                oldRunable()
            } else {
                // 心电测量结束
                endEcg()
            }
        }

    }

    /*
    * ecg结束并分析
     */
    fun endEcg() {
        LogUtils.d("XD日志:endEcg!!!")
        binding.cardiographView.keepScreenOn = false //关闭常亮
        isStart = false
        if (job != null && !job!!.isCancelled) {
            job!!.cancel()
        }

        YCBManager.ecgMeasureStop {
            mainScope.launch {
                LogUtils.d("XD日志:ecgMeasureStop!!!")
                loadingView.dismiss()
                binding.mStart.isSelected = false
                listGet.value?.let {
                    it.clear()
                }
                count = 0
                binding.mProgress.progress = 0
                binding.mStart.text = getString(R.string.start_test)
                binding.mTvStatus.visibility = View.INVISIBLE
                index = 0
                LogUtils.d("XD日志:mEcgMeasureListSize:${mEcgMeasureList.size}")
                if (mEcgMeasureList.size > 2800) {
                    // 心率分析
                    loadingView.show()
                    YCBManager.getAiResult { heart, type, isAif ->
                        mainScope.launch {
                            loadingView.dismiss()
                            var typeName = ""
                            when (type) {
                                1 -> {
                                    // 正常
                                    typeName = "正常"
                                }

                                5 -> {
                                    //室早心拍
                                    typeName = "室性早博"
                                }

                                9 -> {
                                    //房早心拍
                                    typeName = "房性早博"
                                }

                                15 -> {
                                    //噪声
                                    typeName = "噪声"

                                }
                            }
                            LogUtils.d("XD日志:getAiResult TypeName:${typeName}")

//                            var sb = StringBuilder()
//                            drawLists.forEach {
//                                sb.append("$it").append("\n")
//                            }
                            //saveFile(sb.toString())
                            //mViewModel.uploadXd(heart,isAif)
                            splicingBitmap(typeName, isAif)
                        }
                    }
                } else {
                    CommonToastUtils.showToast("测量数据不记录 无效")
                }
                drawLists.clear()  //清除绘制数据 避免重复测量时导致的绘制问题
            }
        }
    }

    override fun observer() {
        mViewModel.uploadXd.observe(this) {
            bundle.clear()

            bundle.putString(
                "hr",
                if (binding.mTv1.tag == null) "0" else binding.mTv1.tag.toString()
            )
//            bundle.putString(
//                "hrv",
//                if (binding.mTv2.tag == null) "0" else binding.mTv2.tag.toString()
//            )
//            bundle.putString(
//                "dbp",
//                if (binding.mTv3.tag == null) "0" else binding.mTv3.tag.toString()
//            )

            bundle.putString("typeName", typeName)
            bundle.putString("image", savePath)
            RouteManager.goAct(ARouterUrl.XD_DETAIL, bundle)

            binding.mTv1.tag = "0"
//            binding.mTv2.tag = "0"
            binding.mTv3.tag = "0"


        }
    }

    override fun onDestroy() {
        loadingView.dismiss()
        for (bitmap in listBitmap) {
            if (bitmap != null && !bitmap.isRecycled) {
                bitmap.recycle()
            }
        }
        listBitmap.clear()
        super.onDestroy()
    }

    override fun onPause() {
        endEcg()
        super.onPause()
    }

    //保存bitmap
    private fun saveBitmap() {
        var bitmap = Bitmap.createBitmap(
            binding.mBitmap.width,
            binding.mBitmap.height,
            Bitmap.Config.ARGB_8888
        )
        var canvas = Canvas(bitmap)

        binding.mBitmap.layout(
            0,
            binding.mTopView.height,
            binding.mBitmap.width,
            binding.mTopView.height + binding.mBitmap.height
        )
        binding.mBitmap.draw(canvas)
        listBitmap.add(bitmap)

    }

    private fun saveFile(str: String) {
        val absolutePath: String =
            requireActivity().getExternalFilesDir(null)!!.getAbsoluteFile().getAbsolutePath()
        val file = File(absolutePath)
        if (!file.exists()) {
            file.mkdirs()
        }
        val s = absolutePath + File.separator.toString() + "右手.txt"
        val file1 = File(absolutePath)
        try {
            val fos = FileOutputStream(s, true)
            fos.write(str.toByteArray())
            val a = System.getProperty("line.separator")
            fos.write(a.toByteArray())
            fos.flush()
            fos.close()
        } catch (e: FileNotFoundException) {
            e.printStackTrace()
        } catch (e: IOException) {
            e.printStackTrace()
        }
    }

    /**
     * 图片合成
     */
    private fun splicingBitmap(typeName: String, isAif: Boolean) {
        LogUtils.d("XD日志:开始图片合成！！")
        if (listBitmap.isEmpty()) {
            return
        }

        this.typeName = if (isAif) "房颤" else typeName
        var bitmap = listBitmap[0]
        var bitmaps = Bitmap.createBitmap(
            bitmap.width * listBitmap.size,
            bitmap.height,
            Bitmap.Config.ARGB_8888
        )
        var canvas = Canvas(bitmaps)
        val paint = Paint()
        listBitmap.forEachIndexed { index, bitmap ->
            canvas.drawBitmap(bitmap, index * (bitmap.width).toFloat(), 0f, paint)
        }
        savePath =
            FileUtils.getCacheFile(requireContext()) + File.separator + System.currentTimeMillis() + ".jpg"
        PictureUtils.saveBitmapToFile(savePath, bitmaps)


        var hr = if (binding.mTv1.tag == null) "0" else binding.mTv1.tag.toString()
        var hrv = if (AITools.getInstance().getHRV() != 0) AITools.getInstance().getHRV()
            .toString() else "0"
        var dbp = if (binding.mTv3.tag == null) "0" else binding.mTv3.tag.toString()

        LogUtils.d("XD日志:开始上传心电信息SavePath:$savePath;; typeName:$typeName;; hr:$hr;; hrv:$hrv;; dbp:$dbp;;")
        mViewModel.uploadXdInfo(savePath, this.typeName, hr, hrv, dbp)


        /*  bundle.clear()
          bundle.putString("hr",binding.mTv1.text.toString())
          bundle.putString("hrv",binding.mTv2.text.toString())
          bundle.putString("dbp",binding.mTv3.text.toString())
          bundle.putString("typeName",if(isAif) "房颤" else typeName)
          bundle.putString("image",savePath)
          bundle.putBoolean("isAif",isAif)
          RouteManager.goAct(ARouterUrl.XD_DETAIL,bundle)*/

    }
}