package com.cm.smartgate.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cm.common.base.AbstractService;
import com.cm.common.constants.ISystemConstant;
import com.cm.common.exception.RemoveException;
import com.cm.common.exception.SearchException;
import com.cm.common.exception.UpdateException;
import com.cm.common.exception.base.SystemException;
import com.cm.common.pojo.ListPage;
import com.cm.common.result.SuccessResult;
import com.cm.common.result.SuccessResultData;
import com.cm.common.result.SuccessResultList;
import com.cm.common.utils.HashMapUtil;
import com.cm.common.utils.UUIDUtil;
import com.cm.smartgate.dao.ISmartGateDao;
import com.cm.smartgate.enums.DoorTipsTypeEnum;
import com.cm.smartgate.manager.SmartGateManager;
import com.cm.smartgate.manager.SmartGateOnlineBO;
import com.cm.smartgate.pojo.dtos.SmartGateDTO;
import com.cm.smartgate.pojo.vos.SmartGateVO;
import com.cm.smartgate.pojo.vos.check.SmartGateCheckVO;
import com.cm.smartgate.service.ISmartGateIdCardCheckService;
import com.cm.smartgate.service.ISmartGateService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * When you feel like quitting. Think about why you started
 * 当你想要放弃的时候，想想当初你为何开始
 *
 * @ClassName: SmartGateServiceImpl
 * @Description: 智慧闸机
 * @Author: WangGeng
 * @Date: 2020/8/27 9:42
 * @Version: 1.0
 **/
@Service
public class SmartGateServiceImpl extends AbstractService implements ISmartGateService {

    @Autowired
    private ISmartGateDao smartGateDao;
    @Autowired
    private ISmartGateIdCardCheckService smartGateIdCardCheckService;
    @Autowired
    private DoorModeOperationService doorModeOperationService;
    @Autowired
    private GeneralModeOperationService generalModeOperationService;
    @Autowired
    private TrustModeOperationService trustModeOperationService;
    @Autowired
    private OpenDoorOperationService openDoorOperationService;


    @Override
    public SuccessResult saveSmartGate(SmartGateVO smartGateVO) throws Exception {
        SmartGateDTO smartGateDTO = getSmartGateBySerialNo(smartGateVO.getSmartGateSerialNo());
        if (smartGateDTO != null) {
            throw new SearchException("设备编码已经存在");
        }
        Map<String, Object> params = HashMapUtil.beanToMap(smartGateVO);
        params.put("smartGateId", UUIDUtil.getUUID());
        setSaveInfo(params);
        smartGateDao.saveSmartGate(params);
        return new SuccessResult();
    }

    @Override
    public SuccessResult removeSmartGate(String ids) throws RemoveException {
        Map<String, Object> params = getHashMap(3);
        params.put("smartGateIds", Arrays.asList(ids.split("_")));
        setUpdateInfo(params);
        smartGateDao.removeSmartGate(params);
        return new SuccessResult();
    }

    @Override
    public SuccessResult updateSmartGate(String smartGateId, SmartGateVO smartGateVO) throws Exception {
        SmartGateDTO smartGateDTO = getSmartGateBySerialNo(smartGateVO.getSmartGateSerialNo());
        if (smartGateDTO != null) {
            if (!StringUtils.equals(smartGateDTO.getSmartGateId(), smartGateId)) {
                throw new SearchException("设备编码已经存在");
            }
        }
        Map<String, Object> params = HashMapUtil.beanToMap(smartGateVO);
        params.put("smartGateId", smartGateId);
        setUpdateInfo(params);
        smartGateDao.updateSmartGate(params);
        return new SuccessResult();
    }

    @Override
    public SuccessResult updateDoorMode(String smartGateId, Integer doorMode) throws SearchException {
        SmartGateDTO smartGateDTO = getSmartGateById(smartGateId);
        if (smartGateDTO == null) {
            throw new SearchException("设备编码不存在");
        }
        Map<String, Object> params = getHashMap(4);
        params.put("smartGateId", smartGateId);
        params.put("doorMode", doorMode);
        setUpdateInfo(params);
        smartGateDao.updateMode(params);
        // 设置设备
        boolean runFlag = doorModeOperationService.run(
                smartGateDTO.getSmartGateIpAddress(),
                smartGateDTO.getSmartGatePort(),
                smartGateDTO.getSmartGateUsername(),
                smartGateDTO.getSmartGatePassword(),
                doorMode);
        if (!runFlag) {
            throw new SystemException("设备操作失败");
        }
        return new SuccessResult();
    }

