package com.huimv.eartag.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.huimv.eartag.dao.entity.EartagDeviceRegisterEntity;
import com.huimv.eartag.dao.repo.EartagDeviceRegisterRepo;
import com.huimv.eartag.service.ICacheService;
import com.huimv.eartag.service.IDeviceRegisterService;
import com.huimv.eartag.utils.BizConst;
import com.huimv.eartag.utils.DateUtil;
import com.huimv.eartag.vo.Result;
import com.huimv.eartag.vo.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import java.sql.Timestamp;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Project : huimv.shiwan
 * @Package : com.huimv.biosafety.uface.controller
 * @Description : TODO
 * @Version : 1.0
 * @Author : ZhuoNing
 * @Create : 2020-12-25
 **/
@Service
@Slf4j
public class DeviceRegisterServiceImpl implements IDeviceRegisterService {
    @Autowired
    private EartagDeviceRegisterRepo deviceRegisterRepo;
    @Autowired
    private ICacheService cacheService;
    @Autowired
    private com.huimv.eartag.producer.ManageProducer producer;

    @Override
    public Result addDevice(String chipId, String deviceCode, Integer deviceStatus, Integer activeStatus, String deviceAlias, String location, String remark, String farmId) throws ParseException {
        DateUtil dateUtil = new DateUtil();
        Date todayDate = dateUtil.getTodayDate();
        Timestamp nowTimestamp = dateUtil.getTimestamp();
        //判断是否存在相同的设备编码
        if(isExistSameDevice(deviceCode)){
            return new Result(BizConst.CODE_DEVICE_CODE_EXIST,BizConst.MSG_DEVICE_CODE_EXIST,false);
        }
        //
        EartagDeviceRegisterEntity deviceRegisterEntity = new EartagDeviceRegisterEntity();
        deviceRegisterEntity.setChipId(chipId.trim());
        deviceRegisterEntity.setDeviceCode(deviceCode.trim());
        deviceRegisterEntity.setFarmId(farmId.trim());
        deviceRegisterEntity.setRegisterTime(nowTimestamp);
        deviceRegisterEntity.setActiveStatus(activeStatus);
        deviceRegisterEntity.setDeviceStatus(deviceStatus);
        deviceRegisterEntity.setDeviceAlias(deviceAlias.trim());
        deviceRegisterEntity.setLocation(location.trim());
        deviceRegisterEntity.setRemark(remark.trim());
        deviceRegisterEntity.setCreateDate(new java.sql.Date(todayDate.getTime()));
        deviceRegisterRepo.saveAndFlush(deviceRegisterEntity);

        //{设置工作状态}
        setDeviceWorkStatus(deviceRegisterEntity);
        return new Result(ResultCode.SUCCESS);
    }

    @Override
    public Result editDevice(String chipId, String deviceCode, Integer lastDeviceStatus, Integer deviceStatus, Integer activeStatus, String deviceAlias, String location, String remark, Integer id) throws ParseException {
        if(deviceStatus == 2){
            activeStatus = 2;
        }
        //
//        EartagDeviceRegisterEntity deviceRegisterEntity = deviceRegisterRepo.getById(id);
        EartagDeviceRegisterEntity deviceRegisterEntity = deviceRegisterRepo.getDeviceRegister(deviceCode);
//        deviceRegisterEntity.setChipId(chipId);
//        deviceRegisterEntity.setDeviceCode(deviceCode);
        deviceRegisterEntity.setDeviceStatus(deviceStatus);
        deviceRegisterEntity.setActiveStatus(activeStatus);
        deviceRegisterEntity.setDeviceAlias(deviceAlias);
        deviceRegisterEntity.setLocation(location);
        deviceRegisterEntity.setRemark(remark);
        deviceRegisterRepo.saveAndFlush(deviceRegisterEntity);
        //设置注销状态
        if((lastDeviceStatus == 0 || lastDeviceStatus == 1) && deviceStatus == 2){
            //{设置注销状态}
            setDeviceCancelStatus(deviceRegisterEntity);
        }
        //设置工作状态
        if(lastDeviceStatus == 2 && (deviceStatus == 1 || deviceStatus == 0)){
            //{设置工作状态}
            setDeviceWorkStatus(deviceRegisterEntity);
        }
        //发送更名操作
        producer.sendUpdateDeviceAlias(JSONObject.toJSONString(deviceRegisterEntity));
        return new Result(ResultCode.SUCCESS);
    }

//    @Override
//    public Result removeDevice(String ids) {
//        String[] idsArray = ids.split(",");
//        List<Integer> idList = new ArrayList();
////        for(int a=0;a<idsArray.length;a++){
////            idList.add(Integer.parseInt(idsArray[a]));
////        }
////        deviceRegisterRepo.removeDevice(idList);
////        List<EartagDeviceRegisterEntity> deviceRegisterEntityList = deviceRegisterRepo.getDeviceRegisterByIds(idList);
////        deviceRegisterRepo.deleteAll(deviceRegisterEntityList);
////        deviceRegisterRepo.removeDevice();
//
////        EartagDeviceRegisterEntity deviceRegisterEntity = deviceRegisterRepo.getDeviceRegister(ids);
//        return new Result(ResultCode.SUCCESS);
//    }

