package com.abbidot.tracker.ui.fragment.map

import android.content.Context
import android.content.Intent
import android.location.LocationManager
import android.provider.Settings
import android.view.View
import androidx.core.view.WindowInsetsCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.commit
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import com.abbidot.baselibrary.constant.ConState
import com.abbidot.baselibrary.constant.EventName
import com.abbidot.baselibrary.constant.MMKVKey
import com.abbidot.baselibrary.eventbus.XEventBus
import com.abbidot.baselibrary.list.BaseRecyclerAdapter
import com.abbidot.baselibrary.util.AppUtils
import com.abbidot.baselibrary.util.LogUtil
import com.abbidot.baselibrary.util.MMKVUtil
import com.abbidot.tracker.R
import com.abbidot.tracker.adapter.HomeMapDeviceMsgAdapter
import com.abbidot.tracker.adapter.HomeMapDeviceStateAdapter
import com.abbidot.tracker.base.BaseDialog
import com.abbidot.tracker.base.BaseFragment
import com.abbidot.tracker.bean.BleReportDataBean
import com.abbidot.tracker.bean.BleTrackDeviceBean
import com.abbidot.tracker.bean.DataBean
import com.abbidot.tracker.bean.FamilyBean
import com.abbidot.tracker.bean.MapDeviceBean
import com.abbidot.tracker.constant.ConstantInt
import com.abbidot.tracker.constant.ConstantString
import com.abbidot.tracker.constant.GetResultCallback
import com.abbidot.tracker.database.MyDatabase
import com.abbidot.tracker.databinding.FragmentMapV2Binding
import com.abbidot.tracker.dialog.CommonDialog1
import com.abbidot.tracker.dialog.SelectMapTypeDialog
import com.abbidot.tracker.ui.activity.HomeV2Activity
import com.abbidot.tracker.ui.activity.device.MyTrackerV2Activity
import com.abbidot.tracker.ui.activity.map.LiveActivityV2
import com.abbidot.tracker.ui.common.map.HomeMapCommon
import com.abbidot.tracker.util.Util
import com.abbidot.tracker.util.ViewUtil
import com.abbidot.tracker.util.bluetooth.SRBleUtil
import com.abbidot.tracker.vm.FamilyViewModel
import com.abbidot.tracker.vm.FencesMapViewModel
import com.abbidot.tracker.vm.MapViewModel
import com.abbidot.tracker.widget.MapDeviceNetView
import com.clj.fastble.BleManager
import com.hjq.permissions.XXPermissions
import com.hjq.permissions.permission.PermissionLists
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import javax.inject.Inject


/**
 * 首页map
 * create an instance of this fragment.
 */
@AndroidEntryPoint
class MapV2Fragment : BaseFragment<FragmentMapV2Binding>(FragmentMapV2Binding::inflate) {

    private val mFencesMapViewModel: FencesMapViewModel by viewModels()
    private val mMapViewModel: MapViewModel by viewModels()
    private val mFamilyViewModel: FamilyViewModel by viewModels()

    private lateinit var mLocationManager: LocationManager

    private lateinit var mHomeV2Activity: HomeV2Activity

    private var mSelectMapTypeDialog: SelectMapTypeDialog? = null

    //当前这个页面显示的宠物下标
    private var mCurrentShowPetPos = -1

    @Inject
    lateinit var mHomeMapCommon: HomeMapCommon
    private lateinit var mFragment: Fragment
    private var mMapDeviceBean: MapDeviceBean? = null

    private lateinit var mDeviceStateList: MutableList<DataBean>
    private lateinit var mDeviceStateAdapter: HomeMapDeviceStateAdapter
    private lateinit var mDeviceMsgList: MutableList<DataBean>
    private lateinit var mDeviceMsgAdapter: HomeMapDeviceMsgAdapter

    //启动移动地图摄像机
    private var isMoveCamera = true
    private var mShowCenterLocationType = ConstantInt.PetLocationType

    //是否显示围栏
    private var isShowFence = true

    //地图类型，标准和卫星地图
    private var mMapType = ConstantInt.Type0

