package com.abbidot.tracker.ui.activity.data

import android.content.Intent
import android.text.TextUtils
import android.view.View
import androidx.activity.viewModels
import com.abbidot.baselibrary.constant.EventName
import com.abbidot.baselibrary.constant.MMKVKey
import com.abbidot.baselibrary.eventbus.XEventBus
import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.baselibrary.util.MMKVUtil
import com.abbidot.baselibrary.util.Utils
import com.abbidot.tracker.R
import com.abbidot.tracker.base.BaseActivity
import com.abbidot.tracker.base.BaseDialog
import com.abbidot.tracker.bean.ActiveTimeBean
import com.abbidot.tracker.bean.PetBean
import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.constant.ConstantString
import com.abbidot.tracker.constant.GetResultCallback
import com.abbidot.tracker.databinding.ActivityMoreActivityBinding
import com.abbidot.tracker.dialog.ShowCalenderDialog
import com.abbidot.tracker.util.Util
import com.abbidot.tracker.util.ViewUtil
import com.abbidot.tracker.vm.DataDetailViewModel
import com.haibin.calendarview.Calendar

class MoreActivityActivity :
    BaseActivity<ActivityMoreActivityBinding>(ActivityMoreActivityBinding::inflate) {

    private val mDataDetailViewModel: DataDetailViewModel by viewModels()

    //    private var mCalenderDialog: ShowCalenderDialog? = null
    private lateinit var mMonthsAbbr: Array<String>

    private var mPetBean: PetBean? = null

    private var mToday = ""
    private var mActiveTimeBean: ActiveTimeBean? = null

    override fun getTopBar() = mViewBinding.moreActivityTopBar.titleTopBar

    override fun initData() {
        super.initData()
        setTopBarTitle(R.string.txt_activity)
        mRightImageButton = addRightImageButton(R.drawable.selector_share_icon_pressed1)

        mMonthsAbbr = resources.getStringArray(R.array.array_month_abbr)

        intent.extras?.apply {
            mPetBean = Util.getParcelableAdaptive(intent, ConstantString.Pet, PetBean::class.java)
        }

        mViewBinding.apply {
            val share = MMKVUtil.getInt(MMKVKey.Shared)
            if (share != ConstantInt.NoShare) {
                btnMoreActivityEditGoal.visibility = View.GONE
            }

            mPetBean?.let {
                ViewUtil.instance.setPetTypeHead(
                    ilMoreActivityPetHead.appHeadImage, it.imgurl, it.petType
                )
                tvMoreActivityPetName.text = it.petName
            }
            tvActivitySelectCalendarShow.text =
                Utils.formatTime(System.currentTimeMillis(), Utils.DATE_FORMAT_PATTERN_EN4)

            setOnClickListenerViews(tvActivitySelectCalendarShow, btnMoreActivityEditGoal)

            hcvActivityDataHorizontalCalenderView.setOnDaySelectedListener { hasChanged, year, month, day, week, items ->
                val curDate = "$year-${Utils.fill2Digits(month)}-${Utils.fill2Digits(day)}"
                val curTimestamp = Utils.stringToTimestamp(curDate, Utils.DATE_FORMAT_PATTERN_CN)
                val enDate = Utils.stringToDate(
                    curDate, Utils.DATE_FORMAT_PATTERN_CN, Utils.DATE_FORMAT_PATTERN_EN4
                )
//                mCalenderDialog?.setSelectDate(curTimestamp)
                tvActivitySelectCalendarShow.text = enDate
                getActiveTimeByDay(curDate)
            }

            ilMoreActiveTime.apply {
                ivSportDataType.setImageResource(R.drawable.icon_active_time)
                tvSportDataTitle.text = getString(R.string.txt_time)
                tvSportDataUnit.text = getString(R.string.txt_min)
            }
            ilMoreActiveCalories.apply {
                ivSportDataType.setImageResource(R.drawable.icon_calories)
                tvSportDataTitle.text = getString(R.string.data_active_calories)
                tvSportDataUnit.text = getString(R.string.txt_calorie_unit)
            }
            ilMoreActiveCaloriesAvg.apply {
                ivSportDataType.setImageResource(R.drawable.icon_calories)
                tvSportDataTitle.text = getString(R.string.txt_7days_avg)
                tvSportDataUnit.text = getString(R.string.txt_calorie_unit)
            }

            ilMoreActiveLast30TimeAvg.apply {
                ivSportDataType.setImageResource(R.drawable.icon_active_time)
                tvSportDataTitle.text = getString(R.string.txt_time_avg)
                tvSportDataUnit.text = getString(R.string.txt_min)
            }
            ilMoreActiveLast30CaloriesAvg.apply {
                ivSportDataType.setImageResource(R.drawable.icon_calories)
                tvSportDataTitle.text = getString(R.string.txt_calories_avg)
                tvSportDataUnit.text = getString(R.string.txt_calorie_unit)
            }
        }

        initSportData()

        mToday = Utils.getCurrentTime(Utils.DATE_FORMAT_PATTERN_CN)
        getActiveTimeByDay(mToday)
    }

    /**
     * 默认的数据
     */
    private fun initSportData() {
        val goal = MMKVUtil.getInt(MMKVKey.ActivityGoal)
        mViewBinding.apply {
            moreActivityTimeProgress.progress = 0
            tvMoreActivityGoalPercent.text =
                String.format(getString(R.string.txt_goal_percent), "0")
            tvMoreActivityGoal.text =
                String.format(getString(R.string.txt_min_unit_lower), "0/$goal")
            ilMoreActiveTime.tvSportDataContent.text = "0"
            ilMoreActiveCalories.tvSportDataContent.text = "0"
            ilMoreActiveCaloriesAvg.tvSportDataContent.text = "0"
            val distanceUnit = Util.getMetricUnits(mContext, ConstantInt.Type4)
            ilMoreActiveDistance.let {
                it.tvSportDataContent.text = "0"
                it.tvSportDataUnit.text = distanceUnit
            }
            tvActivityTotalDistanceUnit.text = distanceUnit
            ilMoreActiveLast30TimeAvg.tvSportDataContent.text = "0"
            ilMoreActiveLast30CaloriesAvg.tvSportDataContent.text = "0"
            tvActivityTotalTimeHour.visibility = View.INVISIBLE
            tvActivityTotalTimeHourTitle.visibility = View.INVISIBLE
            tvActivityTotalTimeMin.text = "0"
            tvActivityTotalDistance.text = "0"

            moreActiveTimeView.setData(mutableListOf())
            last7dayActiveChartView.setData(mutableListOf())
            last30dayActiveLineChartView.setData(mutableListOf())
        }
    }

    override fun liveDataObserve() {
        mDataDetailViewModel.mActiveDetailLiveData.observe(this) {
            dealRequestResult(it, object : GetResultCallback {
                override fun onResult(any: Any) {
                    it.getOrNull()?.apply {
                        setActiveData(this)
                    }
                }
            })
        }

        XEventBus.observe(this, EventName.SetGoal) {
            mActiveTimeBean?.apply {
                val goal = MMKVUtil.getInt(MMKVKey.ActivityGoal)
                setGoal(goal)
            }
        }
    }

    private fun setGoal(goalTime: Int) {
        mViewBinding.apply {
            mActiveTimeBean?.let {
                val goal = if (goalTime < ConstantInt.MinSportGoal) ConstantInt.DefaultSportGoal
                else goalTime
                val activeMin = it.activeTime / 60
                tvMoreActivityGoal.text =
                    String.format(getString(R.string.txt_min_unit_lower), "$activeMin/$goal")
                var goalPercent = activeMin / goal.toFloat()
                goalPercent = Utils.formatDecimal(goalPercent, 2).toFloat()
                goalPercent *= 100
                ViewUtil.instance.viewNumberValueAnimator(
                    tvMoreActivityGoalPercent,
                    0,
                    goalPercent.toInt(),
                    getString(R.string.txt_goal_percent)
                )
                ViewUtil.instance.viewNumberValueAnimator(
                    moreActivityTimeProgress, 0, goalPercent.toInt()
                )
            }
        }
    }

    private fun setActiveData(activeTimeBean: ActiveTimeBean) {
        mActiveTimeBean = activeTimeBean
        mViewBinding.apply {
            activeTimeBean.let {
                setGoal(it.goalTime)
                ViewUtil.instance.viewNumberValueAnimator(
                    ilMoreActiveTime.tvSportDataContent, 0, it.activeTime / 60
                )
                ViewUtil.instance.viewNumberValueAnimator(
                    ilMoreActiveCalories.tvSportDataContent, 0, it.calories
                )
                ViewUtil.instance.viewNumberValueAnimator(
                    ilMoreActiveDistance.tvSportDataContent,
                    0,
                    Util.metricConvertUnits(it.distance.toFloat(), ConstantInt.Type4, 2)
                )
                ViewUtil.instance.viewNumberValueAnimator(
                    ilMoreActiveCaloriesAvg.tvSportDataContent, 0, it.calories / 7
                )
                ViewUtil.instance.viewNumberValueAnimator(
                    tvActivityTotalDistance, 0, Util.metricConvertUnits(
                        it.totalDistance.toFloat(), ConstantInt.Type4, 2
                    )
                )
                val h = it.totalTimes / 3600
                if (h == 0) {
                    tvActivityTotalTimeHour.visibility = View.INVISIBLE
                    tvActivityTotalTimeHourTitle.visibility = View.INVISIBLE
                } else {
                    tvActivityTotalTimeHour.visibility = View.VISIBLE
                    tvActivityTotalTimeHourTitle.visibility = View.VISIBLE
                    ViewUtil.instance.viewNumberValueAnimator(tvActivityTotalTimeHour, 0, h)
                }
                ViewUtil.instance.viewNumberValueAnimator(
                    tvActivityTotalTimeMin, 0, (it.totalTimes % 3600) / 60
                )

                if (!TextUtils.isEmpty(it.activeValue)) {
                    val activeTimeList = mutableListOf<Int>()
                    val activeList = it.activeValue.split(",")
                    for (i in activeList.indices step 2) {
                        val time = activeList[i].toInt() + activeList[i + 1].toInt()
                        activeTimeList.add(time / 60)
                    }
                    moreActiveTimeView.setData(activeTimeList)
                }

                it.sevenDatas?.let { s ->
                    if (s.size > 0) {
                        val yAxis = mutableListOf<String>()
                        val data = mutableListOf<Int>()
                        for (a in s) {
                            val week = Utils.stringToDate(
                                a.dayTime, Utils.DATE_FORMAT_PATTERN_CN, Utils.WEEK_FORMAT_PATTERN
                            )
                            if (a.dayTime == mToday) yAxis.add(getString(R.string.txt_today))
                            else yAxis.add(week)
                            data.add(a.activeTime / 60)
                        }
                        last7dayActiveChartView.setData(data, yAxis)
                    }
                }
                it.thirtyDatas?.let { t ->
                    if (t.size > 0) {
                        val subList = if (t.size > 30) t.subList(0, 30) else t
                        val xAxis = mutableListOf<String>()
                        val data = mutableListOf<Int>()
                        var step = 0
                        var stepValue = 0
                        var timeSum = 0
                        var kcalSum = 0.0
                        for (i in 0 until subList.size) {
                            val a = subList[i]
                            if (i == stepValue) {
                                val date = Utils.stringToDate(
                                    a.dayTime,
                                    Utils.DATE_FORMAT_PATTERN_CN,
                                    Utils.DATE_FORMAT_PATTERN_EN5
                                )
                                if (a.dayTime == mToday) xAxis.add(getString(R.string.txt_today))
                                else xAxis.add(date)
                                step++
                                stepValue = 6 * step - 1
                            }
                            val min = a.activeTime / 60
                            timeSum += min
                            kcalSum += a.calories
                            data.add(min)

                            LogUtil.e(a.dayTime + ",${t.size}")
                        }

//                        val min = it.activeTime / 60
//                        timeSum += min
//                        kcalSum += it.calories
                        ViewUtil.instance.viewNumberValueAnimator(
                            ilMoreActiveLast30TimeAvg.tvSportDataContent, 0, timeSum / data.size
                        )
                        ViewUtil.instance.viewNumberValueAnimator(
                            ilMoreActiveLast30CaloriesAvg.tvSportDataContent, 0, kcalSum / data.size
                        )
                        //反向输出
                        xAxis.reverse()
                        data.reverse()
                        last30dayActiveLineChartView.setData(data, xAxis)
                    }
                }
            }
        }
    }

    private fun getActiveTimeByDay(dayTime: String) {
        initSportData()
        mPetBean?.apply {
            mDataDetailViewModel.getActiveTimeByDay(
                this@MoreActivityActivity, deviceId, dayTime, petId
            )
        }
    }

    private fun showCalenderDialog() {
        val cTimestamp = Utils.stringToTimestamp(
            mViewBinding.tvActivitySelectCalendarShow.text.toString(), Utils.DATE_FORMAT_PATTERN_EN4
        )
        val calenderDialog =
            ShowCalenderDialog(mContext, object : BaseDialog.OnDialogSelectListener {
                override fun onSelectClick(dialog: BaseDialog<*>, any: Any) {
                    if (any is Calendar) {
                        mViewBinding.hcvActivityDataHorizontalCalenderView.setSelectedDate(
                            any.year, any.month, any.day
                        )
                    }
                }
            }, calenderShowTimestamp = cTimestamp, minLastDayRange = 29)
        calenderDialog.show()
    }

    override fun onClick(v: View?) {
        mViewBinding.apply {
            when (v!!) {
                tvActivitySelectCalendarShow -> showCalenderDialog()
                btnMoreActivityEditGoal -> mPetBean?.let { pet ->
                    Intent(mContext, DataBoardActivity::class.java).let {
                        it.putExtra(ConstantString.Pet, pet)
                        startActivity(it)
                    }
                }

                mRightImageButton -> Intent(mContext, SharePetActivityActivity::class.java).let {
                    it.putExtra(ConstantString.Pet, mPetBean)
                    it.putExtra(ConstantString.HistoryDataBean, mActiveTimeBean)
                    startActivity(it)
                }
            }
        }
    }
}