package com.yuchen.saas.park.service.service.elevator.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.thinkunion.sdk.iot.bean.api.CallingDeviceServiceResponse;
import com.yuchen.saas.park.api.dto.elevator.*;
import com.yuchen.saas.park.api.dto.elevator.iot.request.DeviceInfoDTO;
import com.yuchen.saas.park.api.dto.elevator.iot.request.DeviceInfosDTO;
import com.yuchen.saas.park.api.dto.elevator.iot.request.PersonInfoDTO;
import com.yuchen.saas.park.api.dto.elevator.iot.request.PersonInfosDTO;
import com.yuchen.saas.park.api.dto.pldoor.CallDeviceServiceDto;
import com.yuchen.saas.park.api.dto.pldoor.PlDoorAddFaceDTO;
import com.yuchen.saas.park.api.entity.elevator.*;
import com.yuchen.saas.park.api.entity.park.PmgBatParkInfo;
import com.yuchen.saas.park.api.entity.pldoor.PlDoorPoint;
import com.yuchen.saas.park.api.entity.pldoor.PlDoorUserPointSetItem;
import com.yuchen.saas.park.api.entity.pldoor.PlVisitorInfo;
import com.yuchen.saas.park.api.entity.property.PropertyBuildingUnit;
import com.yuchen.saas.park.api.entity.property.PropertyBuildings;
import com.yuchen.saas.park.api.entity.property.PropertyHouses;
import com.yuchen.saas.park.api.request.ElevatorPersonRequest;
import com.yuchen.saas.park.api.vo.elevator.ElevatorPersonVO;
import com.yuchen.saas.park.service.controller.elevator.SaasParkElevatorManageController;
import com.yuchen.saas.park.service.iot.IoTRemoteService;
import com.yuchen.saas.park.service.mapper.elevator.SaasParkElevatorPersonMapper;
import com.yuchen.saas.park.service.mapper.elevator.SaasParkElevatorRecordPermissionRecordsMapper;
import com.yuchen.saas.park.service.mapper.elevator.SaasParkElevatorRelativePersonElevatorMapper;
import com.yuchen.saas.park.service.mapper.property.PropertyBuildingUnitMapper;
import com.yuchen.saas.park.service.mapper.property.PropertyBuildingsMapper;
import com.yuchen.saas.park.service.service.PmgBatParkInfoService;
import com.yuchen.saas.park.service.service.elevator.*;
import com.yuchen.saas.park.service.service.property.PropertyBuildingUnitService;
import com.yuchen.saas.park.service.service.property.PropertyBuildingsLevelService;
import com.yuchen.saas.park.service.service.property.PropertyBuildingsService;
import com.yuchen.saas.park.service.service.property.PropertyHousesService;
import com.yuchen.saas.park.service.util.EncryptUntil;
import com.yuchen.saas.park.service.util.PicToBase64Utils;
import lombok.extern.slf4j.Slf4j;
import org.nest.springwrap.core.log.exception.ServiceException;
import org.nest.springwrap.core.mp.base.BaseServiceImpl;
import org.nest.springwrap.core.mp.support.Condition;
import org.nest.springwrap.core.mp.support.Query;
import org.nest.springwrap.core.tool.api.R;
import org.nest.springwrap.core.tool.utils.BeanUtil;
import org.nest.springwrap.core.tool.utils.Func;
import org.nest.springwrap.core.tool.utils.StringUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 梯控人员登记表 服务实现类
 * </p>
 *
 * @author baichaojie
 * @since 2024-07-08
 */
@Slf4j
@Service
public class SaasParkElevatorPersonServiceImpl extends BaseServiceImpl<SaasParkElevatorPersonMapper, SaasParkElevatorPerson> implements ISaasParkElevatorPersonService {

    @Autowired
    private IoTRemoteService ioTRemoteService;


    @Resource
    private ISaasParkElevatorManageLocationService iSaasParkElevatorManageLocationService;

    @Resource
    private ISaasParkElevatorRelativePersonElevatorService iSaasParkElevatorRelativePersonElevatorService;

    @Resource
    private SaasParkElevatorPersonMapper saasParkElevatorPersonMapper;

    @Resource
    private PropertyBuildingsMapper propertyBuildingsMapper;

    @Resource
    private PropertyBuildingUnitMapper propertyBuildingUnitMapper;

    @Resource
    private ISaasParkElevatorRecordPermissionRecordsService iSaasParkElevatorRecordPermissionRecordsService;


    @Resource
    private PmgBatParkInfoService pmgBatParkInfoService;

    @Resource
    private PropertyBuildingsService propertyBuildingsService;
    @Resource
    private PropertyBuildingUnitService propertyBuildingUnitService;
    @Resource
    private PropertyBuildingsLevelService propertyBuildingsLevelService;
    @Resource
    private PropertyHousesService propertyHousesService;


    private final String SAVEPERSON = "savePerson";

    private final String DELPERSON = "delPerson";

    private final String STARTTIME = "2000-01-01 00:00:00";
    private final String ENDTIME = "2099-01-01 00:00:00";