    companion object {
        @JvmStatic
        fun newInstance(context: Context) = MapV2Fragment().apply {
            mContext = context
        }
    }

    override fun initData() {
        mLocationManager = mContext!!.getSystemService(Context.LOCATION_SERVICE) as LocationManager
        mHomeV2Activity = activity as HomeV2Activity
        mCurrentShowPetPos = mHomeV2Activity.mSelectPetPosition

        isShowFence = Util.getShowFenceSp()

        mViewBinding.apply {
            mHomeV2Activity.edgeToEdgeAdapterBars(
                rlHomeMapTopLayout, WindowInsetsCompat.Type.statusBars()
            )
            mFragment = mHomeMapCommon.getMapFragment(
                mContext!!, miHomeMapAddressView, dnHomeMapNetView
            ) { mapLoadOk() }

            dnHomeMapNetView.setShowNetType(MapDeviceNetView.NO_NET_TYPE)
            llHomeMapTopPet.ivTopPetBtnSmall.setImageResource(R.drawable.icon_map_type)

            ViewUtil.instance.setMapSwitchLocationButtonImage(
                homeMapRefreshBtn, mShowCenterLocationType
            )

            mDeviceStateList = mutableListOf()
            mDeviceMsgList = mutableListOf()
            mMapViewModel.addDeviceDefaultStateData(mContext!!, mDeviceStateList)
            mDeviceStateAdapter = HomeMapDeviceStateAdapter(mContext!!, mDeviceStateList)
            ViewUtil.instance.setRecyclerViewVerticalLinearLayout(
                mContext!!, rvHomeMapDeviceState, mDeviceStateAdapter, bottom = 10
            )

            mDeviceMsgAdapter = HomeMapDeviceMsgAdapter(mContext!!, mDeviceMsgList)
            ViewUtil.instance.setRecyclerViewVerticalLinearLayout(
                mContext!!, rvHomeMapDeviceMsg, mDeviceMsgAdapter, bottom = 10
            )

            setOnClickListenerViews(
                homeMapRefreshBtn,
                homeMapBluetoothBtn,
                homeMapLiveBtn,
                llHomeMapTopPet.ivTopPetBtnSmall,
                llHomeMapTopPet.homeDataPetNameSmall,
                llHomeMapTopPet.homeDataPetHeadSmall.root
            )

            if (AppUtils.isDebug()) {
                llHomeMapTopPet.homeDataPetHeadSmall.appHeadImage.setOnLongClickListener {
                    mHomeV2Activity.goToDebugActivity()
                    true
                }
            }
        }

        //解决报错java.lang.IllegalArgumentException
        //No view found for id 0x7f090254 (com.abbidot.tracker:id/fc_home_map_fragment) for fragment HomeMapGoogleMapFragment
        //https://www.jianshu.com/p/9235092f407a
        childFragmentManager.commit {
            add(R.id.fc_home_map_fragment, mFragment)
        }
//        (mActivity as FragmentActivity).supportFragmentManager.commit {
//            add(R.id.fc_home_map_fragment, mFragment)
//        }

        locationPermissionsTip(1)
    }

    override fun onResume() {
        super.onResume()

        //其他页面是否选择了宠物
        if (mCurrentShowPetPos != mHomeV2Activity.mSelectPetPosition) {
            showPetNameAndHead(mHomeV2Activity.mSelectPetPosition)
        }
        mViewBinding.apply {
            homeMapLiveBtn.isEnabled = true
            homeMapBluetoothBtn.isEnabled = true
        }

        val showFence = Util.getShowFenceSp()
        //检测直播页面有没有修改围栏显示
        if (isShowFence != showFence) {
            if (null == mSelectMapTypeDialog) {
                setFencesShow(showFence)
            } else {
                mSelectMapTypeDialog?.setFencesSwitch(showFence)
            }
        }
    }

    private fun getHomeV2Activity(): HomeV2Activity? {
        return if (null == activity) {
            LogUtil.e("getHomeV2Activity,null == activity")
            null
        } else {
            activity as HomeV2Activity
        }
    }