    @Override
    public Result listDevice(String farmId, String deviceCode, Integer deviceStatus, Integer activeStatus, String deviceAlias, String location, Integer pageNo, Integer pageSize) {
        //
        Specification<EartagDeviceRegisterEntity> sf = (Specification<EartagDeviceRegisterEntity>) (root, criteriaQuery, criteriaBuilder) -> {
            //
            List<Predicate> predList = new ArrayList<>();
            //farmId
            if (null != farmId && farmId.trim().length()>0) {
                predList.add(criteriaBuilder.equal(root.get("farmId").as(String.class), farmId));
            }
            //deviceCode
            if (null != deviceCode && deviceCode.trim().length()>0) {
                predList.add(criteriaBuilder.equal(root.get("deviceCode").as(String.class), deviceCode));
            }
            //createDate
//            if (null != createDate && createDate.trim().length()>0) {
//                try {
//                    predList.add(criteriaBuilder.equal(root.get("createDate").as(java.sql.Date.class), new java.sql.Date(new DateUtil().parseDateTextToLong(createDate))));
//                } catch (ParseException e) {
//                    e.printStackTrace();
//                }
//            }
            //deviceStatus
            if (null != deviceStatus) {
                predList.add(criteriaBuilder.equal(root.get("deviceStatus").as(Integer.class), deviceStatus));
            }
            //activeStatus
            if (null != activeStatus) {
                predList.add(criteriaBuilder.equal(root.get("activeStatus").as(Integer.class), activeStatus));
            }
            //location
            if (null != location && location.trim().length()>0) {
                predList.add(criteriaBuilder.like(root.get("location").as(String.class), location));
            }
            //deviceAlias
            if (null != deviceAlias && deviceAlias.trim().length()>0) {
                predList.add(criteriaBuilder.like(root.get("deviceAlias").as(String.class), deviceAlias));
            }
            Predicate[] pred = new Predicate[predList.size()];
            Predicate and = criteriaBuilder.and(predList.toArray(pred));
            criteriaQuery.where(and);
            //
            List<Order> orders = new ArrayList<>();
            orders.add(criteriaBuilder.desc(root.get("id")));
            return criteriaQuery.orderBy(orders).getRestriction();
        };
        Pageable pageable = PageRequest.of(pageNo - 1, pageSize);
        Page<EartagDeviceRegisterEntity> entityPage = deviceRegisterRepo.findAll(sf, pageable);
        return new Result(ResultCode.SUCCESS, entityPage);
    }

    @Override
    public Result removeBatchDevice(String ids) {
        String id = "1";
        Integer id2 = 1;

        deviceRegisterRepo.getById(id2);

        return null;
    }

    @Override
    public Result setDeviceStatus(Integer id, Integer deviceStatus) throws ParseException {
//        System.out.println("## <setDeviceStatus> id="+id);
//        System.out.println("## <setDeviceStatus> deviceStatus="+deviceStatus);
        //
        EartagDeviceRegisterEntity deviceRegisterEntity = deviceRegisterRepo.getById(id);
        if(deviceRegisterEntity == null){
            log.error(BizConst.MSG_DEVICE_REGISTER_NO_EXIST);
            return new Result(BizConst.CODE_DEVICE_REGISTER_NO_EXIST,BizConst.MSG_DEVICE_REGISTER_NO_EXIST,false);
        }
        deviceRegisterEntity.setDeviceStatus(deviceStatus);
        deviceRegisterRepo.saveAndFlush(deviceRegisterEntity);
        String deviceCode = deviceRegisterEntity.getDeviceCode();
        //操作缓存
        if(deviceStatus==1){
            //{设置工作状态}
            setDeviceWorkStatus(deviceRegisterEntity);
        }else if(deviceStatus==2){
            //{设置注销状态}
            setDeviceCancelStatus(deviceRegisterEntity);
        }
        return new Result(ResultCode.SUCCESS);
    }