    @Override
    public SuccessResult updateGeneralMode(String smartGateId, Integer generalMode) throws UpdateException {
        SmartGateDTO smartGateDTO = getSmartGateById(smartGateId);
        if (smartGateDTO == null) {
            throw new SearchException("设备编码不存在");
        }
        Map<String, Object> params = getHashMap(4);
        params.put("smartGateId", smartGateId);
        params.put("generalMode", generalMode);
        setUpdateInfo(params);
        smartGateDao.updateMode(params);
        // 设置设备
        boolean runFlag = generalModeOperationService.run(
                smartGateDTO.getSmartGateIpAddress(),
                smartGateDTO.getSmartGatePort(),
                smartGateDTO.getSmartGateUsername(),
                smartGateDTO.getSmartGatePassword(),
                generalMode);
        if (!runFlag) {
            throw new SystemException("设备操作失败");
        }
        return new SuccessResult();
    }

    @Override
    public SuccessResult updateTrustMode(String smartGateId, Integer trustMode) throws UpdateException {
        SmartGateDTO smartGateDTO = getSmartGateById(smartGateId);
        if (smartGateDTO == null) {
            throw new SearchException("设备编码不存在");
        }
        Map<String, Object> params = getHashMap(4);
        params.put("smartGateId", smartGateId);
        params.put("trustMode", trustMode);
        setUpdateInfo(params);
        smartGateDao.updateMode(params);
        // 设置设备
        boolean runFlag = trustModeOperationService.run(
                smartGateDTO.getSmartGateIpAddress(),
                smartGateDTO.getSmartGatePort(),
                smartGateDTO.getSmartGateUsername(),
                smartGateDTO.getSmartGatePassword(),
                trustMode);
        if (!runFlag) {
            throw new SystemException("设备操作失败");
        }
        return new SuccessResult();
    }

    @Override
    public SmartGateDTO getSmartGateById(String smartGateId) throws SearchException {
        Map<String, Object> params = super.getHashMap(1);
        params.put("smartGateId", smartGateId);
        return smartGateDao.getSmartGate(params);
    }


    @Override
    public SmartGateDTO getSmartGateBySerialNo(String smartGateSerialNo) throws SearchException {
        Map<String, Object> params = super.getHashMap(2);
        params.put("smartGateSerialNo", smartGateSerialNo);
        return smartGateDao.getSmartGate(params);
    }

    @Override
    public SuccessResultData<String> checkSmartGateBySerialNo(String smartGateSerialNo) throws SearchException {
        SmartGateDTO smartGateDTO = getSmartGateBySerialNo(smartGateSerialNo);
        if (smartGateDTO == null) {
            return new SuccessResultData<>(ISystemConstant.IS_FALSE);
        }
        return new SuccessResultData<>(ISystemConstant.IS_TRUE);
    }

    @Override
    public SuccessResultData<String> checkSmartGateBySerialNo(String smartGateId, String smartGateSerialNo) throws SearchException {
        SmartGateDTO smartGateDTO = getSmartGateBySerialNo(smartGateSerialNo);
        if (smartGateDTO != null) {
            if (!StringUtils.equals(smartGateDTO.getSmartGateId(), smartGateId)) {
                throw new SearchException("设备编码已经存在");
            }
        }
        if (smartGateDTO != null) {
            if (!StringUtils.equals(smartGateDTO.getSmartGateId(), smartGateId)) {
                return new SuccessResultData<>(ISystemConstant.IS_TRUE);
            }
        }
        return new SuccessResultData<>(ISystemConstant.IS_FALSE);
    }

    @Override
    public List<SmartGateDTO> listSmartGate(Map<String, Object> params) throws SearchException {
        return smartGateDao.listSmartGate(params);
    }

    @Override
    public SuccessResultList<List<SmartGateDTO>> listPageSmartGate(ListPage page) throws SearchException {
        PageHelper.startPage(page.getPage(), page.getRows());
        List<SmartGateDTO> smartGateDTOs = smartGateDao.listSmartGate(page.getParams());
        SmartGateManager smartGateManager = SmartGateManager.getInstance();
        List<SmartGateOnlineBO> smartGateOnlineBOs = smartGateManager.listSmartGate();
        for (SmartGateDTO smartGateDTO : smartGateDTOs) {
            for (SmartGateOnlineBO smartGateOnlineBO : smartGateOnlineBOs) {
                if (!StringUtils.equals(smartGateDTO.getSmartGateId(), smartGateOnlineBO.getSmartGateId())) {
                    continue;
                }
                smartGateDTO.setLastOnlineTime(new DateTime(smartGateOnlineBO.getLastOnlineTime()).toString(DateTimeFormat.forPattern(ISystemConstant.DATE_FORMATTER_YYYY_MM_DD_HH_MM_SS)));
                smartGateDTO.setOnlineState(smartGateManager.isGateOffline(smartGateOnlineBO) ? 0 : 1);
                break;
            }
        }
        PageInfo<SmartGateDTO> pageInfo = new PageInfo<>(smartGateDTOs);
        return new SuccessResultList<>(smartGateDTOs, pageInfo.getPageNum(), pageInfo.getTotal());
    }