    /**
     * 地图加载好了
     */
    private fun mapLoadOk() {
        LogUtil.e("MapV2Fragment 地图加载好了${mHomeV2Activity.mPetList}")
//        mHomeV2Activity.mDataViewModel.getHomeBindPetList(mHomeV2Activity)
        mHomeV2Activity.apply {
            if (mPetList.size > 0) showPetNameAndHead(mSelectPetPosition)
            mFamilyViewModel.getDeviceInviteInfo(this)
        }
    }

    override fun liveDataObserve() {
        //获取设备邀请信息
        mFamilyViewModel.mInviteInfoLiveData.observe(this) {
            dealRequestResult(it, object : GetResultCallback {
                override fun onResult(any: Any) {
                    it.getOrNull()?.apply {
                        if (deleteArray.isNotEmpty()) showDeleteInviteDialog(deleteArray)
                        if (inviteArray.isNotEmpty()) showInviteDialog(inviteArray)
                    }
                }
            })
        }
        //获取当前宠物位置和围栏信息
        mMapViewModel.mMapDeviceLiveData.observe(this) {
            dealRequestResult(it, object : GetResultCallback {
                override fun onResult(any: Any) {
                    val data = it.getOrNull()
                    data?.apply {
                        mMapDeviceBean = data
                        setMapData(data)
                        mMapViewModel.setDeviceStateAndWarningData(
                            mContext!!,
                            mHomeV2Activity.getPet(),
                            data,
                            mDeviceStateList,
                            mDeviceStateAdapter,
                            mDeviceMsgList,
                            mDeviceMsgAdapter,
                            mViewBinding.rvHomeMapDeviceMsg
                        )
                    }
                }
            }, showLoading = false, isRequestErrorTip = false)
        }

        //删除围栏通知
        XEventBus.observe(this, EventName.DeleteFences) {
            updateMapDeviceStatus()
        }
        //添加编辑围栏通知
        XEventBus.observe(this, EventName.RefreshFences) {
            updateMapDeviceStatus()
        }
        //直播自动结束提示
        XEventBus.observe(this, EventName.LiveAutoEnd) {
            ViewUtil.instance.showDialog(
                mContext!!, R.string.txt_live_ended, object : BaseDialog.OnDialogOkListener {
                    override fun onOkClick(dialog: BaseDialog<*>) {
                        dialog.dismiss()
                    }
                }, okTextResId = R.string.txt_sure, cancelTextResId = R.string.txt_cancel
            )
        }
        //直播超时
        XEventBus.observe(this, EventName.LiveOpenTimeOut) {
            ViewUtil.instance.showDialog(
                mContext!!,
                R.string.txt_time_out_try_again,
                object : BaseDialog.OnDialogOkListener {
                    override fun onOkClick(dialog: BaseDialog<*>) {
                        dialog.dismiss()
                        locationPermissionsTip()
                    }
                },
                okTextResId = R.string.txt_sure
            )
        }
        //蓝牙上报的数据
        XEventBus.observe(this, EventName.BleReportData) { reportData: BleReportDataBean ->
            mHomeV2Activity.getPet(false)?.apply {
                if (macID == reportData.mac) updateBleReportData(reportData)
            }
        }
        //接收蓝牙连接状态
        XEventBus.observe(this, EventName.ConnectDeviceState) { trackBle: BleTrackDeviceBean ->
            mHomeV2Activity.getPet(false)?.apply {
                //蓝牙断开就重新获取服务器数据，蓝牙数据上报断开
                if (trackBle.mac == macID && trackBle.conState != ConState.CONNECTED) {
                    //隐藏蓝牙nearby
                    mViewBinding.rvHomeMapDeviceMsg.visibility = View.GONE
                    updateMapDeviceStatus()
                }
            }
        }
    }

