package cn.pluss.platform.device.impl;

import cn.pluss.platform.device.DeviceOperateInfoService;
import cn.pluss.platform.device.DeviceTransferDetailService;
import cn.pluss.platform.device.DeviceTransferService;
import cn.pluss.platform.deviceStock.DeviceStockService;
import cn.pluss.platform.dto.DeviceTransferDTO;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.enums.DeviceOperateType;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.mapper.DeviceTransferMapper;
import cn.pluss.platform.userApp.UserAppService;
import cn.pluss.platform.util.DateUtils;
import cn.pluss.platform.util.StringUtil;
import cn.pluss.platform.vo.DeviceTransferDetailVO;
import cn.pluss.platform.vo.DeviceTransferVO;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 设备划拨记录表 服务实现类
 * </p>
 *
 * @author crystal
 * @since 2022-03-31
 */
@Service
public class DeviceTransferServiceImpl extends ServiceImpl<DeviceTransferMapper, DeviceTransfer> implements DeviceTransferService {

    @Resource
    private DeviceTransferDetailService mtdService;

    @Resource
    private DeviceStockService deviceStockService;

    @Resource
    private DeviceOperateInfoService doiService;

    @Resource
    private UserAppService userAppService;

    /**
     * 设备划拨操作
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void transfer(DeviceTransferDTO dto) {
        UserApp userApp = userAppService.checkApiToken();
        MsgException.checkEquals(userApp.getUserId(), dto.getAcceptUserId(), "不能划拨给自己");

        dto.setUserId(userApp.getUserId());
        MsgException.checkNull(dto.getAcceptUserId(),"缺失划拨用户ID");
        UserApp acceptUser = userAppService.selectInfoJoinByUserId(dto.getAcceptUserId());
        MsgException.checkNull(acceptUser,"划拨用户异常");
        List<String> list = dto.getDeviceNoList();
        if(list == null || list.size() == 0){
            MsgException.throwException("划拨的设备编号不能为空");
        }
        QueryWrapper<DeviceStock> queryWrapper = new QueryWrapper<DeviceStock>()
                .in("deviceNo", dto.getDeviceNoList()).eq("transferStatus","01");
        List<DeviceStock> dList = deviceStockService.list(queryWrapper);
        MsgException.check(!dList.isEmpty(),"所选设备中包含等待接收的已划拨设备");
        String batchNo = StringUtil.generateMixStr(3) + DateUtils.toString(DateUtils.currentDate(),"yyyyMMddHHmmss");
        DeviceTransfer transfer = new DeviceTransfer(dto.getUserId(),dto.getAcceptUserId(),batchNo,"00",null,null);
        List<DeviceTransferDetail> detailList = new ArrayList<>();
        List<DeviceOperateInfo> operateInfoList = new ArrayList<>();
        List<String> deviceNoList = new ArrayList<>();

        baseMapper.insert(transfer);
        UpdateWrapper<DeviceStock> updateStock = new UpdateWrapper<>();
        for (String deviceNo:list) {
            DeviceTransferDetail detail = new DeviceTransferDetail(transfer,deviceNo);
            detail.setTid(transfer.getId());
            detailList.add(detail);
            String remark = acceptUser.getPhone();
            String userName = acceptUser.getUserName();
            if(StringUtil.isNotEmpty(userName)){
                remark = "划拨给" + userName + "(" + acceptUser.getPhone() + "), 待接收";
            }
            DeviceOperateInfo operateInfo = new DeviceOperateInfo(userApp, DeviceOperateType.TRANSFER.getCode(),deviceNo,remark);
            operateInfoList.add(operateInfo);
            deviceNoList.add(deviceNo);
        }
        updateStock.in("snNo",deviceNoList);
        updateStock.set("transferStatus","01");
        deviceStockService.update(updateStock);
        mtdService.saveBatch(detailList);
        doiService.saveBatch(operateInfoList);
    }

    /**
     * 划拨记录分页查询
     * @param page
     * @param dto
     * @return
     */
    @Override
    public Page<DeviceTransferVO> pageInfo(Page<DeviceTransferVO> page, DeviceTransferDTO dto) {
        return baseMapper.pageInfo(page,dto);
    }

    /**
     * 查询划拨明细
     * @param dto
     * @return
     */
    @Override
    public DeviceTransferVO getDetail(DeviceTransferDTO dto) {
        MsgException.checkNull(dto.getId(),"划拨ID不能为空");
        DeviceTransferVO transfer = baseMapper.selectByIdVo(dto.getId());
        MsgException.checkNull(transfer,"划拨ID数据有误！");
        List<DeviceTransferDetailVO> detailList =  mtdService.selectListByTid(transfer.getId());
        transfer.setDetailList(detailList);
        return transfer;
    }

    /**
     * 接收设备
     * @param dto
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public void accept(DeviceTransferDTO dto) {
        UserApp userApp = userAppService.checkApiToken();
        dto.setUserId(userApp.getUserId());
        MsgException.checkNull(dto.getId(),"划拨ID不能为空");
        DeviceTransfer transfer = baseMapper.selectById(dto.getId());
        MsgException.checkNull(transfer,"划拨ID数据有误！");
        MsgException.check(!transfer.getAcceptUserId().equals(dto.getUserId()),"只能接收划拨给自己的设备");
        transfer.setAcceptTime(new Date());
        transfer.setStatus(DeviceTransfer.ALREADY_ACCEPT);
        List<DeviceTransferDetailVO> detailList =  mtdService.selectListByTid(transfer.getId());
        if(detailList.isEmpty()){
            MsgException.throwException("设备划拨详情异常");
        }
        List<String> deviceNoList = new ArrayList<>();
        List<DeviceOperateInfo> operateInfoList = new ArrayList<>();
        for (DeviceTransferDetailVO detail:detailList) {
            deviceNoList.add(detail.getDeviceNo());
            DeviceOperateInfo operateInfo = new DeviceOperateInfo(userApp, DeviceOperateType.RECEIVE.getCode(),detail.getSnNo(),null);
            operateInfoList.add(operateInfo);
        }
        UpdateWrapper<DeviceStock> updateWrapper = new UpdateWrapper<DeviceStock>()
                .set("belongUserId",transfer.getAcceptUserId())
                .set("transferStatus","00")
                .set("inStockTime",transfer.getAcceptTime()).in("snNo",deviceNoList);
        deviceStockService.update(updateWrapper);
        baseMapper.updateById(transfer);
        doiService.saveBatch(operateInfoList);
    }
}