    @Override
    public SuccessResultData<Integer> countSmartGate(Map<String, Object> params) throws SearchException {
        Integer count = smartGateDao.countSmartGate(params);
        return new SuccessResultData<>(count == null ? 0 : count);
    }

    @Override
    public SuccessResult heartbeat(String serialNo) {
        SmartGateDTO smartGateDTO = getSmartGateBySerialNo(serialNo);
        if (smartGateDTO == null) {
            LOG.error("设备编码不存在");
            throw new SearchException("设备编码不存在");
        }
        SmartGateManager.getInstance().updateSmartGateManager(smartGateDTO.getSmartGateId(), serialNo);
        return new SuccessResult();
    }

    @Override
    public JSONObject getOpenDoorStateCheckByIdCard(SmartGateCheckVO smartGateCheckVO, MultipartFile picture) throws SearchException {
        savePicture(picture);
        JSONObject result = new JSONObject();
        JSONObject pictureAck = new JSONObject();
        JSONObject doorOpenAndShowTips = new JSONObject();
        pictureAck.put("PicID", smartGateCheckVO.getPicID());
        pictureAck.put("Result", true);
        result.put("PictureAck", pictureAck);
        doorOpenAndShowTips.put("Type", DoorTipsTypeEnum.BOTH.getValue());
        doorOpenAndShowTips.put("Tipstime", 3000L);
        doorOpenAndShowTips.put("BackgroundColor", Arrays.asList(new Integer[]{255, 0, 0, 204}));
        doorOpenAndShowTips.put("BorderColor", Arrays.asList(new Integer[]{255, 255, 255, 204}));
        doorOpenAndShowTips.put("DoorIndex", 0);
        doorOpenAndShowTips.put("Opendelay", 0L);
        result.put("DoorOpenAndShowTips", doorOpenAndShowTips);

        List<SmartGateCheckVO.EventVO> events = smartGateCheckVO.getEvents();
        if (events.isEmpty()) {
            LOG.debug("校验人证事件列表为空");
            doorOpenAndShowTips.put("Customtip", "校验失败，请重新校验");
            return result;
        }
        SmartGateCheckVO.EventVO event = events.get(0);
        LOG.debug("Event Code: " + event.getCode());
        if (!StringUtils.equals("EventFaceAndCardsCompare", event.getCode())) {
            LOG.debug("非人证对比模式");
            doorOpenAndShowTips.put("Customtip", "非人证对比模式");
            return result;
        }
        LOG.debug("Event Pass: " + event.getPass());
        if (event.getPass() != 1) {
            LOG.debug("人证校验不失败");
            doorOpenAndShowTips.put("Customtip", "人证校验不失败，请重新校验");
            return result;
        }
        LOG.debug("event: ", event);
        SmartGateCheckVO.EventVO.CardsInfoVO cardsInfoVO = event.getCardsInfo();
        if (cardsInfoVO == null) {
            return result;
        }
        LOG.debug("CardsInfoVO: " + cardsInfoVO);
        boolean passState = smartGateIdCardCheckService.getPassState(cardsInfoVO.getNumber());
        LOG.debug("Pass State: " + passState);
        if (!passState) {
            LOG.debug("该身份证没有预约，不通过: {}", cardsInfoVO.getNumber());
            doorOpenAndShowTips.put("Customtip", "该身份证没有预约");
            return result;
        }
        LOG.debug("有预约，放行");
        doorOpenAndShowTips.put("Customtip", "校验通过");
        doorOpenAndShowTips.put("Opendelay", 1000L);
        return result;
    }

    @Override
    public SuccessResult getOpenDoorById(String smartGateId) throws SearchException {
        SmartGateDTO smartGateDTO = getSmartGateById(smartGateId);
        if (smartGateDTO == null) {
            throw new SearchException("设备不存在");
        }
        boolean openFlag = openDoorOperationService.run(smartGateDTO.getSmartGateIpAddress(), smartGateDTO.getSmartGatePort(), smartGateDTO.getSmartGateUsername(), smartGateDTO.getSmartGatePassword(), 0);
        if (!openFlag) {
            throw new SearchException("开门失败");
        }
        return new SuccessResult();
    }

    /**
     * 操作图片，暂不做处理
     *
     * @param picture
     */
    private void savePicture(MultipartFile picture) {
        if (picture == null) {
            return;
        }
        try (InputStream inputStream = picture.getInputStream()) {
            // 暂时不做处理
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


}
