package com.abbidot.tracker.ui.activity.pet

import android.content.Intent
import android.text.TextUtils
import android.view.View
import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.core.content.ContextCompat
import androidx.core.widget.doAfterTextChanged
import coil.load
import com.abbidot.baselibrary.constant.EventName
import com.abbidot.baselibrary.constant.ResultCode
import com.abbidot.baselibrary.eventbus.XEventBus
import com.abbidot.baselibrary.list.BaseRecyclerAdapter
import com.abbidot.baselibrary.util.AppUtils
import com.abbidot.baselibrary.util.Utils
import com.abbidot.tracker.R
import com.abbidot.tracker.adapter.PetLabelsAdapter
import com.abbidot.tracker.adapter.TextViewAdapter
import com.abbidot.tracker.base.BaseActivity
import com.abbidot.tracker.base.BaseDialog
import com.abbidot.tracker.bean.DataBean
import com.abbidot.tracker.bean.LabelBean
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.ActivityPetProfileBinding
import com.abbidot.tracker.dialog.CommonListDialog
import com.abbidot.tracker.dialog.SelectPetLabelDialog
import com.abbidot.tracker.dialog.SetPetWeightDialog
import com.abbidot.tracker.dialog.ShowCalenderDialog
import com.abbidot.tracker.util.Util
import com.abbidot.tracker.util.Util.Companion.limitLetterChinese
import com.abbidot.tracker.util.ViewUtil
import com.abbidot.tracker.vm.PetInfoViewModel
import com.abbidot.tracker.vm.TakePhotoAndCompressViewModel
import com.abbidot.tracker.vm.UserProfileViewModel
import com.haibin.calendarview.Calendar
import com.huantansheng.easyphotos.EasyPhotos
import com.huantansheng.easyphotos.models.album.entity.Photo

/**
 * 宠物Profile
 */
