package com.grkj.iscs.view.presenter

import com.grkj.iscs.BusinessManager
import com.grkj.iscs.R
import com.grkj.iscs.extentions.serialNo
import com.grkj.iscs.modbus.ModBusController
import com.grkj.iscs.model.Constants.JOB_STATUS_ACQUIRE_KEY
import com.grkj.iscs.model.Constants.JOB_STATUS_ACQUIRE_LOCK
import com.grkj.iscs.model.Constants.JOB_STATUS_NOT_STARTED
import com.grkj.iscs.model.Constants.USER_TYPE_LOCKER
import com.grkj.iscs.model.DeviceConst.DEVICE_TYPE_KEY
import com.grkj.iscs.model.DeviceConst.DEVICE_TYPE_LOCK
import com.grkj.iscs.model.vo.card.CardInfoRespVO
import com.grkj.iscs.model.vo.lock.LockTakeUpdateReqVO
import com.grkj.iscs.model.vo.ticket.StepDetailRespVO
import com.grkj.iscs.model.vo.ticket.TicketDetailMonitorRespVO
import com.grkj.iscs.model.vo.ticket.TicketDetailRespVO
import com.grkj.iscs.util.Executor
import com.grkj.iscs.util.NetApi
import com.grkj.iscs.util.SPUtils
import com.grkj.iscs.util.ToastUtils
import com.grkj.iscs.util.log.LogUtil
import com.grkj.iscs.view.base.BasePresenter
import com.grkj.iscs.view.iview.IJobProgressView

class JobProgressPresenter : BasePresenter<IJobProgressView>() {
    /**
     * 获取作业票详细信息
     */
    fun getTicketDetail(ticketId: Long?, callBack: (TicketDetailRespVO?) -> Unit) {
        if (ticketId == null) {
            ToastUtils.tip(mContext!!.resources.getString(R.string.ticket_id_is_null))
            return
        }
        NetApi.getTicketDetail(ticketId) {
            Executor.runOnMain {
                callBack.invoke(it)
            }
        }
    }

    fun getStepDetail(ticketId: Long, callBack: (MutableList<StepDetailRespVO>?) -> Unit) {
        NetApi.getStepDetail(ticketId) {
            Executor.runOnMain {
                callBack(it)
            }
        }
    }

    fun getTicketDetailMonitor(ticketId: Long, callBack: (TicketDetailMonitorRespVO?) -> Unit) {
        NetApi.getTicketDetailMonitor(ticketId) {
            Executor.runOnMain {
                callBack.invoke(it)
            }
        }
    }

    fun getCardInfoByNfc(cardNfc: String, callBack: (CardInfoRespVO?) -> Unit) {
        NetApi.getCardInfoByNfc(cardNfc) {
            Executor.runOnMain {
                callBack(it)
            }
        }
    }

    fun updateColockerStatus(ticketId: Long, cardNfc: String, jobStatus: String, callBack: (Boolean) -> Unit) {
        NetApi.updateColockerStatus(ticketId, cardNfc, jobStatus) {
            Executor.runOnMain {
                callBack(it)
            }
        }
    }

    /**
     * 检查是否可以继续执行后续操作（例：点击后不拿设备或者无法拿设备，又再次点击按钮）
     *
     * @return 0：可以继续
     */
//    fun checkCanProcess(ticketId: Long): Int {
//        val takeList = BusinessManager.mDeviceTakeList.filter { it.ticketId == ticketId }

//    }
    
    /**
     * 上锁人上锁流程
     */
    fun handleLockProcess(ticketId: Long) {
        getTicketDetail(ticketId) { ticketDetail ->
            LogUtil.i("getTicketDetail lock: $ticketDetail")
            val role = ticketDetail?.jobTicketUserList?.find { it.userId == SPUtils.getLoginUser(mContext!!)?.userId && it.userType == USER_TYPE_LOCKER }
            if (role == null) {
                ToastUtils.tip(R.string.you_are_not_locker_tip)
                return@getTicketDetail
            }

            // 3个状态全检查锁和钥匙分配情况，防止第一次拿了钥匙和部分锁
            if (role.jobStatus == JOB_STATUS_NOT_STARTED || role.jobStatus == JOB_STATUS_ACQUIRE_LOCK || role.jobStatus == JOB_STATUS_ACQUIRE_KEY) {
                NetApi.getTicketEquipDetail(ticketId) { equipDetail ->
                    LogUtil.i("EquipDetail : $equipDetail")
                    // 取锁具、取钥匙
                    val needLockCount = equipDetail?.ticketLockVOList?.count { it.lockId == null } ?: 0
                    val readyLockCount = BusinessManager.mDeviceTakeList.count { it.deviceType == DEVICE_TYPE_LOCK && it.ticketId == ticketId }
                    val realCount = (needLockCount - readyLockCount).coerceAtLeast(0)
                    if (readyLockCount > 0) {
                        ToastUtils.tip(R.string.please_take_out_ready_device_first)
                    }
                    val isNeedKey = equipDetail?.ticketKeyVOList?.filter { it.keyId == null }?.size != 1
                            && BusinessManager.mDeviceTakeList.none { it.deviceType == DEVICE_TYPE_KEY && it.ticketId == ticketId }
                    BusinessManager.checkEquipCount(realCount, isNeedKey) { keyPair, lockMap ->
                        val lockList = mutableListOf<LockTakeUpdateReqVO>()
                        lockMap.forEach { (addr, mLockList) ->
                            lockList.addAll(mLockList.map { LockTakeUpdateReqVO(ticketDetail.ticketId, it.rfid, mContext!!.serialNo()) })
                            // 开锁卡扣
                            ModBusController.controlLockBuckle(true, addr, mLockList.map { it.idx }.toMutableList())
                            mLockList.forEach { itLock ->
                                BusinessManager.addDeviceTake(DEVICE_TYPE_LOCK, ticketId, itLock.rfid)
                            }
                        }
                        // null表示锁具数量不够，不给钥匙
                        if (keyPair != null) {
                            BusinessManager.addDeviceTake(DEVICE_TYPE_KEY, ticketId, keyPair.second?.rfid!!)
                        }
                    }
                }
            }
        }
    }

    /**
     * 上锁人解锁流程
     */
    fun handleUnlockProcess(ticketId: Long) {
        getTicketDetail(ticketId) { ticketDetail ->
            LogUtil.i("getTicketDetail unlock: $ticketDetail")
            val role = ticketDetail?.jobTicketUserList?.find { it.userId == SPUtils.getLoginUser(mContext!!)?.userId && it.userType == USER_TYPE_LOCKER }
            if (role == null) {
                ToastUtils.tip(R.string.you_are_not_locker_tip)
                return@getTicketDetail
            }
            BusinessManager.checkEquipCount(0, true) { keyPair, _ ->
                // null表示锁具数量不够，不给钥匙
                if (keyPair != null) {
                    BusinessManager.addDeviceTake(DEVICE_TYPE_KEY, ticketId, keyPair.second?.rfid!!)
                    
                    BusinessManager.getCurrentStatus(5, BusinessManager.getBleDeviceByMac(keyPair.second?.mac)!!.bleDevice)
                }
            }
        }
    }
}