    /**
     * 更新蓝牙上报的数据
     */
    private fun updateBleReportData(bleReportDataBean: BleReportDataBean) {
        bleReportDataBean.apply {
            if (haveDeviceStateData) {
                mMapViewModel.stopGetData()
                if (null == mMapDeviceBean) mMapDeviceBean = MapDeviceBean()
                mMapDeviceBean?.let {
                    Util.bleReportDataToMapDevice(it, bleReportDataBean)
                    if (haveLocationData) {
                        locationList?.let { list ->
                            val location = list[list.size - 1]
                            it.longitude = location.longitude
                            it.latitude = location.latitude
                        }
                        mHomeMapCommon.setMapDeviceBean(mMapDeviceBean)
                        mHomeMapCommon.refreshPetCurrentLocation(
                            it.latitude, it.longitude, isMoveCamera
                        )
                        mHomeMapCommon.startRefreshUserLocation()
                    }
                }

                mViewBinding.homeMapLiveBtn.visibility = View.VISIBLE

                mMapViewModel.setDeviceStateAndWarningData(
                    mContext!!,
                    mHomeV2Activity.getPet(),
                    mMapDeviceBean!!,
                    mDeviceStateList,
                    mDeviceStateAdapter,
                    mDeviceMsgList,
                    mDeviceMsgAdapter,
                    mViewBinding.rvHomeMapDeviceMsg
                )
            }
        }
    }

    /**
     * 显示被删除邀请的弹窗
     */
    private fun showDeleteInviteDialog(deleteArray: MutableList<FamilyBean>) {
        lifecycleScope.launch(Dispatchers.IO) {
            val myDeviceDb = MyDatabase.deviceDao().findAll(MyDatabase.DeviceTableName)
            myDeviceDb?.apply {
                for (deviceDb in myDeviceDb) {
                    for (item in deleteArray) {
                        if (deviceDb.deviceId == item.deviceId) {
                            MyDatabase.deviceDao().delete(deviceDb)
                            LogUtil.e("删除了邀请的设备")
                        }
                    }
                }
            }
            val newDeviceDb = MyDatabase.deviceDao().findAll(MyDatabase.DeviceTableName)
            newDeviceDb?.apply {
                LogUtil.e("删去了邀请，还剩${newDeviceDb.size}下个设备")
            }
        }
        CommonDialog1(
            mContext!!,
            getString(R.string.txt_setting_notification),
            getString(R.string.txt_view_access),
            false,
            okClickListener = object : BaseDialog.OnDialogOkListener {
                override fun onOkClick(dialog: BaseDialog<*>) {
                    if (mHomeV2Activity.mPetList.size == 0) {
                        mHomeV2Activity.noSharePet()
                    } else {
                        mHomeV2Activity.onChangeClick(0)
                    }
                }
            }).show()
    }

    /**
     * 显示被邀请通知弹窗
     */
    private fun showInviteDialog(inviteArray: MutableList<FamilyBean>) {
        for (item in inviteArray) {
            val content = String.format(
                getString(R.string.txt_invites_you_check), item.userName, item.petName
            )
            CommonDialog1(
                mContext!!,
                getString(R.string.txt_setting_notification),
                content,
                false,
                okClickListener = object : BaseDialog.OnDialogOkListener {
                    override fun onOkClick(dialog: BaseDialog<*>) {
                        startActivity(
                            mHomeV2Activity, Intent(
                                mHomeV2Activity, MyTrackerV2Activity::class.java
                            )
                        )
                    }
                }).show()
        }
    }

    private val mPermissionsTips =
        "ABBIDOT APP collects location data,The route and distance between the current location and the device can be calculated."

    /**
     * 弹窗说明需要位置权限做什么，上架市场需要
     */
    private fun locationPermissionsTip(type: Int = 0) {
        if (XXPermissions.isGrantedPermissions(
                mContext!!, mutableListOf(
                    PermissionLists.getAccessFineLocationPermission(),
                    PermissionLists.getAccessCoarseLocationPermission()
                )
            )
        ) {
            if (type == 0) checkPermissions(type)
        } else {
            ViewUtil.instance.showDialog(
                mContext!!, mPermissionsTips, object : BaseDialog.OnDialogOkListener {
                    override fun onOkClick(dialog: BaseDialog<*>) {
                        dialog.dismiss()
                        if (type == 0) checkPermissions(type)
                        else Util.checkLocationPermissionsGpsEnabled(mContext!!, {})
                    }
                }, okTextResId = R.string.txt_accept, cancelTextResId = R.string.txt_deny
            )
        }
    }