    @Override
    public R<IPage<ElevatorPersonVO>> list(ElevatorPersonRequest qryDTO, Query query) {

        LambdaQueryWrapper<SaasParkElevatorPerson> queryWrapperBefore = new LambdaQueryWrapper<>();

        queryWrapperBefore.eq(Func.isNotEmpty(qryDTO.getParkId()), SaasParkElevatorPerson::getParkId, qryDTO.getParkId());
        List<SaasParkElevatorPerson> listBefore = this.list(queryWrapperBefore);

        for (SaasParkElevatorPerson saasParkElevatorPerson : listBefore) {
            //根据设置的有效时间修改permissionState字段
            Date validStartTime = saasParkElevatorPerson.getValidStartTime();
            Date validEndTime = saasParkElevatorPerson.getValidEndTime();
            Date toDay = new Date();
            if (validStartTime == null) {
                saasParkElevatorPerson.setPermissionState("0");
            }
            if (validEndTime == null) {
                saasParkElevatorPerson.setPermissionState("0");
            }

            if (validStartTime != null && validEndTime != null) {
                if (toDay.before(validStartTime)) {
                    saasParkElevatorPerson.setPermissionState("0");
                } else if (toDay.after(validEndTime)) {
                    saasParkElevatorPerson.setPermissionState("2");
                } else {
                    saasParkElevatorPerson.setPermissionState("1");
                }
                this.updateById(saasParkElevatorPerson);
            }
        }


        Page<SaasParkElevatorPerson> page = new Page<>(query.getCurrent(), query.getSize());

        LambdaQueryWrapper<SaasParkElevatorPerson> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Func.isNotEmpty(qryDTO.getParkId()), SaasParkElevatorPerson::getParkId, qryDTO.getParkId());
        queryWrapper.eq(Func.isNotEmpty(qryDTO.getBuildingId()), SaasParkElevatorPerson::getBuildingId, qryDTO.getBuildingId());
        queryWrapper.eq(Func.isNotEmpty(qryDTO.getUnitId()), SaasParkElevatorPerson::getUnitId, qryDTO.getUnitId());
        queryWrapper.eq(Func.isNotEmpty(qryDTO.getRoomNumberId()), SaasParkElevatorPerson::getRoomNumberId, qryDTO.getRoomNumberId());
        queryWrapper.eq(Func.isNotEmpty(qryDTO.getSendState()), SaasParkElevatorPerson::getSendState, qryDTO.getSendState());
        queryWrapper.eq(Func.isNotEmpty(qryDTO.getPermissionState()), SaasParkElevatorPerson::getPermissionState, qryDTO.getPermissionState());
        queryWrapper.like(Func.isNotEmpty(qryDTO.getUserName()), SaasParkElevatorPerson::getUserName, qryDTO.getUserName());

        queryWrapper.orderByDesc(SaasParkElevatorPerson::getCreateTime);

        IPage<SaasParkElevatorPerson> pages = this.page(page, queryWrapper);

        List<SaasParkElevatorPerson> saasParkElevatorPersonList = pages.getRecords();


        if (saasParkElevatorPersonList.isEmpty()) {
            return R.data(Condition.getPage(query));
        }

        //组装返回response
        IPage<ElevatorPersonVO> pageVo = new Page(pages.getCurrent(), pages.getSize(), pages.getTotal());
        List<ElevatorPersonVO> records = this.listVO(pages.getRecords());

