package com.mortals.xhx.module.site.model;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.DefaultJSONParser;
import com.alibaba.fastjson.parser.JSONToken;
import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer;
import com.mortals.framework.common.Rest;
import com.mortals.framework.util.DataUtil;
import com.mortals.xhx.common.code.DeviceStatusEnum;
import com.mortals.xhx.common.code.EnabledEnum;
import com.mortals.xhx.common.code.YesNoEnum;
import com.mortals.xhx.common.pdu.site.SitePdu;
import com.mortals.xhx.feign.site.ISiteFeign;
import com.mortals.xhx.module.area.model.AreaEntity;
import com.mortals.xhx.module.device.model.DeviceEntity;
import com.mortals.xhx.module.device.model.DeviceQuery;
import com.mortals.xhx.module.device.service.DeviceService;
import com.mortals.xhx.module.sitestat.model.SitestatEntity;
import com.mortals.xhx.module.sitestat.service.SitestatService;
import com.mortals.xhx.utils.SpringUtils;
import lombok.Data;
import org.springframework.util.ObjectUtils;

import java.io.Serializable;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 区域前端映射树结构实体类
 *
 * @author zxfei
 * @date 2022-01-12
 */
@Data
public class SiteTreeSelect implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * 节点ID
     */
    private String id;

    /**
     * 站点编码
     */
    private String siteCode;

    /**
     * 站点详细地址
     */
    private String detailAddress;

    /**
     * 节点名称
     */
    private String label;
    /**
     * 区域编码
     */
    private String areaCode;
    /**
     * 为区域时 层级
     */
    private Integer level;
    /**
     * 是否叶子节点
     */
    private Boolean isLeaf;

    /**
     * 经度
     */
    private String longitude;
    /**
     * 纬度
     */
    private String latitude;

    /**
     * 节点类型
     */
    private String type;

    /**
     * 图标
     */
    private String icon;

    /**
     * 设备总数
     */
    private Integer deviceTotal;

    /**
     * 在线总数
     */
    private Integer offlineTotal;

    /**
     * 离线总数
     */
    private Integer onlineTotal;

    private Integer stopCount;
    /**
     * 未激活设备数量
     */
    private Integer UnActiveTotal;

    /**
     * 子节点数量
     */
    private Integer siteCount;


    /**
     * 子节点
     */
    private List<SiteTreeSelect> children;


    /**
     * 站点统计id
     */
    private Long siteStatId;

    public SiteTreeSelect() {
    }

    public SiteTreeSelect(AreaEntity entity) {
        //如果是站点，则替换名称和id

        this.id = entity.getIid();
        this.label = entity.getName();
        if ("False".equalsIgnoreCase(entity.getHaveSonArea())) {
            this.isLeaf = true;
            this.children = new ArrayList();
        } else {
            this.isLeaf = false;
        }
        this.areaCode = entity.getAreaCode();
        this.type = "area";
        this.icon = "el-icon-folder";
    }

    public SiteTreeSelect(AreaEntity entity, Map<String, SiteEntity> siteMap) {
        List<SiteEntity> collect = siteMap.entrySet().stream().filter(f -> f.getKey().startsWith(entity.getAreaCode()))
                .map(m -> m.getValue())
                .collect(Collectors.toList());
        if (!ObjectUtils.isEmpty(collect)) {
            this.id = collect.stream().map(item -> item.getId().toString()).collect(Collectors.joining(","));
            this.label = collect.stream().map(item -> item.getSiteName()).collect(Collectors.joining(","));
            this.siteCode = collect.stream().map(item -> item.getSiteCode()).collect(Collectors.joining(","));
            this.type = "site";
            this.icon = "el-icon-wind-power";
            this.detailAddress = collect.stream().map(item -> item.getDetailAddress()).collect(Collectors.joining(","));
            this.longitude = collect.stream().findFirst().map(item -> item.getLongitude()).orElseGet(() -> "");
            this.latitude = collect.stream().findFirst().map(item -> item.getLatitude()).orElseGet(() -> "");
        } else {
            this.id = entity.getIid();
            this.label = entity.getName();
            this.type = "area";
            this.icon = "el-icon-place";
        }
        this.level = entity.getAreaLevel();
        if ("False".equalsIgnoreCase(entity.getHaveSonArea())) {
            this.isLeaf = true;
            //this.children = new ArrayList();
        } else {
            this.isLeaf = false;
            this.children = entity.getChildren().stream().map(item -> new SiteTreeSelect(item, siteMap)).collect(Collectors.toList());
        }
        this.areaCode = entity.getAreaCode();


    }

    // 反序列化器
    public static class Deserializer implements ObjectDeserializer {
        @Override
        public SiteTreeSelect deserialze(DefaultJSONParser parser, Type type, Object fieldName) {
            SiteTreeSelect node = new SiteTreeSelect();
            JSONObject jsonObject = parser.parseObject();
            node.setId(jsonObject.getString("id"));
            node.setSiteCode(jsonObject.getString("siteCode"));
            node.setLabel(jsonObject.getString("label"));
            node.setAreaCode(jsonObject.getString("areaCode"));
            node.setIsLeaf(jsonObject.getBoolean("isLeaf"));
            node.setLongitude(jsonObject.getString("longitude"));
            node.setLatitude(jsonObject.getString("latitude"));
            node.setType(jsonObject.getString("type"));
            node.setIcon(jsonObject.getString("icon"));
            ISiteFeign siteFeign = SpringUtils.getBean(ISiteFeign.class);
            SitePdu sitePdu = new SitePdu();
            if ("site".equals(node.getType())) {
                //统计当前站点下的所有在线 离线 设备总数。
                DeviceService deviceService = SpringUtils.getBean(DeviceService.class);
                SitestatService sitestatService = SpringUtils.getBean(SitestatService.class);
                List<DeviceEntity> deviceList = deviceService.find(new DeviceQuery().siteId(DataUtil.converStr2Long(node.getId(), -1)));
                node.setDeviceTotal(deviceList.size());
                //未激活数量
                Long deviceUnActiveCount = deviceList.parallelStream()
                        .filter(f -> f.getDeviceStatus() == DeviceStatusEnum.未激活.getValue())
                        .count();
                node.setUnActiveTotal(deviceUnActiveCount.intValue());
                Long deviceOnlineCount = deviceList.parallelStream()
                        .filter(f -> f.getDeviceStatus() > DeviceStatusEnum.未激活.getValue())
                        .filter(f -> f.getEnabled() == EnabledEnum.启用.getValue())
                        .filter(f -> f.getDeviceStatus() == DeviceStatusEnum.在线.getValue())
                        .count();

                node.setOnlineTotal(deviceOnlineCount.intValue());
                //离线数量
                Long deviceOfflineCount = deviceList.parallelStream()
                        .filter(f -> f.getDeviceStatus() > DeviceStatusEnum.未激活.getValue())
                        .filter(f -> f.getEnabled() == EnabledEnum.启用.getValue())
                        .filter(f -> f.getDeviceStatus() == DeviceStatusEnum.离线.getValue())
                        .count();
                node.setOfflineTotal(deviceOfflineCount.intValue());

                //停用数量
                Long stopCount = deviceList.stream()
                        .filter(f -> f.getDeviceStatus() > DeviceStatusEnum.未激活.getValue())
                        .filter(f -> f.getEnabled() == YesNoEnum.NO.getValue())
                        .count();
                node.setStopCount(stopCount.intValue());
                //设置统计id
                SitestatEntity sitestatCache = sitestatService.getExtCache(node.getSiteCode());
                if (!ObjectUtils.isEmpty(sitestatCache)) {
                    node.setSiteStatId(sitestatCache.getId());
                }
            }
            sitePdu.setAreaCode(node.getAreaCode());
            Rest<Integer> rest = siteFeign.countSitesByArea(sitePdu);
            if (rest.getCode() == YesNoEnum.YES.getValue()) {
                node.setSiteCount(rest.getData());
            }
            JSONArray jsonArray = jsonObject.getJSONArray("children");
            List<SiteTreeSelect> children = new ArrayList<>();
            if (!ObjectUtils.isEmpty(jsonArray)) {
                for (int i = 0; i < jsonArray.size(); i++) {
                    SiteTreeSelect child = JSON.parseObject(jsonArray.getJSONObject(i).toJSONString(), SiteTreeSelect.class);
                    children.add(child);
                }
            }
            node.setChildren(children);
            return node;
        }

        @Override
        public int getFastMatchToken() {
            return JSONToken.LBRACE;
        }
    }

}