package com.mvc.service.taizhang;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.mvc.dao.CustomizeGroupMapper;
import com.mvc.entity.CustomizeGroup;
import com.mvc.entity.CustomizeGroupExample;
import com.mvc.model.*;
import com.mvc.othermodel.GroupAndStationTree;
import com.mvc.service.app.AppDevgroupDetailService;
import com.mvc.service.app.AppDeviceGroupService;
import com.mvc.utils.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
public class CustomizeGroupService {
    @Resource
    private CustomizeGroupMapper customizeGroupMapper;

    @Resource
    private StationAccService stationAccService;

    @Resource
    private DeviceAccService deviceAccService;

    @Resource
    private AppDeviceGroupService appDeviceGroupService;

    @Resource
    private AppDevgroupDetailService appDevgroupDetailService;

    public Map<String, Object> findAllCustomizeGroup(Integer page, Integer rows) {
        Map<String, Object> resMap = new HashMap<>();
        Page<Object> pageObject = PageHelper.startPage(page, rows);
        List<CustomizeGroup> CustomizeGroups = customizeGroupMapper.selectByExample(null);
        List<CustomizeGroupModel> resList = new ArrayList<>();
        for (CustomizeGroup CustomizeGroup : CustomizeGroups) {
            CustomizeGroupModel model = new CustomizeGroupModel();
            BeanUtils.copyProperties(CustomizeGroup, model);
            resList.add(model);
        }
        resMap.put("total", pageObject.getTotal());
        resMap.put("list", resList);
        return resMap;
    }