    /**
     * @Method      : setDeviceWorkStatus
     * @Description : 设置工作状态
     * @Params      : [deviceRegisterEntity]
     * @Return      : void
     * 
     * @Author      : ZhuoNing
     * @Date        : 2022/4/1       
     * @Time        : 10:43
     */
    private void setDeviceWorkStatus(EartagDeviceRegisterEntity deviceRegisterEntity) throws ParseException {
        String deviceCode = deviceRegisterEntity.getDeviceCode();
        String chipId = deviceRegisterEntity.getChipId();
//        String farmId = deviceRegisterEntity.getFarmId();
//        DateUtil dateUtil = new DateUtil();
        //设置设备注册信息缓存
        cacheService.putDeviceRegister(deviceCode,deviceRegisterEntity);
        //{将该设备编号加入到集合Set当中}
        cacheService.putAllDeviceSet(deviceCode);
        //{将芯片ID和设备编码加入缓存}
        cacheService.putChipIdToCache(chipId,deviceCode);
        //{将该设备编码加入到在线设备集合当中}
//        cacheService.putOnlineDeviceSet(farmId,deviceCode,dateUtil.getTodayDateText());

        //{将最新设备数量加入到缓存}--MQ异步处理
//        Integer deviceStatus = 1;
//        cacheService.putDeviceTotal_(getDeviceSum(deviceRegisterEntity.getFarmId(),deviceStatus),deviceRegisterEntity.getFarmId());

        //{MQ异步处理-设备注册信息}
        producer.sendSyncDeviceRegister(JSONObject.toJSONString(deviceRegisterEntity));
    }

    public Integer getDeviceSum(String farmId, Integer liveStatus){
        //# 计算处于工作状态的设备总数（设备注册表）
        List<Object[]> deviceRegList = deviceRegisterRepo.getDeviceCountByFarmIdAndLiveStatus(farmId,liveStatus);
        Object[] deviceRegObj = (Object[]) deviceRegList.get(0);
        //设备总数
        return Integer.parseInt(deviceRegObj[0].toString());
    }

    //设置注销状态
    private void setDeviceCancelStatus(EartagDeviceRegisterEntity deviceRegisterEntity) throws ParseException {
        //
        DateUtil dateUtil = new DateUtil();
        String todayDateText = dateUtil.getTodayDateText();
        String deviceCode = deviceRegisterEntity.getDeviceCode();
        String chipId = deviceRegisterEntity.getChipId();
        String farmId = deviceRegisterEntity.getFarmId();
        //删除设备注册消息
        cacheService.deleteDeviceRegister(deviceCode);
        //{从集合Set当中删除设备编号}
        cacheService.deleteDeviceCodeSetCache(deviceCode);
        //{从在线设备集合中删除该设备编码}
        cacheService.deleteOnlineDeviceSet(farmId,deviceCode,todayDateText);
        if(chipId != null){
            //{删除芯片ID缓存}
            cacheService.deleteChipIdHashCache(chipId);
        }
        //发送MQ，处理更新在线设备数
        producer.sendSyncDeviceTotal(farmId,deviceCode);
    }

    @Override
    public Result removeDevice(String ids) {
        String[] idArray = ids.split(",");
        List deviceCodeList = new ArrayList();
        for(int a=0;a<idArray.length;a++){
            EartagDeviceRegisterEntity deviceRegisterEntity = deviceRegisterRepo.getById(Integer.parseInt(idArray[a]));
            if(deviceRegisterEntity == null){
                //暂不确定这里怎么写
                //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
            }else{
                if(deviceRegisterEntity.getDeviceStatus()==2){
                    deviceRegisterRepo.delete(deviceRegisterEntity);
                }else{
                    deviceCodeList.add(deviceRegisterEntity.getDeviceCode());
                }
            }
        }
        if(deviceCodeList.size()==0){
            return new Result(ResultCode.SUCCESS);
        }else{
            return new Result(BizConst.CODE_DEVICE_STATUS_EXIST,"这些设备["+deviceCodeList.toString()+"]要先注销再删除.",false);
        }

    }

    //
    private Boolean isExistSameDevice(String deviceCode) {
        int allDeviceSetSize = cacheService.isExistAllDeviceSet();
        if(allDeviceSetSize == 0){
            //{初始化集合}
            initAllDeviceSet();
        }
        boolean isExist = cacheService.isExistDeviceCode(deviceCode);
        return isExist;
    }

    private void initAllDeviceSet() {
        List<Object[]> objectList = deviceRegisterRepo.getDeviceCodeFromDeviceRegister();
        List list = new ArrayList();
        for(int a=0;a<objectList.size();a++){
            Object[] object = (Object[]) objectList.get(a);
            list.add(object[0]);
        }
        System.out.println("list.toString()>>"+list.toString());
        cacheService.putAllDeviceSet(list);
    }
}