    /**
     * 更新首页设备状态数据
     */
    private fun updateMapDeviceStatus(
        isNeedCountDown: Boolean = true, useBleLocation: Boolean = false
    ) {
//        mShowCenterLocationType = ConstantInt.PetLocationType
//        ViewUtil.instance.setMapSwitchLocationButtonImage(
//            mViewBinding.homeMapRefreshBtn, mShowCenterLocationType
//        )
        if (mHomeV2Activity.mPetList.size <= mCurrentShowPetPos) return
        mHomeV2Activity.getPet()?.apply {
            //蓝牙连接上，就直接用蓝牙上报的位置刷新
            if (useBleLocation && BleManager.getInstance().isConnected(macID)) {
                mMapDeviceBean?.let {
                    mHomeMapCommon.refreshPetCurrentLocation(
                        it.latitude, it.longitude, isMoveCamera
                    )
                    mHomeMapCommon.startRefreshUserLocation()
                }
            } else {
                mMapViewModel.getMapDeviceStatus(deviceId, isNeedCountDown)
            }
        }
    }

    /**
     * 显示地图类型选择弹窗
     */
    private fun showMapTypeDialog() {
        if (null == mSelectMapTypeDialog) mSelectMapTypeDialog = ViewUtil.instance.getMapTypeDialog(
            mContext!!, object : BaseRecyclerAdapter.OnItemClickListener {
                override fun onItemClick(itemView: View?, pos: Int) {
                    mMapType = Util.getMapTypeSp()
                    if (pos == mMapType) {
                        return
                    }
                    mHomeMapCommon.switchSatelliteAndNormalMapType()
                }
            }) { v, isChecked ->
            if (v.id == R.id.cb_dialog_map_fences_switch) {
                setFencesShow(isChecked)
            }
        }
        else {
            mSelectMapTypeDialog!!.mapTypeSpToUpdate()
        }
        mSelectMapTypeDialog?.show()
    }

    /**
     * 设置围栏显示
     */
    private fun setFencesShow(isShow: Boolean) {
        isShowFence = isShow
        MMKVUtil.putBoolean(MMKVKey.ShowFence, isShow)
        if (isShow) {
            mMapDeviceBean?.fences?.let { fences ->
                mFencesMapViewModel.setFencesData(mContext!!, fences, mFragment)
            }
        } else {
            mFencesMapViewModel.setFencesData(mContext!!, null, mFragment)
        }
    }

    /**
     * 设置需要更新的标识
     */
    fun setNeedUpdateTag() {
        mCurrentShowPetPos = -1
    }

    /**
     * 显示选择宠物
     */
    fun showPetNameAndHead(position: Int) {
        //变量初始化
        if (!::mHomeV2Activity.isInitialized) {
            return
        }
        if (mHomeV2Activity.mPetList.size == 0) {
            return
        }
        mCurrentShowPetPos = position

        ViewUtil.instance.selectPetDialogShow(
            mContext!!,
            mHomeV2Activity.mPetList,
            position,
            mViewBinding.llHomeMapTopPet.homeDataPetNameSmall,
            mViewBinding.llHomeMapTopPet.homeDataPetHeadSmall.appHeadImage
        )

        if (mHomeMapCommon.isMapLoadOk()) {
            isMoveCamera=true
            mHomeMapCommon.clearMarker()
            mViewBinding.miHomeMapAddressView.visibility = View.GONE
            mViewBinding.rvHomeMapDeviceMsg.visibility = View.GONE
            showLoading(true)
            val pet = mHomeV2Activity.mPetList[position]
            //重新设置地图宠物头像
            mHomeMapCommon.setPetHeadIcon(pet.imgurl, pet.petType)

            //获取首页设备信息状态
            updateMapDeviceStatus()
        }
    }