    /**
     * 获取自定义分组树
     *
     * @param unitCode
     * @param userId
     * @return
     */
    public List<GroupAndStationTree> findCustomizeGroupTree(String unitCode, String userId) {
        unitCode = StringUtils.isEmpty(unitCode) ? "0" : unitCode;            //内部用户为0
        CustomizeGroupExample example = new CustomizeGroupExample();
        CustomizeGroupExample.Criteria criteria = example.createCriteria();
        criteria.andUnitCodeEqualTo(unitCode);
        example.setOrderByClause("GROUP_NAME ASC");
        List<CustomizeGroup> customizeGroups = customizeGroupMapper.selectByExample(example);
        if (customizeGroups == null || customizeGroups.size() == 0) return null;

        Map<String, List<CustomizeGroup>> map = customizeGroups.stream().filter(item -> StringUtils.isNotBlank(item.getCreateUserId()))
                .collect(Collectors.groupingBy(t -> t.getCreateUserId()));

        List<GroupTempModel> tempModels = new ArrayList<>();
        //使登陆人的分组在前
        if (map.containsKey(userId)) {
            GroupTempModel tempModel = new GroupTempModel(userId, map.get(userId));
            tempModels.add(tempModel);
        }

        for (String key : map.keySet()) {
            if (key.equals(userId)) {
                continue;
            }
            GroupTempModel tempModel = new GroupTempModel(key, map.get(key));
            tempModels.add(tempModel);
        }

        List<GroupAndStationTree> groupAndStationTrees = new ArrayList<>();

        for (GroupTempModel tempModel : tempModels) {

            boolean isFirst = true;
            List<CustomizeGroup> list = map.get(tempModel.getUserId());

            for (CustomizeGroup group : list) {
                //顶级(姓名)
                if (isFirst) {
                    GroupAndStationTree top = new GroupAndStationTree();
                    top.setId(group.getCreateUserId());
                    top.setLabel(group.getCreateUserName());
                    top.setCode(group.getCreateUserId());
                    top.setType("-1");//由于姓名这一级是后来补的,为了不影响前端,采用了-1 2024-03-06 guozhao
                    groupAndStationTrees.add(top);
                    isFirst = false;
                }

                //二级
                CustomizeGroupModel model = new CustomizeGroupModel();
                BeanUtils.copyProperties(group, model);

                int num = StringUtils.isEmpty(group.getStationCodes()) ? 0 : group.getStationCodes().split(",").length;

                String name = group.getGroupName() + "_[" + num + "]";

                if (!group.getCreateUserId().equals(userId) && !group.getPublicFlag().equals("1")) {
                    //非本人且未公开,跳过
                    continue;
                }
                GroupAndStationTree tree = new GroupAndStationTree();
                tree.setId(group.getGroupId());
                tree.setType("0");
                tree.setLabel(name);
                tree.setCode(group.getGroupId());
                tree.setData(model);
                tree.setParentcode(group.getCreateUserId());

                groupAndStationTrees.add(tree);
                if (StringUtils.isEmpty(group.getStationCodes())) continue;

                String[] arr = group.getStationCodes().split(",");

                List<String> stationCodes = Arrays.stream(arr).sorted().collect(Collectors.toList());
                List<GroupAndStationTree> children = new ArrayList<>();

                if (StringUtils.isEmpty(group.getCodeType()) || group.getCodeType().equals("0")) {//遥测站编码分组
                    Map<String, StationAccModel> stationAccModelMap = stationAccService.findStationAccMapByStationCodes(group.getStationCodes());
                    //三级
                    for (String stationCode : stationCodes) {
                        if (StringUtils.isEmpty(stationCode)) continue;
                        GroupAndStationTree accTree = new GroupAndStationTree();
                        accTree.setType("1");
                        accTree.setParentname(group.getGroupName());
                        accTree.setParentcode(group.getGroupId());
                        accTree.setId(stationCode);
                        accTree.setLabel(stationCode);
                        accTree.setCode(stationCode);

                        //有遥测站加站,没有站显示遥测站编码
                        if (stationAccModelMap.containsKey(stationCode)) {
                            accTree.setLabel(stationAccModelMap.get(stationCode).getStationName());
                            accTree.setData(stationAccModelMap.get(stationCode));
                            accTree.setDeviceType(StringUtils.isEmpty(stationAccModelMap.get(stationCode).getDeviceType()) ? "1" : stationAccModelMap.get(stationCode).getDeviceType());
                        }
                        children.add(accTree);
                    }
                } else {//Sn分组
                    Map<String, DeviceAccModel> deviceAccModelMap = deviceAccService.findDeviceAccMapByDeviceSns(group.getStationCodes());
                    //三级
                    for (String deviceSn : stationCodes) {
                        if (StringUtils.isEmpty(deviceSn)) continue;
                        GroupAndStationTree accTree = new GroupAndStationTree();
                        accTree.setType("1");
                        accTree.setParentname(group.getGroupName());
                        accTree.setParentcode(group.getGroupId());
                        accTree.setId(deviceSn);
                        accTree.setLabel(deviceSn);
                        accTree.setCode(deviceSn);

                        //设备台账中有名称则显示设备台账中的名称 2024-11-04 guozhao
                        if (deviceAccModelMap.containsKey(deviceSn)) {
                            accTree.setLabel(StringUtils.isNotEmpty(deviceAccModelMap.get(deviceSn).getDeviceName()) ? deviceAccModelMap.get(deviceSn).getDeviceName() : deviceSn);
                            accTree.setData(deviceAccModelMap.get(deviceSn));
                            accTree.setDeviceType(StringUtils.isEmpty(deviceAccModelMap.get(deviceSn).getDeviceType()) ? "1" : deviceAccModelMap.get(deviceSn).getDeviceType());
                        }
                        children.add(accTree);
                    }
                }

                if (children.size() > 0) {
                    //children = children.stream().sorted(Comparator.comparing(GroupAndStationTree::getCode, Comparator.nullsFirst(String::compareTo))).collect(Collectors.toList());
                    groupAndStationTrees.addAll(children);
                }
            }
        }

        return groupAndStationTrees;
    }

    public Map<String, Object> saveCustomizeGroup(CustomizeGroupModel model) {
        Map<String, Object> resMap = new HashMap<>();
        if (StringUtils.isEmpty(model.getPublicFlag())) {
            model.setPublicFlag("0");
        }
        model.setGroupId(StringUtil.getUuid());
        model.setCreateTime(new Date());
        model.setStartTimeFlag(model.getStartTime() == null ? "0" : "1");
        model.setEndTimeFlag(model.getEndTime() == null ? "0" : "1");
        if (model.getUserType().equals("0")) {
            model.setUnitCode("0");             //内部用户的单位代码用0表示
        }

        if (existCustomizeGroupByName(model.getGroupName(), model.getUnitCode(), model.getCreateUserId(), model.getPublicFlag()) != null) {
            resMap.put("error", "分组名称已经存在");
            return resMap;
        }

        CustomizeGroup CustomizeGroup = new CustomizeGroup();
        BeanUtils.copyProperties(model, CustomizeGroup);
        int insert = customizeGroupMapper.insert(CustomizeGroup);
        resMap.put("res", model);
        return resMap;
    }