class PetProfileActivity :
    BaseActivity<ActivityPetProfileBinding>(ActivityPetProfileBinding::inflate),
    BaseDialog.OnDialogOkListener {

    private val mPetViewModel: PetInfoViewModel by viewModels()
    private val mTakePhotoAndCompressViewModel: TakePhotoAndCompressViewModel by viewModels()
    private val mUserInfoViewModel: UserProfileViewModel by viewModels()

    private var mProfileTypeDialog: CommonListDialog? = null
    private lateinit var mTypeAdapter: TextViewAdapter
    private var mBirthdayDialog: ShowCalenderDialog? = null
    private var mProfileSexDialog: CommonListDialog? = null
    private lateinit var mSexAdapter: TextViewAdapter
    private var mSetWeightDialog: SetPetWeightDialog? = null

    private var mSelectLabelDialog: SelectPetLabelDialog? = null
    private lateinit var mLabelsAdapter: PetLabelsAdapter
    private lateinit var mSelectLabelList: MutableList<LabelBean>
    private lateinit var mSelectLabelsAdapter: PetLabelsAdapter

    private var mPetBean: PetBean? = null
    private lateinit var mOldPetBean: PetBean

    //选取头像本地路径
    private var mSelectPetHeadPath = ""

    //是否编辑
    private var isEdit = false

    override fun getTopBar() = mViewBinding.petProfileTopBar.titleTopBar

    override fun initData() {
        super.initData()
        setTopBarTitle(R.string.txt_pet_profile)

        intent?.extras?.apply {
            isEdit = getBoolean(ConstantString.Edit, false)
            mPetBean = Util.getParcelableAdaptive(intent, ConstantString.Pet, PetBean::class.java)
        }
        if (null == mPetBean) mPetBean = PetBean()

        mOldPetBean = mPetBean!!.copy()

        mViewBinding.apply {
            root.setBackgroundResource(R.color.white)
            ilPetProfileNameLayout.etInputContent.doAfterTextChanged {
                it?.let { s ->
                    val text = s.toString().limitLetterChinese(16)
                    if (text != s.toString()) {
                        s.replace(0, s.length, text)
                    }
                }
            }
            ilPetProfileType.let {
                it.tvInputNameTitle.text = getString(R.string.txt_type)
                ViewUtil.instance.setEditTextDropSelectState(it.etInputContent)
                it.ivInputRepresentImage.visibility = View.VISIBLE
            }
            ilPetProfileBreed.let {
                it.tvInputNameTitle.text = getString(R.string.acccount_breed)
            }
            ilPetProfileBirthday.let {
                it.tvInputNameTitle.text = getString(R.string.acccount_birthday)
                ViewUtil.instance.setEditTextDropSelectState(it.etInputContent)
                it.ivInputRepresentImage.visibility = View.VISIBLE
                it.ivInputRepresentImage.setImageResource(R.drawable.icon_profile_birthday_edit_svg)
            }
            ilPetProfileSex.let {
                it.tvInputNameTitle.text = getString(R.string.txt_sex)
                ViewUtil.instance.setEditTextDropSelectState(it.etInputContent)
                it.ivInputRepresentImage.visibility = View.VISIBLE
            }
            ilPetProfileWeight.let {
                it.tvInputNameTitle.text = getString(R.string.acccount_weight)
                ViewUtil.instance.setEditTextDropSelectState(it.etInputContent)
                it.ivInputRepresentImage.visibility = View.VISIBLE
                it.tvInputUnitDescribe.visibility = View.VISIBLE
                it.tvInputUnitDescribe.text = Util.getMetricUnits(mContext, ConstantInt.Type1)
            }
            ilPetProfileHeight.let {
                it.tvInputNameTitle.text = getString(R.string.acccount_height)
                ViewUtil.instance.setEditTextDropSelectState(it.etInputContent)
                it.ivInputRepresentImage.visibility = View.VISIBLE
                it.tvInputUnitDescribe.visibility = View.VISIBLE
                it.tvInputUnitDescribe.text = Util.getMetricUnits(mContext, ConstantInt.Type0)
            }

            setListData()
            mSelectLabelList = mutableListOf()
            mSelectLabelsAdapter = PetLabelsAdapter(mContext, mSelectLabelList)
            ViewUtil.instance.setRecyclerViewFlexboxLayout(
                mContext,
                rvPetProfileLabel,
                mSelectLabelsAdapter,
                right = AppUtils.dpToPx(6),
                bottom = AppUtils.dpToPx(8)
            )

            setOnClickListenerViews(
                ilPetProfileType.root,
                ilPetProfileType.ivInputRepresentImage,
                ilPetProfileBirthday.root,
                ilPetProfileBirthday.ivInputRepresentImage,
                ilPetProfileSex.root,
                ilPetProfileSex.ivInputRepresentImage,
                ilPetProfileWeight.root,
                ilPetProfileWeight.ivInputRepresentImage,
                ilPetProfileHeight.root,
                ilPetProfileHeight.ivInputRepresentImage,
                rlPetProfileLabels,
                ilPetProfileHeadLayout.ilPetProfileHead.appHeadImage,
                btnPetProfileSave
            )

            setViewClickHideInputMethod(llPetProfileHeadLayout)
            setViewClickHideInputMethod(ilPetProfileHeadLayout.root)
        }

        mTakePhotoAndCompressViewModel.registerCropImageActivityResult(this)

        setPetData()
        mPetViewModel.getPetLabels(this)

        setListenKeyboardChange(methodType = ConstantInt.Type1)
    }

    override fun liveDataObserve() {
        mPetViewModel.apply {
            mPetLabelsLiveData.observe(this@PetProfileActivity) {
                dealRequestResult(it, object : GetResultCallback {
                    override fun onResult(any: Any) {
                        it.getOrNull()?.let { labels ->
                            val labelList = mutableListOf<LabelBean>()
                            for (i in 0 until labels.size) {
                                LabelBean().run {
                                    name = labels[i]
                                    if (mSelectLabelList.size > 0) {
                                        for (label in mSelectLabelList) {
                                            if (name == label.name) check = true
                                        }
                                    }
                                    labelList.add(this)
                                }
                            }
                            mLabelsAdapter.setData(labelList, true)
                        }
                    }
                })
            }

            mAddPetLiveData.observe(this@PetProfileActivity) {
                setButtonEnabled(mViewBinding.btnPetProfileSave, ConstantInt.Type1)
                dealRequestResult(it, object : GetResultCallback {
                    override fun onResult(any: Any) {
                        XEventBus.post(EventName.RefreshPet)
                        showToast(R.string.txt_add_successful, isFinish = true)
                    }
                })
            }

            mUpdatePetInfoLiveData.observe(this@PetProfileActivity) {
                setButtonEnabled(mViewBinding.btnPetProfileSave, ConstantInt.Type1)
                dealRequestResult(it, object : GetResultCallback {
                    override fun onResult(any: Any) {
                        XEventBus.post(EventName.RefreshPet)
                        showToast(R.string.txt_change_successful, isFinish = true)
                    }
                })
            }
        }

        mTakePhotoAndCompressViewModel.mPhotoPathLiveData.observe(this) {
            if (it.size > 0) {
                mSelectPetHeadPath = it[0].path
                mViewBinding.ilPetProfileHeadLayout.ilPetProfileHead.appHeadImage.load(it[0])
            }
        }

        mUserInfoViewModel.mUploadImageLiveData.observe(this) {
            dealRequestResult(it, object : GetResultCallback {
                override fun onResult(any: Any) {
                    it.getOrNull()?.apply {
//                        showToast(R.string.txt_upload_successful)
                        mPetBean?.imgurl = this
                        addAndUpdatePetProfile()
                    }
                }
            })
        }
    }

    override fun leftBackOnClick() {
        var name = mViewBinding.ilPetProfileNameLayout.etInputContent.text.toString()
        val breed = mViewBinding.ilPetProfileBreed.etInputContent.text.toString()
        name = name.trimStart()
        name = name.trimEnd()
        mPetBean?.let {
            it.petName = name
            it.breed = breed

            if (mOldPetBean.hasSameContent(it)) super.leftBackOnClick()
            else ViewUtil.instance.showDialog(
                mContext,
                R.string.txt_weather_save,
                object : BaseDialog.OnDialogOkListener {
                    override fun onOkClick(dialog: BaseDialog<*>) {
                        dialog.dismiss()
                        savePetProfile()
                    }
                },
                okTextResId = R.string.txt_sure,
                cancelListener = object : BaseDialog.OnDialogCancelListener {
                    override fun onCancelClick(dialog: BaseDialog<*>) {
                        dialog.dismiss()
                        finish()
                    }
                })
        }
    }

    private fun setPetData() {
        mViewBinding.apply {
            mPetBean?.let {
                ViewUtil.instance.setPetTypeHead(
                    ilPetProfileHeadLayout.ilPetProfileHead.appHeadImage, it.imgurl, it.petType
                )

                if (isEdit) {
                    ilPetProfileNameLayout.etInputContent.setText(it.petName)
                    ilPetProfileType.etInputContent.setText(
                        mPetViewModel.getTypeName(
                            mContext, it.petType
                        )
                    )
                    ilPetProfileBreed.etInputContent.setText(it.breed)
                    ilPetProfileSex.etInputContent.setText(
                        mPetViewModel.getSexName(
                            mContext, it.gender
                        )
                    )
                    ilPetProfileBirthday.etInputContent.setText(
                        Utils.stringToDate(
                            it.birthdayDate,
                            Utils.DATE_FORMAT_PATTERN_CN,
                            Utils.DATE_FORMAT_PATTERN_EN3
                        )
                    )
                    ilPetProfileWeight.etInputContent.setText(
                        Util.metricConvertUnits(
                            it.weight, ConstantInt.Type1
                        ).toString()
                    )
                    ilPetProfileHeight.etInputContent.setText(
                        Util.metricConvertUnits(
                            it.height, ConstantInt.Type0
                        ).toString()
                    )
                    mSelectLabelList = mPetViewModel.getLabelData(it.labels)
                    mSelectLabelsAdapter.setData(mSelectLabelList, true)
                }
            }
        }
    }


    private fun setListData() {
        val typeList = mutableListOf<DataBean>()
        DataBean().run {
            name = getString(R.string.txt_dog)
            menuType = ConstantInt.DogPetType
            typeList.add(this)
        }
        DataBean().run {
            name = getString(R.string.txt_cat)
            menuType = ConstantInt.CatPetType
            typeList.add(this)
        }
        DataBean().run {
            name = getString(R.string.txt_other)
            menuType = ConstantInt.OtherPetType
            typeList.add(this)
        }
        mTypeAdapter = TextViewAdapter(mContext, typeList).apply {
            setOnItemClickListener(object : BaseRecyclerAdapter.OnItemClickListener {
                override fun onItemClick(itemView: View?, pos: Int) {
                    val dataBean = typeList[pos]
                    mPetBean?.apply {
                        petType = dataBean.menuType
                        if (TextUtils.isEmpty(mSelectPetHeadPath) && TextUtils.isEmpty(imgurl)) ViewUtil.instance.setPetTypeHead(
                            mViewBinding.ilPetProfileHeadLayout.ilPetProfileHead.appHeadImage,
                            imgurl,
                            petType
                        )
                        mSetWeightDialog?.updatePetData(this)
                    }
                    mViewBinding.ilPetProfileType.etInputContent.setText(dataBean.name)
                    mProfileTypeDialog?.dismiss()
                }
            })
        }

        val sexList = mutableListOf<DataBean>()
        DataBean().run {
            name = getString(R.string.pet_manage_gender_male)
            menuType = ConstantInt.Man
            sexList.add(this)
        }
        DataBean().run {
            name = getString(R.string.pet_manage_gender_female)
            menuType = ConstantInt.WoMan
            sexList.add(this)
        }
        mSexAdapter = TextViewAdapter(mContext, sexList).apply {
            setOnItemClickListener(object : BaseRecyclerAdapter.OnItemClickListener {
                override fun onItemClick(itemView: View?, pos: Int) {
                    val dataBean = sexList[pos]
                    mPetBean?.apply {
                        gender = dataBean.menuType
                    }
                    mViewBinding.ilPetProfileSex.etInputContent.setText(dataBean.name)
                    mProfileSexDialog?.dismiss()
                }
            })
        }

        mLabelsAdapter = PetLabelsAdapter(mContext, null).apply {
            setOnItemClickListener(object : BaseRecyclerAdapter.OnItemClickListener {
                override fun onItemClick(itemView: View?, pos: Int) {
                    if (mLabelsAdapter.getData().isNotEmpty()) {
                        val label = mLabelsAdapter.getData()[pos]
                        label.check = !label.check
                        notifyItemChanged(pos)
                    }
                }
            })
        }
    }

    /**
     * 显示已选的标签
     */
    private fun showSelectPetLabels() {
        val labelList = mLabelsAdapter.getData()
        mSelectLabelList.clear()
        mSelectLabelsAdapter.notifyItemRangeChanged(0, mSelectLabelList.size)
        for (lab in labelList) {
            if (lab.check) {
                LabelBean().apply {
                    name = lab.name
                    mSelectLabelList.add(this)
                }
            }
        }
        mSelectLabelsAdapter.setData(mSelectLabelList, true)

        val textColor = if (mSelectLabelList.size > 0) ContextCompat.getColor(
            mContext, R.color.data_black_color
        )
        else ContextCompat.getColor(mContext, R.color.block_color2)
        mViewBinding.tvPetProfileLabelTitle.setTextColor(textColor)

        mViewBinding.svPetProfile.fullScroll(View.FOCUS_DOWN)

        mPetBean?.apply {
            labels = if (mSelectLabelList.size > 0) mSelectLabelList.joinToString(",") { it.name }
            else ""
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (RESULT_OK == resultCode) {
            //相机或相册回调
            if (requestCode == ResultCode.ResultCode_1 && null != data) {
                //返回对象集合：如果你需要了解图片的宽、高、大小、用户是否选中原图选项等信息，可以用这个
                val resultPhotos: ArrayList<Photo> =
                    data.getParcelableArrayListExtra(EasyPhotos.RESULT_PHOTOS)!!
                //返回图片地址集合时如果你需要知道用户选择图片时是否选择了原图选项，用如下方法获取
//                data.getBooleanExtra(EasyPhotos.RESULT_SELECTED_ORIGINAL, false)
                mTakePhotoAndCompressViewModel.goCropAndCompressImage(resultPhotos)
            }
        }
    }

    private val mActivityResultLauncher =
        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
            if (null != it.data) {
                if (it.resultCode == ResultCode.ResultCode_2) {
                    //接收身高设置页面的值
                    it.data?.extras?.getFloat(ConstantString.PetHeight)?.apply {
                        mViewBinding.ilPetProfileHeight.etInputContent.setText("$this")
                        mPetBean?.height = Util.convertMetricUnits(this, ConstantInt.Type0, 4)
                    }
                } else if (it.resultCode == ResultCode.ResultCode_3) {
                    //接收体重设置页面的值
                    it.data?.extras?.getFloat(ConstantString.PetWeight)?.apply {
                        mViewBinding.ilPetProfileWeight.etInputContent.setText("$this")
                        mPetBean?.weight = Util.convertMetricUnits(this, ConstantInt.Type1, 4)
                    }
                }
            }
        }

    /**
     * 显示宠物类型弹窗
     */
    private fun showPetTypeDialog() {
        if (null == mProfileTypeDialog) {
            mProfileTypeDialog = CommonListDialog(mContext, mTypeAdapter, 3, 3)
        }
        mProfileTypeDialog?.show()
    }

    /**
     * 显示生日弹窗
     */
    private fun showBirthdayDialog() {
        if (null == mBirthdayDialog) {
            val calendar = java.util.Calendar.getInstance()
            val cYear = calendar.get(java.util.Calendar.YEAR)
            var cShowTimestamp = 0L
            mPetBean?.apply {
                cShowTimestamp = Utils.stringToTimestamp(birthdayDate, Utils.DATE_FORMAT_PATTERN_CN)
            }
            mBirthdayDialog = ShowCalenderDialog(
                mContext, object : BaseDialog.OnDialogSelectListener {
                    override fun onSelectClick(dialog: BaseDialog<*>, any: Any) {
                        if (any is Calendar) {
                            val selectBirthday = Utils.formatTime(
                                any.timeInMillis, Utils.DATE_FORMAT_PATTERN_EN3
                            )
                            mViewBinding.ilPetProfileBirthday.etInputContent.setText(
                                selectBirthday
                            )
                            mPetBean?.apply {
                                birthdayDate = Utils.formatTime(
                                    any.timeInMillis, Utils.DATE_FORMAT_PATTERN_CN
                                )
                            }
                        }
                    }
                }, minYear = cYear - 20, calenderShowTimestamp = cShowTimestamp
            )
        }
        mBirthdayDialog?.show()
    }

    /**
     * 显示性别弹窗
     */
    private fun showSexDialog() {
        if (null == mProfileSexDialog) {
            mProfileSexDialog = CommonListDialog(mContext, mSexAdapter, 3, 3)
        }
        mProfileSexDialog?.show()
    }

    /**
     * 显示体重弹窗
     */
    private fun showWeightDialog() {
        mPetBean?.apply {
            if (null == mSetWeightDialog) {
                mSetWeightDialog =
                    SetPetWeightDialog(mContext, this, object : BaseDialog.OnDialogSelectListener {
                        override fun onSelectClick(dialog: BaseDialog<*>, any: Any) {
                            if (any is String) {
                                mViewBinding.ilPetProfileWeight.etInputContent.setText(any)
                                weight = Util.convertMetricUnits(
                                    any.toFloat(), ConstantInt.Type1, 4
                                )
                            }
                        }
                    })
            }
            mSetWeightDialog?.show()
        }
    }

    /**
     * 显示标签弹窗
     */
    private fun showLabelDialog() {
        if (null == mSelectLabelDialog) {
            mSelectLabelDialog = SelectPetLabelDialog(mContext, mLabelsAdapter).apply {
                setOkListener(this@PetProfileActivity)
            }
        }
        mSelectLabelDialog?.show()
    }

    private fun addAndUpdatePetProfile() {
        mPetBean?.apply {
            if (isEdit) {
                mPetViewModel.updatePetInfo(this@PetProfileActivity, this)
            } else {
                mPetViewModel.addPet(this@PetProfileActivity, this)
            }
        }
    }

    private fun savePetProfile() {
        mViewBinding.apply {
            var name = ilPetProfileNameLayout.etInputContent.text.toString()
            val type = ilPetProfileType.etInputContent.text.toString()
            val breed = ilPetProfileBreed.etInputContent.text.toString()
            val birthday = ilPetProfileBirthday.etInputContent.text.toString()
            val sex = ilPetProfileSex.etInputContent.text.toString()
            val weight = ilPetProfileWeight.etInputContent.text.toString()
            val height = ilPetProfileHeight.etInputContent.text.toString()
            if (TextUtils.isEmpty(name) || TextUtils.isEmpty(type) || TextUtils.isEmpty(
                    birthday
                ) || TextUtils.isEmpty(sex) || TextUtils.isEmpty(weight) || TextUtils.isEmpty(height)
            ) {
                showToast(R.string.txt_not_null)
                return@apply
            }
            name = name.trimStart()
            name = name.trimEnd()
            mPetBean?.let {
                it.petName = name
                it.breed = breed
            }
            setButtonEnabled(btnPetProfileSave, ConstantInt.Type0)
            if (TextUtils.isEmpty(mSelectPetHeadPath)) {
                addAndUpdatePetProfile()
            } else {
                mUserInfoViewModel.uploadImage(this@PetProfileActivity, mSelectPetHeadPath)
            }
        }
    }

    override fun onOkClick(dialog: BaseDialog<*>) {
        dialog.dismiss()
        showSelectPetLabels()
    }

    override fun onClick(v: View?) {
        mViewBinding.apply {
            hideInputMethod(v!!)
            when (v) {
                ilPetProfileHeadLayout.ilPetProfileHead.appHeadImage -> ViewUtil.instance.goSelectPhoto(
                    this@PetProfileActivity, ResultCode.ResultCode_1
                )

                ilPetProfileType.root, ilPetProfileType.ivInputRepresentImage -> showPetTypeDialog()
                ilPetProfileBirthday.root, ilPetProfileBirthday.ivInputRepresentImage -> showBirthdayDialog()
                ilPetProfileSex.root, ilPetProfileSex.ivInputRepresentImage -> showSexDialog()
                ilPetProfileWeight.root, ilPetProfileWeight.ivInputRepresentImage -> {
                    val intent = Intent(mContext, PetWeightActivity::class.java)
                    intent.putExtra(ConstantString.Pet, mPetBean)
                    launchActivity(mActivityResultLauncher, intent)
                }

                ilPetProfileHeight.root, ilPetProfileHeight.ivInputRepresentImage -> {
                    val intent = Intent(mContext, PetHeightActivity::class.java)
                    intent.putExtra(ConstantString.Pet, mPetBean)
                    launchActivity(mActivityResultLauncher, intent)
                }

                rlPetProfileLabels -> showLabelDialog()
                btnPetProfileSave -> savePetProfile()
            }
        }
    }
}