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.xhx.module.area.model.AreaEntity;
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 String areaName;

    /**
     * 为区域时 层级
     */
    private Integer level;

    /**
     * 是否叶子节点
     */
    private Boolean isLeaf;

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

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

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

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

    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.areaCode=collect.stream().map(item -> item.getAreaCode()).collect(Collectors.joining(","));
            this.areaName=collect.stream().map(item -> item.getAreaName()).collect(Collectors.joining(","));
            this.longitude = collect.stream().map(item -> item.getLongitude()).collect(Collectors.joining(","));
            this.latitude = collect.stream().map(item -> item.getLatitude()).collect(Collectors.joining(","));
        } else {
            this.id = entity.getIid();
            this.label = entity.getName();
            this.type = "area";
            this.icon = "el-icon-place";
            this.areaCode=entity.getAreaCode();
        }
        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.setAreaName(jsonObject.getString("areaName"));
            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"));
            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;
        }
    }

}