    public CustomizeGroup existCustomizeGroupByName(String groupName, String unitCode, String userId, String publicFlag) {
        CustomizeGroupExample example = new CustomizeGroupExample();
        CustomizeGroupExample.Criteria criteria = example.createCriteria();
        if (publicFlag.equals("1")) {
            criteria.andUnitCodeEqualTo(unitCode);
        } else {
            criteria.andCreateUserIdEqualTo(userId);
        }
        criteria.andGroupNameEqualTo(groupName);
        List<CustomizeGroup> customizeGroups = customizeGroupMapper.selectByExample(example);

        return customizeGroups == null || customizeGroups.size() == 0 ? null : customizeGroups.get(0);
    }

    public CustomizeGroupModel updateCustomizeGroup(CustomizeGroupModel model) {
        model.setStationCodes(checkStationCodes(model.getStationCodes(), model.getCodeType()));
        CustomizeGroup customizeGroup = customizeGroupMapper.selectByPrimaryKey(model.getUid());
        if (customizeGroup.getStartTime() != null && model.getStartTime() == null) {//清掉了开始时间
            model.setStartTimeFlag("0");
        } else if (customizeGroup.getStartTime() == null && model.getStartTime() != null) {//加上了结束时间
            model.setStartTimeFlag("1");
        }

        if (customizeGroup.getEndTime() != null && model.getEndTime() == null) {//清掉了结束时间
            model.setEndTimeFlag("0");
        } else if (customizeGroup.getEndTime() == null && model.getEndTime() != null) {//加上了结束时间
            model.setEndTimeFlag("1");
        }

        BeanUtils.copyProperties(model, customizeGroup);
        int i = customizeGroupMapper.updateByPrimaryKey(customizeGroup);
        return model;
    }

    public int deleteCustomizeGroup(int id) {
        int i = customizeGroupMapper.deleteByPrimaryKey(id);
        return i;
    }

    public List<CustomizeGroupModel> findAllCustomizeGroup(CustomizeGroupModel queryModel) {
        CustomizeGroupExample example = new CustomizeGroupExample();
        CustomizeGroupExample.Criteria criteria = example.createCriteria();

        if (StringUtils.isNotEmpty(queryModel.getGroupName())) {
            criteria.andGroupNameLike("%" + queryModel.getGroupName() + "%");
        }

        List<CustomizeGroup> CustomizeGroups = customizeGroupMapper.selectByExample(example);
        List<CustomizeGroupModel> resList = new ArrayList<>();
        for (CustomizeGroup customizeGroup : CustomizeGroups) {
            CustomizeGroupModel model = new CustomizeGroupModel();
            BeanUtils.copyProperties(customizeGroup, model);
            resList.add(model);
        }

        return resList;
    }

    /**
     * 根据组ID删除其中的站代码
     *
     * @param groupId
     * @param stationCode
     */
    public Map<String, Object> deleteStationByGroupId(String groupId, String stationCode, String userId) {
        Map<String, Object> resMap = new HashMap<>();
        CustomizeGroupExample example = new CustomizeGroupExample();
        CustomizeGroupExample.Criteria criteria = example.createCriteria();
        criteria.andGroupIdEqualTo(groupId);
        List<CustomizeGroup> customizeGroups = customizeGroupMapper.selectByExample(example);
        Integer res = 0;
        if (customizeGroups != null && customizeGroups.size() > 0) {
            CustomizeGroup entity = customizeGroups.get(0);
            if (entity.getCreateUserId().equals(userId)) {
                String[] arr = entity.getStationCodes().split(",");
                ArrayList<String> arrayList = new ArrayList<>(arr.length);
                Collections.addAll(arrayList, arr);
                if (arrayList.contains(stationCode)) {
                    arrayList.remove(stationCode);
                    entity.setStationCodes(StringUtils.join(arrayList, ","));
                    res = customizeGroupMapper.updateByPrimaryKey(entity);
                }
            } else {
                resMap.put("error", "分组仅允许创建者操作");
                return resMap;
            }
        }
        resMap.put("res", res);
        return resMap;
    }

    //校验、过滤非法编码
    private String checkStationCodes(String stationCodes, String codeType) {
        if (StringUtils.isEmpty(stationCodes)) return "";
        stationCodes = stationCodes.replace("，", ",");
        String[] arr = stationCodes.split(",");
        ArrayList<String> arrayList = new ArrayList<>();
        int len = codeType.equals("0") ? 10 : 11;
        for (String code : arr) {
            if (StringUtils.isEmpty(code)) continue;
            if (!StringUtils.isNumeric(code)) continue;
            if (code.length() != len) continue;
            if (arrayList.contains(code)) continue;
            arrayList.add(code);
        }
        return StringUtils.join(arrayList, ",");
    }