    /**
     * 设置地图相关数据
     */
    private fun setMapData(mapDeviceBean: MapDeviceBean) {
        mapDeviceBean.apply {
            //分钟后无上报、没有lte信号或在wifi中隐藏直播按钮
            mViewBinding.homeMapLiveBtn.visibility =
                if (Util.isTimeoutReport(updateTime) || powerSwitch == ConstantInt.Type0 || powerSwitch == ConstantInt.Type2 || inWifiZone == ConstantInt.Type1) View.GONE
                else View.VISIBLE

            mHomeMapCommon.setMapDeviceBean(this)
            //设置循环查询时间间隔 30秒
            mMapViewModel.updateMillisInFuture(0.5f)

            if (isShowFence) {
                fences?.let { fences ->
                    mFencesMapViewModel.setFencesData(mContext!!, fences, mFragment)
                }
            }

//            mShowCenterLocationType = ConstantInt.PetLocationType
//            ViewUtil.instance.setMapSwitchLocationButtonImage(
//                mViewBinding.homeMapRefreshBtn, mShowCenterLocationType
//            )
            mHomeMapCommon.refreshPetCurrentLocation(latitude, longitude, isMoveCamera)
            mHomeMapCommon.startRefreshUserLocation()

            isMoveCamera = false
        }
    }

    /**
     * 检查获取定位,蓝牙权限
     */
    private fun checkPermissions(type: Int) {
        Util.checkBluetoothPermissionsEnabled(mContext!!, {
            if (type == 0) {
                if (!mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                    val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
                    startActivity(intent)
                } else if (mHomeV2Activity.isRequestPetData && mHomeV2Activity.mPetList.size == 0) {
                    showToast(R.string.no_bind_pet)
                } else {
                    mHomeV2Activity.getPet()?.apply {
                        mViewBinding.homeMapLiveBtn.isEnabled = false
                        val intent = Intent(mContext, LiveActivityV2::class.java)
                        intent.putExtra(ConstantString.JumpActivity, true)
                        intent.putExtra(ConstantString.Pet, this)
                        startActivity(intent)
                    }
                }
            } else if (type == 1) {
                if (!SRBleUtil.instance.isBleEnable(mContext!!)) {
                    SRBleUtil.instance.openBluetooth(mContext!!)
                } else if (mHomeV2Activity.isRequestPetData && mHomeV2Activity.mPetList.size == 0) {
                    showToast(R.string.no_bind_pet)
                } else {
                    mHomeV2Activity.getPet()?.apply {
                        mViewBinding.homeMapBluetoothBtn.isEnabled = false
                        val intent = Intent(mContext, LiveActivityV2::class.java)
                        intent.putExtra(ConstantString.JumpActivity, false)
                        intent.putExtra(ConstantString.Pet, this)
                        startActivity(intent)
                    }
                }
            }
        })
    }

    override fun onClick(v: View?) {
        mViewBinding.apply {
            when (v!!) {
                homeMapRefreshBtn -> {
                    if (mHomeV2Activity.isRequestPetData && mHomeV2Activity.mPetList.size == 0) {
                        showToast(R.string.no_bind_pet)
                        return
                    }
                    if (mShowCenterLocationType == ConstantInt.PetLocationType) {
                        mShowCenterLocationType = ConstantInt.UserLocationType
                        mHomeMapCommon.switchShowLocation(mShowCenterLocationType)
                    } else {
                        mShowCenterLocationType = ConstantInt.PetLocationType
                        isMoveCamera = true
                        updateMapDeviceStatus(useBleLocation = true)
                    }
                    ViewUtil.instance.setMapSwitchLocationButtonImage(
                        homeMapRefreshBtn, mShowCenterLocationType
                    )
                }

                homeMapLiveBtn -> {
//                    locationPermissionsTip()
                    mHomeV2Activity.getPet()?.apply {
                        mViewBinding.homeMapLiveBtn.isEnabled = false
                        val intent = Intent(mContext, LiveActivityV2::class.java)
                        intent.putExtra(ConstantString.JumpActivity, true)
                        intent.putExtra(ConstantString.Pet, this)
                        startActivity(intent)
                    }
                }

                llHomeMapTopPet.ivTopPetBtnSmall -> showMapTypeDialog()
                homeMapBluetoothBtn -> checkPermissions(1)
                llHomeMapTopPet.homeDataPetNameSmall, llHomeMapTopPet.homeDataPetHeadSmall.root -> mHomeV2Activity.selectPetDialog()
            }

        }
    }
}