        pageVo.setRecords(records);
        return R.data(pageVo);
    }

    public List<ElevatorPersonVO> listVO(List<SaasParkElevatorPerson> listRecords) {
        return (List) listRecords.stream().map(entity -> {
            ElevatorPersonVO elevatorPersonVO = detail(entity.getId(), entity).getData();
            return elevatorPersonVO;
        }).collect(Collectors.toList());

    }


    public R<ElevatorPersonVO> detail(Long id, SaasParkElevatorPerson saasParkElevatorPerson) {
        ElevatorPersonVO elevatorPersonVO = new ElevatorPersonVO();
        BeanUtils.copyProperties(saasParkElevatorPerson, elevatorPersonVO);

        elevatorPersonVO.setFloorName(saasParkElevatorPerson.getFloorId() == null ? "" : saasParkElevatorPerson.getFloorId() + "");


        PmgBatParkInfo parkInfo = pmgBatParkInfoService.getById(saasParkElevatorPerson.getParkId());
        if (Func.isNotEmpty(parkInfo)) {
            elevatorPersonVO.setParkName(parkInfo.getParkName());
        }

        PropertyBuildings propertyBuildings = propertyBuildingsMapper.selectById(saasParkElevatorPerson.getBuildingId());
        if (propertyBuildings != null) {
            elevatorPersonVO.setBuildingName(propertyBuildings.getBuildingName());
        }

        PropertyBuildingUnit propertyBuildingUnit = propertyBuildingUnitMapper.selectById(saasParkElevatorPerson.getUnitId());
        if (propertyBuildingUnit != null) {
            elevatorPersonVO.setUnitName(propertyBuildingUnit.getUnitName());
        }


        PropertyHouses houses = propertyHousesService.getById(saasParkElevatorPerson.getRoomNumberId());
        if (houses != null) {
            elevatorPersonVO.setRoomNumberName(houses.getHouseName());
        }

        String jsonSrt = saasParkElevatorPerson.getRelativeElevatorGroupJsonStr();

        if (!StringUtil.isEmpty(jsonSrt)) {
            try {
                List<PermissionDTO> permissionDTOS = JSON.parseArray(jsonSrt, PermissionDTO.class);

                if (permissionDTOS != null) {
                    elevatorPersonVO.setPermission(permissionDTOS);
                }
            } catch (Exception ex) {
                elevatorPersonVO.setPermission(null);
            }
        }
        LambdaQueryWrapper<SaasParkElevatorRelativePersonElevator> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SaasParkElevatorRelativePersonElevator::getPersonId, saasParkElevatorPerson.getId());
        List<SaasParkElevatorRelativePersonElevator> list = iSaasParkElevatorRelativePersonElevatorService.list(queryWrapper);

        if (list != null && list.size() > 0) {
            //权限范围电梯组里的数量
            elevatorPersonVO.setPermissionDevs(list.size() + "");

            //列表里的电梯点名称
            String pointGroupName = "";
            Integer sendState0 = 0;
            Integer sendState1 = 1;
            Integer sendState2 = 2;

            for (SaasParkElevatorRelativePersonElevator saasParkElevatorRelativePersonElevator : list) {
                pointGroupName += saasParkElevatorRelativePersonElevator.getElevatorName() + ",";

                //下发状态( 0:未下发;1:已下发;2:下发失败;3:部分成功,部分失败)
                if (saasParkElevatorRelativePersonElevator.getSendState().equals("0")) {
                    sendState0++;
                }
                if (saasParkElevatorRelativePersonElevator.getSendState().equals("1")) {
                    sendState1++;
                }
                if (saasParkElevatorRelativePersonElevator.getSendState().equals("2")) {
                    sendState2++;
                }
            }

            if (sendState0 == list.size()) {
                //如果0的数量等于所有的行数,那么他是未下发
                elevatorPersonVO.setSendState("0");
            } else if (sendState1 == list.size()) {
                //如果1的数量等于所有的行数,那么他是下发成功
                elevatorPersonVO.setSendState("1");
            } else if (sendState2 == list.size()) {
                //如果2的数量等于所有的行数,那么他是下发失败
                elevatorPersonVO.setSendState("2");
            } else {
                elevatorPersonVO.setSendState("3");
            }


            if (pointGroupName.charAt(pointGroupName.length() - 1) == ',') {
                pointGroupName = pointGroupName.substring(0, pointGroupName.length() - 1);
            }
            elevatorPersonVO.setPointGroupName(pointGroupName);


        } else {
            elevatorPersonVO.setPermissionDevs("0");
        }

        Date validStartTime = saasParkElevatorPerson.getValidStartTime();
        Date validEndTime = saasParkElevatorPerson.getValidEndTime();
        Date toDay = new Date();
        if (validStartTime == null) {
            elevatorPersonVO.setPermissionState("0");
        }
        if (validEndTime == null) {
            elevatorPersonVO.setPermissionState("0");
        }
        if (validStartTime != null && validEndTime != null) {
            if (toDay.before(validStartTime)) {
                elevatorPersonVO.setPermissionState("0");
            } else if (toDay.after(validEndTime)) {
                elevatorPersonVO.setPermissionState("2");
            } else {
                elevatorPersonVO.setPermissionState("1");
            }
        }

        return R.data(elevatorPersonVO);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean saveOrUpdateByParam(ElevatorPersonDTO elevatorPersonDTO) {
        SaasParkElevatorPerson saasParkElevatorPerson = new SaasParkElevatorPerson();
        BeanUtil.copyProperties(elevatorPersonDTO, saasParkElevatorPerson);
        saasParkElevatorPerson.setRelativeElevatorGroupJsonStr(JSON.toJSONString(elevatorPersonDTO.getPermission()));

        Long id = saasParkElevatorPerson.getId();
        if (Func.isNotEmpty(elevatorPersonDTO.getUserId()) && Func.isEmpty(id)) {
            List<SaasParkElevatorPerson> list = list(new LambdaQueryWrapper<SaasParkElevatorPerson>().eq(SaasParkElevatorPerson::getUserId, elevatorPersonDTO.getUserId()));
            if (Func.isNotEmpty(list) && list.size() > 0) {
                throw new RuntimeException("该人员已存在,不能重复新增");
            }
        }
        saasParkElevatorPerson.setIsDeleted(elevatorPersonDTO.getIsDeleted() == null ? 0 : elevatorPersonDTO.getIsDeleted());
        boolean result = saveOrUpdate(saasParkElevatorPerson);

        if (result) {
            //手动新增编辑触发下发
            downLoadPerson(elevatorPersonDTO, saasParkElevatorPerson);
        }

        return result;
    }


    public void downLoadPerson(ElevatorPersonDTO elevatorPersonDTO, SaasParkElevatorPerson saasParkElevatorPerson) {
        //把对应的要下发的权限更新到要下发的表saas_park_elevator_record_permission_records saas_park_elevator_relative_person_elevator
        List<PermissionDTO> listPermissionDTO = elevatorPersonDTO.getPermission();

        if (listPermissionDTO == null) {
            return;
        }

        //获取将要下发列表
        List<SaasParkElevatorRelativePersonElevator> listNewSaasParkElevatorRelativePersonElevator = getNewPermission(listPermissionDTO, saasParkElevatorPerson.getId());

        //获取原先的下发列表
        List<SaasParkElevatorRelativePersonElevator> listOldSaasParkElevatorRelativePersonElevator = iSaasParkElevatorRelativePersonElevatorService.getPermissionListByPersonId(saasParkElevatorPerson.getId());

        //旧的先删除
        if (listOldSaasParkElevatorRelativePersonElevator != null && listOldSaasParkElevatorRelativePersonElevator.size() > 0) {
            for (SaasParkElevatorRelativePersonElevator saasParkElevatorRelativePersonElevator : listOldSaasParkElevatorRelativePersonElevator) {

                //saas_park_elevator_record_permission_records表记录一条要下发删除的数据
                SaasParkElevatorRecordPermissionRecordsEntity saasParkElevatorRecordPermissionRecords = new SaasParkElevatorRecordPermissionRecordsEntity();
                saasParkElevatorRecordPermissionRecords.setIsDeleted(0);
                saasParkElevatorRecordPermissionRecords.setPersonId(saasParkElevatorRelativePersonElevator.getPersonId() + "");
                //电梯点id
                saasParkElevatorRecordPermissionRecords.setElevatorId(saasParkElevatorRelativePersonElevator.getElevatorId());
                saasParkElevatorRecordPermissionRecords.setUpdateTime(new Date());

                saasParkElevatorRecordPermissionRecords.setStatus(2);//要删除的
                saasParkElevatorRecordPermissionRecords.setCreateTime(new Date());
                if (StringUtil.isEmpty(saasParkElevatorRelativePersonElevator.getSendState())) {
                    saasParkElevatorRelativePersonElevator.setSendState("0");
                }
                saasParkElevatorRecordPermissionRecords.setDownloadStatus(Integer.parseInt(saasParkElevatorRelativePersonElevator.getSendState()));
                saasParkElevatorRecordPermissionRecords.setCanDownload(1);


                //找出对应的设备信息和人员信息

                Long elevatorId = saasParkElevatorRelativePersonElevator.getElevatorId();

                if (elevatorId == null) {
                    log.info("{}无关联设备", saasParkElevatorRelativePersonElevator.getPersonName());
                    continue;
                }
                SaasParkElevatorManageLocationEntity saasParkElevatorManageLocationEntity = iSaasParkElevatorManageLocationService.getById(elevatorId);

                if (saasParkElevatorManageLocationEntity != null) {
                    saasParkElevatorRecordPermissionRecords.setParkId(saasParkElevatorManageLocationEntity.getParkId());
                    saasParkElevatorManageLocationEntity.setBuildingId(saasParkElevatorManageLocationEntity.getBuildingId());
                    saasParkElevatorManageLocationEntity.setUnitId(saasParkElevatorManageLocationEntity.getUnitId());


                    iSaasParkElevatorRecordPermissionRecordsService.saveOrUpdate(saasParkElevatorRecordPermissionRecords);


                    //调用IOT删除旧的人员权限
                    boolean sendDelPersonResult = sendDelPerson(saasParkElevatorRelativePersonElevator, saasParkElevatorManageLocationEntity, saasParkElevatorPerson);


                    if (sendDelPersonResult) {

                        saasParkElevatorRelativePersonElevator.setSendState("1");
                        iSaasParkElevatorRelativePersonElevatorService.updateById(saasParkElevatorRelativePersonElevator);
                        //saas_park_elevator_relative_person_elevator表删除对应旧的数据
                        //iSaasParkElevatorRelativePersonElevatorService.removeById(saasParkElevatorRelativePersonElevator.getId());

                        //修改下发状态为已下发

                        saasParkElevatorRecordPermissionRecords.setDownloadStatus(1);
                        saasParkElevatorRecordPermissionRecords.setDownloadTime(new Date());
                        saasParkElevatorRecordPermissionRecords.setCanDownload(0);
                        saasParkElevatorRecordPermissionRecords.setRemark("下发删除成功");
                        iSaasParkElevatorRecordPermissionRecordsService.saveOrUpdate(saasParkElevatorRecordPermissionRecords);
                    } else {

                        saasParkElevatorRelativePersonElevator.setSendState("2");
                        iSaasParkElevatorRelativePersonElevatorService.updateById(saasParkElevatorRelativePersonElevator);

                        //修改下发状态为下发失败
                        saasParkElevatorRecordPermissionRecords.setDownloadStatus(2);
                        saasParkElevatorRecordPermissionRecords.setDownloadTime(new Date());
                        saasParkElevatorRecordPermissionRecords.setCanDownload(1);
                        saasParkElevatorRecordPermissionRecords.setRemark("下发删除失败");
                        iSaasParkElevatorRecordPermissionRecordsService.saveOrUpdate(saasParkElevatorRecordPermissionRecords);
                    }

                }
            }
        }

        //新的增加
        if (listNewSaasParkElevatorRelativePersonElevator != null && listNewSaasParkElevatorRelativePersonElevator.size() > 0) {

            for (SaasParkElevatorRelativePersonElevator saasParkElevatorRelativePersonElevator : listNewSaasParkElevatorRelativePersonElevator) {

                //过滤掉没选楼层的
                if (StringUtil.isBlank(saasParkElevatorRelativePersonElevator.getFloorIds())) {
                    continue;
                }

                //saas_park_elevator_relative_person_elevator表先新增新的数据
                saasParkElevatorRelativePersonElevator.setIsDeleted(0);
                iSaasParkElevatorRelativePersonElevatorService.saveOrUpdate(saasParkElevatorRelativePersonElevator);


                //saas_park_elevator_record_permission_records表记录一条要下发新增的数据
                SaasParkElevatorRecordPermissionRecordsEntity saasParkElevatorRecordPermissionRecords = new SaasParkElevatorRecordPermissionRecordsEntity();

                saasParkElevatorRecordPermissionRecords.setIsDeleted(0);
                saasParkElevatorRecordPermissionRecords.setPersonId(saasParkElevatorRelativePersonElevator.getPersonId() + "");
                //电梯点id
                saasParkElevatorRecordPermissionRecords.setElevatorId(saasParkElevatorRelativePersonElevator.getElevatorId());
                saasParkElevatorRecordPermissionRecords.setUpdateTime(new Date());
                saasParkElevatorRecordPermissionRecords.setStatus(0);//要下发
                saasParkElevatorRecordPermissionRecords.setCreateTime(new Date());
                if (StringUtil.isEmpty(saasParkElevatorRelativePersonElevator.getSendState())) {
                    saasParkElevatorRelativePersonElevator.setSendState("0");
                }
                saasParkElevatorRecordPermissionRecords.setDownloadStatus(Integer.parseInt(saasParkElevatorRelativePersonElevator.getSendState()));
                saasParkElevatorRecordPermissionRecords.setCanDownload(1);

                iSaasParkElevatorRecordPermissionRecordsService.saveOrUpdate(saasParkElevatorRecordPermissionRecords);


                //找出对应的设备信息和人员信息

                Long elevatorId = saasParkElevatorRelativePersonElevator.getElevatorId();

                if (elevatorId == null) {
                    log.info("{}无关联设备", saasParkElevatorRelativePersonElevator.getPersonName());
                    continue;
                }
                SaasParkElevatorManageLocationEntity saasParkElevatorManageLocationEntity = iSaasParkElevatorManageLocationService.getById(elevatorId);

                if (saasParkElevatorManageLocationEntity != null) {
                    saasParkElevatorRecordPermissionRecords.setParkId(saasParkElevatorManageLocationEntity.getParkId());
                    saasParkElevatorManageLocationEntity.setBuildingId(saasParkElevatorManageLocationEntity.getBuildingId());
                    saasParkElevatorManageLocationEntity.setUnitId(saasParkElevatorManageLocationEntity.getUnitId());

                    //调用IOT下发新的人员权限
                    boolean sendSavePersonResult = sendSavePerson(saasParkElevatorRelativePersonElevator, saasParkElevatorManageLocationEntity, saasParkElevatorPerson);

                    if (sendSavePersonResult) {

                        saasParkElevatorRelativePersonElevator.setSendState("1");
                        iSaasParkElevatorRelativePersonElevatorService.updateById(saasParkElevatorRelativePersonElevator);

                        //修改下发状态为已下发
                        saasParkElevatorRecordPermissionRecords.setDownloadStatus(1);
                        saasParkElevatorRecordPermissionRecords.setDownloadTime(new Date());
                        saasParkElevatorRecordPermissionRecords.setCanDownload(0);
                        saasParkElevatorRecordPermissionRecords.setRemark("下发成功");
                        iSaasParkElevatorRecordPermissionRecordsService.saveOrUpdate(saasParkElevatorRecordPermissionRecords);
                    } else {
                        saasParkElevatorRelativePersonElevator.setSendState("2");
                        iSaasParkElevatorRelativePersonElevatorService.updateById(saasParkElevatorRelativePersonElevator);


                        //修改下发状态为下发失败
                        saasParkElevatorRecordPermissionRecords.setDownloadStatus(2);
                        saasParkElevatorRecordPermissionRecords.setDownloadTime(new Date());
                        saasParkElevatorRecordPermissionRecords.setCanDownload(1);
                        saasParkElevatorRecordPermissionRecords.setRemark("下发失败");
                        iSaasParkElevatorRecordPermissionRecordsService.saveOrUpdate(saasParkElevatorRecordPermissionRecords);
                    }
                }
            }
        }
    }


    /**
     * 发送iot delPerson
     *
     * @param saasParkElevatorRelativePersonElevator
     * @param saasParkElevatorManageLocationEntity
     * @param saasParkElevatorPerson
     */
    private boolean sendDelPerson(SaasParkElevatorRelativePersonElevator saasParkElevatorRelativePersonElevator, SaasParkElevatorManageLocationEntity saasParkElevatorManageLocationEntity, SaasParkElevatorPerson saasParkElevatorPerson) {

        CallDeviceServiceDto callDeviceServiceDto = new CallDeviceServiceDto();
        callDeviceServiceDto.setIdentify(DELPERSON);
        callDeviceServiceDto.setProductKey(saasParkElevatorManageLocationEntity.getProductKey());
        callDeviceServiceDto.setDeviceName(saasParkElevatorManageLocationEntity.getDeviceDid());
        Map<String, Object> in = new HashMap<>();
        try {


            List<PersonInfoDTO> personInfosDTO = new ArrayList<>();
            PersonInfoDTO personInfoDTO = new PersonInfoDTO();
            personInfoDTO.setPersonID(saasParkElevatorRelativePersonElevator.getPersonId() + "");

            personInfosDTO.add(personInfoDTO);


            DeviceInfosDTO deviceInfosDTO = new DeviceInfosDTO();
            List<DeviceInfoDTO> listDeviceInfoDTO = new ArrayList<>();
            DeviceInfoDTO deviceInfoDTO = new DeviceInfoDTO();


            if (saasParkElevatorManageLocationEntity.getDeviceDid() == null) {
                throw new RuntimeException("删除业主对应的电梯未接入IOT");
            }
            deviceInfoDTO.setDeviceID(saasParkElevatorManageLocationEntity.getIotDeviceId());
            listDeviceInfoDTO.add(deviceInfoDTO);
            deviceInfosDTO.setDeviceInfosDTO(listDeviceInfoDTO);

            in.put("personInfos", personInfosDTO);
            //in.put("deviceInfos", deviceInfosDTO);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        callDeviceServiceDto.setParams(in);
        String json = JSONObject.toJSONString(callDeviceServiceDto);
        Map map = JSONObject.parseObject(json, Map.class);

        //调用接口
        log.info("====== 删除业主信息参数：{}", json);
        CallingDeviceServiceResponse response = ioTRemoteService.callServiceReturn(map);
        if (Func.isNotEmpty(response)) {
            boolean result = false;
            String resultJson = JSONObject.toJSONString(response);
            log.info("====== 删除业主信息返回数据：{}", resultJson);
            if (response.getCode().equals("200")) {
                result = true;
            }
            return result;
        }
        return false;

    }

    private List<SaasParkElevatorRelativePersonElevator> getNewPermission(List<PermissionDTO> listPermissionDTO, Long personId) {

        List<SaasParkElevatorRelativePersonElevator> saasParkElevatorRelativePersonElevatorList = new ArrayList<>();

        if (Func.isNotEmpty(listPermissionDTO)) {
            for (PermissionDTO permissionDTO : listPermissionDTO) {
                if (Func.isNotEmpty(permissionDTO.getChildren())) {
                    List<GroupDTO> groupDTOList = permissionDTO.getChildren();
                    for (GroupDTO groupDTO : groupDTOList) {
                        if (Func.isNotEmpty(groupDTO)) {
                            List<DeviceDTO> deviceDTOList = groupDTO.getChildren();
                            for (DeviceDTO deviceDTO : deviceDTOList) {
                                if (Func.isNotEmpty(deviceDTO)) {
                                    //if (deviceDTO.getIsSelected()) {


                                    SaasParkElevatorRelativePersonElevator saasParkElevatorRelativePersonElevator = new SaasParkElevatorRelativePersonElevator();
                                    Long deviceId = deviceDTO.getDeviceId();
                                    SaasParkElevatorManageLocationEntity deviceDetail = iSaasParkElevatorManageLocationService.getById(deviceId);

                                    saasParkElevatorRelativePersonElevator.setBuildingId(deviceDetail.getBuildingId());
                                    saasParkElevatorRelativePersonElevator.setElevatorName(deviceDetail.getDeviceName());
                                    saasParkElevatorRelativePersonElevator.setElevatorId(deviceDetail.getId());
                                    saasParkElevatorRelativePersonElevator.setSendState("0");
                                    saasParkElevatorRelativePersonElevator.setPersonId(personId);
                                    saasParkElevatorRelativePersonElevator.setUpdateTime(new Date());
                                    saasParkElevatorRelativePersonElevator.setIsDeleted(0);
                                    saasParkElevatorRelativePersonElevator.setSendState("0");


                                    List<FloorDTO> floorDTOList = deviceDTO.getChildren();
                                    if (floorDTOList != null) {
                                        String floor = "";
                                        for (int i = 0; i < floorDTOList.size(); i++) {
                                            if (Func.isNotEmpty(floorDTOList.get(i))) {
                                                if (floorDTOList.get(i).getIsSelected()) {
                                                    if (i == floorDTOList.size() - 1) {
                                                        floor += floorDTOList.get(i).getFloorId();
                                                    } else {
                                                        floor += floorDTOList.get(i).getFloorId() + ",";
                                                    }
                                                }
                                            }
                                        }


                                        saasParkElevatorRelativePersonElevator.setFloorIds(floor);
                                    }
                                    if (StringUtil.isNotBlank(saasParkElevatorRelativePersonElevator.getFloorIds())) {
                                        iSaasParkElevatorRelativePersonElevatorService.saveOrUpdate(saasParkElevatorRelativePersonElevator);
                                        saasParkElevatorRelativePersonElevatorList.add(saasParkElevatorRelativePersonElevator);
                                    }
                                    //}
                                }
                            }
                        }
                    }
                }
            }

            return saasParkElevatorRelativePersonElevatorList;
        } else {
            return null;
        }

    }


    @Override
    public ElevatorPersonVO getDetailById(Long id) {
        ElevatorPersonVO elevatorPersonVO = new ElevatorPersonVO();
        if (Func.isNotEmpty(id)) {
            SaasParkElevatorPerson saasParkElevatorPerson = getById(id);
            BeanUtil.copyProperties(saasParkElevatorPerson, elevatorPersonVO);
            elevatorPersonVO = detail(saasParkElevatorPerson.getId(), saasParkElevatorPerson).getData();
        }
        return elevatorPersonVO;
    }


    @Override
    public List<ElevatorPersonVO> getDetailsByIds(PersonIdsDTO PersonIds) {
        List<ElevatorPersonVO> listElevatorPersonVO = new ArrayList<>();
        if (PersonIds != null) {
            if (PersonIds.getPersonIds() != null) {
                for (int i = 0; i < PersonIds.getPersonIds().size(); i++) {

                    ElevatorPersonVO elevatorPersonVO = new ElevatorPersonVO();
                    if (Func.isNotEmpty(PersonIds.getPersonIds().get(i))) {
                        SaasParkElevatorPerson saasParkElevatorPerson = getById(PersonIds.getPersonIds().get(i));
                        if (saasParkElevatorPerson == null) {
                            continue;
                        }
                        BeanUtil.copyProperties(saasParkElevatorPerson, elevatorPersonVO);
                        elevatorPersonVO = detail(saasParkElevatorPerson.getId(), saasParkElevatorPerson).getData();
                        listElevatorPersonVO.add(elevatorPersonVO);
                    }
                }
            }
        }
        return listElevatorPersonVO;
    }


    public boolean sendUserPower(Long id) {

        SaasParkElevatorPerson saasParkElevatorPerson = getById(id);
        if (Func.isNotEmpty(saasParkElevatorPerson)) {

            String relativeElevatorGroupJsonStr = saasParkElevatorPerson.getRelativeElevatorGroupJsonStr();
            if (StringUtil.isEmpty(relativeElevatorGroupJsonStr)) {
                throw new ServiceException("该人员未设置人员权限");
            }
            if (relativeElevatorGroupJsonStr.equals("all")) {

            } else {
                List<PermissionDTO> permissionList = JSON.parseArray(relativeElevatorGroupJsonStr, PermissionDTO.class);
                //List<ElevatorDownLoadDTO> elevatorDownLoadDTOList = new ArrayList<>();
                List<SaasParkElevatorRelativePersonElevator> saasParkElevatorRelativePersonElevatorList = new ArrayList<>();

                if (Func.isNotEmpty(permissionList)) {
                    for (PermissionDTO permissionDTO : permissionList) {
                        if (Func.isNotEmpty(permissionDTO.getChildren())) {
                            List<GroupDTO> groupDTOList = permissionDTO.getChildren();
                            for (GroupDTO groupDTO : groupDTOList) {
                                if (Func.isNotEmpty(groupDTO)) {
                                    List<DeviceDTO> deviceDTOList = groupDTO.getChildren();
                                    for (DeviceDTO deviceDTO : deviceDTOList) {
                                        if (Func.isNotEmpty(deviceDTO)) {
                                            if (deviceDTO.getIsSelected()) {


                                                SaasParkElevatorRelativePersonElevator saasParkElevatorRelativePersonElevator = new SaasParkElevatorRelativePersonElevator();
                                                Long deviceId = deviceDTO.getDeviceId();
                                                SaasParkElevatorManageLocationEntity deviceDetail = iSaasParkElevatorManageLocationService.getById(deviceId);

                                                saasParkElevatorRelativePersonElevator.setBuildingId(deviceDetail.getBuildingId());
                                                saasParkElevatorRelativePersonElevator.setElevatorName(deviceDetail.getDeviceName());
                                                saasParkElevatorRelativePersonElevator.setSendState("0");
                                                saasParkElevatorRelativePersonElevator.setPersonId(id);
                                                saasParkElevatorRelativePersonElevator.setUpdateTime(new Date());

                                                iSaasParkElevatorRelativePersonElevatorService.saveOrUpdate(saasParkElevatorRelativePersonElevator);

                                                saasParkElevatorRelativePersonElevatorList.add(saasParkElevatorRelativePersonElevator);

                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

            }
            //调用iot下发(可重复发送,从数据库表SaasParkElevatorRelativePersonElevator取出这个人的进行发送)
            //sendElevator(saasParkElevatorRelativePersonElevatorList);


//            if (Func.isNotEmpty(elevatorDownLoadDTOList)) {
//                //多设备
//                elevatorDownLoadDTOList.forEach(item -> {
//                    //人员与设备关联表新增/更新
//
//
//                    //具体的协议下发给设备
//
//
//                    //下发结果保存到下发表
//
//                });
//            }


//            if (Func.isNotEmpty(permissionList)) {
//                //从permissionList获取需要下发的人员以及电梯信息,弄到集合里
//                List<Long> pointIds = itemList.stream().map(PlDoorUserPointSetItem::getDoorPointId).collect(Collectors.toList());
//                if (Func.isNotEmpty(pointIds)) {
//
//
//                    List<PlDoorPoint> pointList = plDoorPointService.list(new LambdaQueryWrapper<PlDoorPoint>().in(PlDoorPoint::getId, pointIds));
//                    if (Func.isNotEmpty(pointList)) {
//                        //多设备
//                        pointList.forEach(item -> {
//                            //组装参数
//                            List<PlDoorAddFaceDTO.Face> listFace = new ArrayList<>();
//                            //人员权限下发，调用iot接口注册人脸
//                            CallDeviceServiceDto callDeviceServiceDto = new CallDeviceServiceDto();
//                            callDeviceServiceDto.setIdentify(addFace);
//                            PlDoorAddFaceDTO addFace = new PlDoorAddFaceDTO();
//                            if (Func.isNotEmpty(item.getTerminalNumber())) {
//                                String terminalNumber = item.getTerminalNumber();
//                                if (Func.isNotEmpty(terminalNumber)) {
//                                    PlDoorAddFaceDTO.Face face = new PlDoorAddFaceDTO.Face();
//                                    face.setUserId(saasParkElevatorPerson.getUserId().toString());
//                                    face.setUserName(saasParkElevatorPerson.getUserName());
//                                    face.setFaceUrl(saasParkElevatorPerson.getUserFaceUrl());
//                                    if (Func.isNotEmpty(saasParkElevatorPerson.getUserFaceUrl())) {
//                                        try {
//                                            URL url = new URL(saasParkElevatorPerson.getUserFaceUrl());
//                                            String base64Encoded = Base64.getEncoder().encodeToString(url.toString().getBytes(StandardCharsets.UTF_8));
//                                            face.setFaceImgBase64(base64Encoded);
//                                        } catch (MalformedURLException e) {
//                                            throw new RuntimeException(e);
//                                        }
//                                    }
//                                    face.setTerminalNumber(terminalNumber);
//                                    //face.setRole(1);
//                                    //face.setCardNo(1);
//                                    //face.setPlanId(1);
//                                    if (Func.isNotEmpty(saasParkElevatorPerson.getValidStartTime())) {
//                                        face.setStartTime(DateUtil.format(saasParkElevatorPerson.getValidStartTime(), "yyyy-MM-dd HH:mm:ss"));
//                                    } else {
//                                        face.setStartTime(startTime);
//                                    }
//                                    if (Func.isNotEmpty(saasParkElevatorPerson.getValidEndTime())) {
//                                        face.setEndTime(DateUtil.format(saasParkElevatorPerson.getValidEndTime(), "yyyy-MM-dd HH:mm:ss"));
//                                    } else {
//                                        face.setEndTime(endTime);
//                                    }
//                                    listFace.add(face);
//                                }
//                            }
//                            callDeviceServiceDto.setProductKey(item.getProductKey());
//                            callDeviceServiceDto.setDeviceName(item.getDeviceDid());
//
//                            //下发人脸
//                            addFace.setListFace(listFace);
//                            sendFace(callDeviceServiceDto, saasParkElevatorPerson, addFace);
//
//                            //下发二维码
//                            //sendQRCode(pointSet, item);
//                        });
//                    }
//                }
//
//
//            }

        }
        return true;
    }


    /**
     * 发送iot savePerson
     *
     * @param saasParkElevatorRelativePersonElevator
     * @param point
     * @param saasParkElevatorPerson
     * @return
     */
    public boolean sendSavePerson(SaasParkElevatorRelativePersonElevator
                                          saasParkElevatorRelativePersonElevator, SaasParkElevatorManageLocationEntity point, SaasParkElevatorPerson
                                          saasParkElevatorPerson) {
        CallDeviceServiceDto callDeviceServiceDto = new CallDeviceServiceDto();
        callDeviceServiceDto.setIdentify(SAVEPERSON);
        callDeviceServiceDto.setProductKey(point.getProductKey());
        callDeviceServiceDto.setDeviceName(point.getDeviceDid());
        Map<String, Object> in = new HashMap<>();
        try {


            List<PersonInfoDTO> personInfosDTO = new ArrayList<>();
            PersonInfoDTO personInfoDTO = new PersonInfoDTO();
            personInfoDTO.setPersonID(saasParkElevatorRelativePersonElevator.getPersonId() + "");

            LambdaQueryWrapper<SaasParkElevatorPerson> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Func.isNotEmpty(saasParkElevatorRelativePersonElevator.getPersonId()), SaasParkElevatorPerson::getId, saasParkElevatorRelativePersonElevator.getPersonId());
            queryWrapper.last("limit 1");

            SaasParkElevatorPerson person = this.getOne(queryWrapper);
            if (person == null) {
                throw new RuntimeException("人员不存在");
            }

            personInfoDTO.setPersonType(0);//0普通用户  1管理员  2访客
            personInfoDTO.setPersonName(person.getUserName());
            personInfoDTO.setSex(person.getGender());
            personInfoDTO.setCardNO("");


            String floors = floors(saasParkElevatorRelativePersonElevator.getFloorIds(), point.getStartFloor(), point.getEndFloor());

            personInfoDTO.setFrontFloor(floors);

            personInfoDTO.setBackFloor("0000000000000000");

            personInfoDTO.setStartTime(DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss"));

            if (Func.isNotEmpty(saasParkElevatorRelativePersonElevator.getEffectTime())) {
                personInfoDTO.setEndTime(DateUtil.format(saasParkElevatorRelativePersonElevator.getEffectTime(), "yyyy-MM-dd HH:mm:ss"));
            } else {
                personInfoDTO.setEndTime(ENDTIME);
            }

            personInfoDTO.setPersonPhotoUrl(person.getUserFaceUrl());

            if (Func.isNotEmpty(person.getUserFaceUrl())) {
                // face.setFaceUrl(pointSet.getUserFaceUrl());
                try {
                    URL url = new URL(person.getUserFaceUrl());
                    // 压缩图片50k
                    //String base64Encoded = ImageUrlToBase64Util.imageUrlToBase64(url.toString());
                    String base64Encoded = PicToBase64Utils.imgChangeStrLimitSize50L(person.getUserFaceUrl());
                    personInfoDTO.setPersonPhotoUrl(base64Encoded);
                } catch (MalformedURLException e) {
                    throw new RuntimeException(e);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }


            personInfosDTO.add(personInfoDTO);
            in.put("personInfos", personInfosDTO);


            DeviceInfosDTO deviceInfosDTO = new DeviceInfosDTO();
            List<DeviceInfoDTO> listDeviceInfoDTO = new ArrayList<>();
            DeviceInfoDTO deviceInfoDTO = new DeviceInfoDTO();


            if (point.getDeviceDid() == null) {
                throw new RuntimeException("保存业主对应的电梯未接入IOT");
            }
            deviceInfoDTO.setDeviceID(point.getIotDeviceId());
            listDeviceInfoDTO.add(deviceInfoDTO);
            deviceInfosDTO.setDeviceInfosDTO(listDeviceInfoDTO);


            listDeviceInfoDTO.add(deviceInfoDTO);
            deviceInfosDTO.setDeviceInfosDTO(listDeviceInfoDTO);
            // in.put("deviceInfos", deviceInfosDTO);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        callDeviceServiceDto.setParams(in);
        String json = JSONObject.toJSONString(callDeviceServiceDto);
        Map map = JSONObject.parseObject(json, Map.class);

        //调用接口
        log.info("====== 保存业主信息参数：{}", json);
        CallingDeviceServiceResponse response = ioTRemoteService.callServiceReturn(map);
        if (Func.isNotEmpty(response)) {
            boolean result = false;
            String resultJson = JSONObject.toJSONString(response);
            log.info("====== 保存业主业主信息返回数据：{}", resultJson);
            if (response.getCode().equals("200")) {
                result = true;
            }
            return result;
        }
        return false;
    }


    private String floors(String strFloors, Integer startFloor, Integer endFloor) {

        String[] strFloorsList = strFloors.split(",");
        List<String> list = new ArrayList<>(Arrays.asList(strFloorsList));
        String softFloor = "";
        for (String floor : list) {
            softFloor += getSoftFloor(Integer.parseInt(floor), startFloor, endFloor) + ",";
        }
        softFloor = softFloor.substring(0, softFloor.length() - 1);
        return softFloor;

    }

    private Integer getSoftFloor(Integer nowFloor, Integer startFloor, Integer endFloor) {

        Integer softFloor = 1;
        if (startFloor == null) {
            startFloor = 1;
        }
        if (endFloor == null) {
            endFloor = 100;
        }

        if (startFloor < 0) {
            //存在地下室
            softFloor = nowFloor - 1 + startFloor + 1;
        }
        if (startFloor > 0) {
            //存在地下室
            softFloor = nowFloor - 1 + startFloor;
        }

        return softFloor;

    }


}