    public String checkStationCodes(CustomizeGroupModel model) {
        if (StringUtils.isEmpty(model.getStationCodes())) return null;
        String stationCodes = model.getStationCodes().replace("，", ",");
        String[] arr = stationCodes.split(",");
        ArrayList<String> arrayList = new ArrayList<>();
        ArrayList<String> errList = new ArrayList<>();

        //0：遥测站(10)，1：设备SN(11)
        int len = model.getCodeType().equals("0") ? 10 : 11;

        for (String code : arr) {
            if (StringUtils.isEmpty(code)) continue;
            if (!StringUtils.isNumeric(code)) {
                errList.add(code);
            }
            if (code.length() != len) {
                errList.add(code);
            }
            if (arrayList.contains(code)) continue;
            arrayList.add(code);
        }
        if (errList.size() > 0) {
            return "编号不规范:" + StringUtils.join(errList, ",");
        } else {
            model.setStationCodes(StringUtils.join(arrayList, ","));
            return null;
        }
    }

    /**
     * 根据CustomeGroupQueryModel对象更新分组(前台根据版本勾选后使用)
     *
     * @param model
     * @return
     */
    public CustomizeGroupModel updateCustomizeGroupByCustomeGroupQueryModel(CustomeGroupQueryModel model) {
        String stationCodes = String.join(",", model.getStationCodes());
        CustomizeGroup customizeGroup = customizeGroupMapper.selectByPrimaryKey(model.getUid());
        stationCodes = stationCodes + "," + customizeGroup.getStationCodes();
        String codeType = StringUtils.isEmpty(customizeGroup.getCodeType()) ? "0" : customizeGroup.getCodeType();
        customizeGroup.setStationCodes(checkStationCodes(stationCodes, codeType));

        customizeGroupMapper.updateByPrimaryKey(customizeGroup);

        CustomizeGroupModel customizeGroupModel = new CustomizeGroupModel();
        BeanUtils.copyProperties(customizeGroup, customizeGroupModel);
        return customizeGroupModel;
    }

    /**
     * 根据GroupId获取对象
     *
     * @param groupId
     * @return
     */
    public CustomizeGroupModel findCustomizeGroupByGroupId(String groupId) {
        CustomizeGroupExample example = new CustomizeGroupExample();
        CustomizeGroupExample.Criteria criteria = example.createCriteria();
        criteria.andGroupIdEqualTo(groupId);
        List<CustomizeGroup> customizeGroups = customizeGroupMapper.selectByExample(example);
        if (customizeGroups != null && customizeGroups.size() > 0) {
            CustomizeGroup customizeGroup = customizeGroups.get(0);
            CustomizeGroupModel customizeGroupModel = new CustomizeGroupModel();
            BeanUtils.copyProperties(customizeGroup, customizeGroupModel);
            return customizeGroupModel;
        }
        return null;
    }

    /**
     * 将自定义分组复制到APP分组
     *
     * @param customizeGroupModel
     * @param appUserModel
     * @return
     */
    public AppDeviceGroupModel copyCustomizeGroupToAppGroup(CustomizeGroupModel customizeGroupModel, AppUserModel appUserModel) {
        AppDeviceGroupModel appDeviceGroupModel = new AppDeviceGroupModel();
        appDeviceGroupModel.setGroupId(customizeGroupModel.getGroupId());
        appDeviceGroupModel.setGroupName(customizeGroupModel.getGroupName());
        appDeviceGroupModel.setUserId(appUserModel.getUserId());
        appDeviceGroupModel.setGroupType("3");//规定是3
        appDeviceGroupModel = appDeviceGroupService.saveAppDeviceGroup(appDeviceGroupModel);
        String[] stationCodes = customizeGroupModel.getStationCodes().split(",");
        for (String stationCode : stationCodes) {
            AppDevgroupDetailModel detailModel = new AppDevgroupDetailModel();
            //存疑:要不要过滤掉未绑定站点的
            detailModel.setGroupId(appDeviceGroupModel.getGroupId());
            detailModel.setStationCode(stationCode);
            appDevgroupDetailService.saveAppDevgroupDetail(detailModel);
        }
        return appDeviceGroupModel;
    }

    /**
     * 分组临时对象
     */
    class GroupTempModel {
        public GroupTempModel(String userId, List<CustomizeGroup> details) {
            this.userId = userId;
            this.details = details;
        }

        private String userId;
        private List<CustomizeGroup> details;

        public String getUserId() {
            return userId;
        }

        public void setUserId(String userId) {
            this.userId = userId;
        }

        public List<CustomizeGroup> getDetails() {
            return details;
        }

        public void setDetails(List<CustomizeGroup> details) {
            this.details = details;
        }
    }
}
