package com.dcsoft.system.ladder.service.impl;

import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.http.HttpException;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dcsoft.common.core.constant.Constants;
import com.dcsoft.common.core.enums.exception.CommonExceptionEnum;
import com.dcsoft.common.core.exception.ServiceException;
import com.dcsoft.system.domain.SysBranch;
import com.dcsoft.system.domain.SysEquipment;
import com.dcsoft.system.domain.SysPeople;
import com.dcsoft.system.ladder.domain.*;
import com.dcsoft.system.ladder.mapper.TEmpowerManageMapper;
import com.dcsoft.system.ladder.mapper.TLadderConfigMapper;
import com.dcsoft.system.ladder.mapper.TLadderRuleMapper;
import com.dcsoft.system.ladder.service.ITEmpowerManageService;
import com.dcsoft.system.mapper.SysBranchMapper;
import com.dcsoft.system.utils.FloorUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class TEmpowerManageServiceImpl implements ITEmpowerManageService {

    @Resource
    private TEmpowerManageMapper empowerManageMapper;

    @Resource
    private TLadderRuleMapper tLadderRuleMapper;

    @Resource
    private TLadderConfigMapper tLadderConfigMapper;

    @Resource
    private SysBranchMapper sysBranchMapper;

    @Value("${ladder.url}")
    private String url;

    @Value("${ladder.pass}")
    private String pass;

    /**
     * 卡权限创建接口
     */
    public static final String create = "/cardinfo/create";

    /**
     * 卡权限删除接口
     */
    public static final String delete = "/cardinfo/delete";

    /**
     * 新增梯控授权管理
     */
    @Override
    @Transactional
    public void saveEmpowerManage(EmpowerManageVo empowerManageVo) {
        // 人员授权
        if(Constants.ONE.equals(empowerManageVo.getType())) {
            if(StringUtils.isEmpty(empowerManageVo.getPeopleIds())) {
                throw new ServiceException("人员id不能为空");
            }
            List<String> list = Arrays.asList(empowerManageVo.getPeopleIds().split(","));
            EmpowerManageVo manage = empowerManageMapper.queryEmpowerManage(empowerManageVo, list);
            if(manage != null) {
                throw new ServiceException(manage.getPeopleName() + "已授权" + manage.getRuleName() + "规则");
            }
            TLadderRule tLadderRule = tLadderRuleMapper.selectTLadderRuleById(empowerManageVo.getLadderRuleId());

            if(StringUtils.isEmpty(tLadderRule.getStoreyId()) && StringUtils.isEmpty(tLadderRule.getPointId())) {
                throw new ServiceException("请绑定设备");
            }

            List<String> pointIdList = Arrays.asList(tLadderRule.getSpaceId().split(","));

            // 查询设备信息
            List<SysEquipment> equipmentsList = empowerManageMapper.queryDeviceEmpower(pointIdList);

            // 获取下发楼层
            Map<String, String> map = floorEncryption(empowerManageVo);

            List<EmpowerManageVo> manageVoList = new ArrayList<>();
            for (String s : list) {
                EmpowerManageVo manageVo = new EmpowerManageVo();
                manageVo.setPeopleId(s);
                manageVo.setType(empowerManageVo.getType());
                manageVo.setLadderRuleId(empowerManageVo.getLadderRuleId());
                manageVoList.add(manageVo);
            }
            // 保存授权管理数据
            empowerManageMapper.saveEmpowerManage(manageVoList);
            // 保存授权记录数据
            saveEmpowerRecord(list, Constants.ONE, empowerManageVo.getLadderRuleId(), map, equipmentsList, tLadderRule);
        }

        // 部门授权
        if(Constants.TWO.equals(empowerManageVo.getType())) {
            if(StringUtils.isEmpty(empowerManageVo.getBranchIds())) {
                throw new ServiceException("部门id不能为空");
            }
            List<String> list = Arrays.asList(empowerManageVo.getBranchIds().split(","));
            EmpowerManageVo manage = empowerManageMapper.queryEmpowerManage(empowerManageVo, list);
            if(manage != null) {
                throw new ServiceException(manage.getBranchName() + "已授权" + manage.getRuleName() + "规则");
            }

            // 获取下发楼层
            Map<String, String> map = floorEncryption(empowerManageVo);

            TLadderRule tLadderRule = tLadderRuleMapper.selectTLadderRuleById(empowerManageVo.getLadderRuleId());

            if(StringUtils.isEmpty(tLadderRule.getStoreyId()) && StringUtils.isEmpty(tLadderRule.getPointId())) {
                throw new ServiceException("请绑定设备");
            }
            List<String> pointIdList = Arrays.asList(tLadderRule.getSpaceId().split(","));

            // 查询设备信息
            List<SysEquipment> equipmentsList = empowerManageMapper.queryDeviceEmpower(pointIdList);


            List<EmpowerManageVo> manageVoList = new ArrayList<>();
            for (String s : list) {
                // 保存授权记录
                EmpowerManageVo manageVo = new EmpowerManageVo();
                manageVo.setBranchId(s);
                manageVo.setType(empowerManageVo.getType());
                manageVo.setLadderRuleId(empowerManageVo.getLadderRuleId());
                manageVoList.add(manageVo);
            }
            empowerManageMapper.saveEmpowerManage(manageVoList);
            // 保存授权记录数据
            ThreadUtil.execAsync(() -> {
                try {
                    saveEmpowerRecord(list, Constants.TWO, empowerManageVo.getLadderRuleId(), map, equipmentsList, tLadderRule);
                    log.info("保存部门授权记录数据成功");
                } catch (HttpException e) {
                    log.error("保存部门授权记录数据失败", e);
                    throw new RuntimeException(e);
                }
            });

        }
    }

    /**
     * 保存授权记录数据
     */
    private void saveEmpowerRecord(List<String> list, String type, String ladderRuleId, Map<String, String> floor, List<SysEquipment> equipmentsList, TLadderRule tLadderRule) {
        List<PeopleInfoVo> peopleInfoList = new ArrayList<>();
        List<EmpowerManageVo> empowerRecordList = new ArrayList<>();
        List<PeopleInfoVo> peopleInfoVos = empowerManageMapper.queryPeopleInfo(list, type);
        for (PeopleInfoVo peopleInfoVo : peopleInfoVos) {
            // 下发梯控设备
            for (SysEquipment sysEquipment : equipmentsList) {
                try {
                    String s = floor.get(sysEquipment.getSequence());
                    if(StringUtils.isEmpty(s)) {
                        continue;
                    }
                    deviceDistribute(sysEquipment, peopleInfoVo, s, tLadderRule);
                } catch (Exception e) {
                    log.error("梯控卡权限创建接口异常（设备ip" + sysEquipment.getIp() + "）" + e);
                    PeopleInfoVo infoVo = new PeopleInfoVo();
                    infoVo.setPeopleId(peopleInfoVo.getPeopleId());
                    infoVo.setIp(sysEquipment.getIp());
                    peopleInfoList.add(infoVo);
                    continue;
                }
                log.info("梯控卡权限创建接口（设备ip:" + sysEquipment.getIp() + "）");
                EmpowerManageVo manageVo = new EmpowerManageVo();
                manageVo.setPeopleId(peopleInfoVo.getPeopleId());
                manageVo.setPeopleName(peopleInfoVo.getPeopleName());
                manageVo.setInfoDown(Constants.ZERO);
                manageVo.setStatus(Constants.ZERO);
                manageVo.setLadderRuleId(ladderRuleId);
                manageVo.setSerialNumber(sysEquipment.getSequence());
                empowerRecordList.add(manageVo);
            }
        }

        // 更新设备异常信息
        updateDeviceException(peopleInfoList);

        // 保存授权记录数据
        saveEmpowerRecord(empowerRecordList, peopleInfoVos, equipmentsList);
    }

    /**
     * 更新梯控设备异常信息
     * @param peopleInfoList
     */
    private void updateDeviceException(List<PeopleInfoVo> peopleInfoList) {
        if(!CollectionUtils.isEmpty(peopleInfoList)) {
            List<PeopleInfoVo> peopleInfoVos = new ArrayList<>();
            Map<String, List<PeopleInfoVo>> collect = peopleInfoList.stream().collect(Collectors.groupingBy(PeopleInfoVo::getPeopleId));
            for (String s : collect.keySet()) {
                List<PeopleInfoVo> peopleInfoVoList = collect.get(s);
                PeopleInfoVo infoVo = new PeopleInfoVo();
                infoVo.setPeopleId(s);
                String ips = peopleInfoVoList.stream().map(PeopleInfoVo::getIp).collect(Collectors.joining(","));
                infoVo.setRemark("梯控设备失败，设备ip为：" + ips + "网络异常");
                peopleInfoVos.add(infoVo);
            }
            empowerManageMapper.updateDeviceException(peopleInfoVos);
        }
    }

    /**
     * 保存授权记录数据
     */
    private void saveEmpowerRecord(List<EmpowerManageVo> empowerRecordList, List<PeopleInfoVo> peopleInfoVos, List<SysEquipment> equipmentsList) {
        if(!CollectionUtils.isEmpty(empowerRecordList)) {
            List<String> peopleIds = peopleInfoVos.stream().map(PeopleInfoVo::getPeopleId).collect(Collectors.toList());
            List<String> sequences = equipmentsList.stream().map(SysEquipment::getSequence).collect(Collectors.toList());
            List<EmpowerRecordVo> equipments = empowerManageMapper.selectEmpowerRecordInfo(peopleIds, sequences);
            if(!CollectionUtils.isEmpty(equipments)) {
                empowerRecordList.removeIf(c -> equipments.stream().anyMatch(n -> n.getPeopleId().equals(c.getPeopleId()) && n.getSerialNumber().equals(c.getSerialNumber())));
            }
            // 保存授权记录数据
            if (!CollectionUtils.isEmpty(empowerRecordList)) {
                empowerManageMapper.saveEmpowerRecord(empowerRecordList);
            }
        }
    }

    /**
     * 卡权限创建接口
     */
    private void deviceDistribute(SysEquipment sysEquipment, PeopleInfoVo peopleInfoVo, String floor, TLadderRule tLadderRule) throws InterruptedException {
        if(StringUtils.isNotEmpty(peopleInfoVo.getDoorNo())) {
            Thread.sleep(3000);
            SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Map<String, Object> map = new HashMap<>();
            CardInfoVo infoVo = new CardInfoVo();
            infoVo.setIdcardnum(peopleInfoVo.getDoorNo());
            infoVo.setFloortype(Constants.ZERO);
            infoVo.setFloor(floor);
            infoVo.setCalltype(Constants.ONE);
            infoVo.setCustomertype(Constants.FIVE);
            infoVo.setStarttime(dateformat.format(tLadderRule.getStartTime()));
            infoVo.setEndtime(dateformat.format(tLadderRule.getEndTime()));
            infoVo.setStartdaytime(tLadderRule.getAdmittanceStart());
            infoVo.setEnddaytime(tLadderRule.getAdmittanceEnd());
            infoVo.setWeek(Constants.WEEK);
            map.put("cardinfo", infoVo);
            map.put("pass", sysEquipment.getPassword());
            String body = HttpUtil.createPost("http://" + sysEquipment.getIp() + ":8090" + create).timeout(10000).body(JSON.toJSONString(map)).execute().body();
            JSONObject object = JSONObject.parseObject(body);
            if(!Constants.CODE.equals(object.get("msg"))) {
                throw new ServiceException(CommonExceptionEnum.REQUEST_ERROR.getCode(), "梯控卡权限创建接口" +
                        CommonExceptionEnum.REQUEST_ERROR.getMessage() + "梯控卡权限创建接口异常码" + object.get("msg").toString());
            }
        }
    }



    /**
     * 楼层转换
     * @param empowerManageVo
     * @return
     */
    private Map<String, String> floorEncryption(EmpowerManageVo empowerManageVo) {
        TLadderConfig ladderConfig = new TLadderConfig();
        ladderConfig.setId(empowerManageVo.getLadderRuleId());
        TLadderRule tLadderRule = tLadderRuleMapper.selectTLadderRuleById(empowerManageVo.getLadderRuleId());
        Map<String, String> map = new HashMap<>();
        List<StoreyInfoVo> storeyInfoVos = tLadderConfigMapper.queryFloorInfo(Arrays.asList(tLadderRule.getPointId().split(",")));
        if(!CollectionUtils.isEmpty(storeyInfoVos)) {
            Map<String, List<StoreyInfoVo>> collect = storeyInfoVos.stream().collect(Collectors.groupingBy(StoreyInfoVo::getSerialNumber));
            for (String s : collect.keySet()) {
                String floor = FloorUtil.floorConvert(collect.get(s).stream().map(StoreyInfoVo::getStorey).collect(Collectors.toList()));
                map.put(s, floor);
            }
        }
        return map;
    }

    /**
     * 查询梯控授权管理列表
     */
    @Override
    public List<EmpowerManageVo> queryEmpowerManagePage(EmpowerManageVo empowerManageVo) {
        return empowerManageMapper.queryEmpowerManagePage(empowerManageVo);
    }

    /**
     * 查询梯控授权管理列表
     */
    @Override
    public void deleteEmpowerManage(EmpowerManageVo empowerManageVo) {
        List<String> collect = new ArrayList<>();
        if(Constants.ONE.equals(empowerManageVo.getType())) {
            collect = Arrays.asList(empowerManageVo.getPeopleId().split(","));
        }

        if(Constants.TWO.equals(empowerManageVo.getType())) {
            List<PeopleInfoVo> peopleInfoVos =  empowerManageMapper.queryPeopleInfo(Arrays.asList(empowerManageVo.getBranchId().split(",")), Constants.TWO);
            collect = peopleInfoVos.stream().map(PeopleInfoVo::getPeopleId).collect(Collectors.toList());
        }

//        empowerManageMapper.deleteEmpowerRecord(collect, empowerManageVo.getLadderRuleId());
        empowerManageMapper.deleteEmpowerManage(empowerManageVo);

    }

    /**
     * 查询梯控授权记录列表
     */
    @Override
    public List<EmpowerRecordVo> queryEmpowerRecordPage(EmpowerManageVo empowerManageVo) {
        return empowerManageMapper.queryEmpowerRecordPage(empowerManageVo);
    }

    /**
     * 修改禁用或启用状态
     */
    @Override
    public void updateLadderState(EmpowerManageVo empowerManageVo) throws IOException {
        List<String> list = Arrays.asList(empowerManageVo.getId().split(","));

        // 修改授权记录状态
        empowerManageMapper.updateEmpowerRecord(list, empowerManageVo.getStatus());
    }

    /**
     * 查询人员是否下发设备中
     */
    @Override
    public EmpowerManageVo queryEmpowerRecordInfo(SysPeople people) {
        return empowerManageMapper.queryEmpowerRecordInfo(people);
    }

    /**
     * 查询梯控规则
     */
    @Override
    public TLadderRule queryLadderRuleInfo(String ladderRuleId) {
        return empowerManageMapper.queryLadderRuleInfo(ladderRuleId);
    }

    /**
     * 查询楼层信息
     */
    @Override
    public List<StoreyInfoVo> queryStoreyInfo(List<String> list) {
        return tLadderConfigMapper.queryFloorInfo(list);
    }

    /**
     * 删除授权记录
     */
    @Override
    public void deleteLadderState(EmpowerManageVo empowerManageVo) {
        List<PeopleInfoVo> peopleInfoList = new ArrayList<>();
        List<String> ids = new ArrayList<>();
        List<String> list = Arrays.asList(empowerManageVo.getId().split(","));
        List<SysEquipment> equipments = empowerManageMapper.queryEmpower(list);
        Map<String, List<SysEquipment>> collectMap = equipments.stream().collect(Collectors.groupingBy(SysEquipment::getSequence));
        for (String s : collectMap.keySet()) {
            List<SysEquipment> equipments1 = collectMap.get(s);
            for (SysEquipment sysEquipment : equipments1) {
                try {
                    deleteLadder(sysEquipment);
                } catch (Exception e) {
                    log.error("梯控删除卡号接口异常:" + e);
                    PeopleInfoVo infoVo = new PeopleInfoVo();
                    infoVo.setIp(sysEquipment.getIp());
                    infoVo.setPeopleId(sysEquipment.getPeopleId());
                    infoVo.setDoorNo(sysEquipment.getDoorNo());
                    peopleInfoList.add(infoVo);
                    continue;
                }
                ids.add(sysEquipment.getEmpowerRecordId());
            }
        }
        if(!CollectionUtils.isEmpty(ids)) {
            empowerManageMapper.deleteLadderState(ids);
        }

        // 更新梯控设备异常信息
        updateDeviceException(peopleInfoList);
    }

    private void deleteLadder(SysEquipment sysEquipment) throws InterruptedException {
        Thread.sleep(3000);
        log.info("梯控删除:" + sysEquipment);
        log.info("梯控删除地址:" + "http://" + sysEquipment.getIp() + ":8090" +  delete);
        Map<String, Object> map = new HashMap<>();
        map.put("idcardnum", sysEquipment.getDoorNo());
        map.put("pass", sysEquipment.getPassword());
        String body = HttpUtil.createPost("http://" + sysEquipment.getIp() + ":8090" +  delete).timeout(5000).body(JSON.toJSONString(map)).execute().body();
        log.info("梯控删除卡号接口返回:" + body);
        JSONObject object = JSONObject.parseObject(body);
        if(!Constants.CODE.equals(object.get("msg"))) {
            log.error("梯控删除卡号接口异常码:" + object.get("msg").toString());
            throw new ServiceException(CommonExceptionEnum.REQUEST_ERROR.getCode(), "梯控删除卡号接口" + CommonExceptionEnum.REQUEST_ERROR.getMessage());
        }
    }

    /**
     * 保存梯口识别记录
     */
    @Override
    public void saveLadderRecord(LadderRecordVo recordVo) {
        PeopleInfoVo people = empowerManageMapper.queryPeople(recordVo);
        if(people != null && StringUtils.isNotEmpty(people.getPeopleName())) {
            recordVo.setName(people.getPeopleName());
        }
        empowerManageMapper.saveLadderRecord(recordVo);
    }

    /**
     * 查询识别记录
     */
    @Override
    public List<LadderRecordVo> queryLadderRecord(LadderRecordVo recordVo) {
        return empowerManageMapper.queryLadderRecord(recordVo);
    }

    /**
     * 删除识别记录saveEmpowerManage
     */
    @Override
    public void deleteLadderRecord(LadderRecordVo recordVo) {
        empowerManageMapper.deleteLadderRecord(Arrays.asList(recordVo.getId().split(",")));
    }

    /**
     * 保存梯控设备授权
     * @return
     */
    @Override
    public void saveLadderDevice(SysPeople sysPeople) {
        System.out.println("sysPeople------------" + sysPeople);
        SysBranch sysBranch = sysBranchMapper.selectSysBranchById(sysPeople.getBranchId());
        if(StringUtils.isNotEmpty(sysBranch.getLadderRuleId())) {
            TLadderRule tLadderRule = tLadderRuleMapper.selectTLadderRuleById(sysBranch.getLadderRuleId());
            if(StringUtils.isEmpty(tLadderRule.getStoreyId()) && StringUtils.isEmpty(tLadderRule.getPointId())) {
                throw new ServiceException("梯控规则未绑定设备!");
            }
            List<String> pointIdList = Arrays.asList(tLadderRule.getPointId().split(","));

            // 查询设备信息
            List<SysEquipment> equipmentsList = empowerManageMapper.queryDeviceEmpower(pointIdList);

            // 获取下发楼层
            EmpowerManageVo manage = new EmpowerManageVo();
            manage.setLadderRuleId(sysBranch.getLadderRuleId());
            Map<String, String> map = floorEncryption(manage);

            EmpowerManageVo manageVo = new EmpowerManageVo();
            List<EmpowerManageVo> manageVoList = new ArrayList<>();
            manageVo.setPeopleId(sysPeople.getId().toString());
            manageVo.setType(Constants.ONE);
            manageVo.setLadderRuleId(sysBranch.getLadderRuleId());
            manageVoList.add(manageVo);
            // 保存授权管理数据
            empowerManageMapper.saveEmpowerManage(manageVoList);

            // 保存授权记录数据
            List<String> list = new ArrayList<>();
            list.add(sysPeople.getId().toString());
            saveEmpowerRecord(list, Constants.ONE, sysBranch.getLadderRuleId(), map, equipmentsList, tLadderRule);

        }
    }

    /**
     * 查询梯控数量（今天，昨天）
     * @param recordVo
     * @return
     */
    @Override
    public List<LadderRecordVo> queryLadderRecordCount(LadderRecordVo recordVo) {
        return empowerManageMapper.queryLadderRecordCount(recordVo);
    }


}
