package com.reyun.service.impl;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.reyun.model.*;
import com.reyun.repository.*;
import com.reyun.service.*;
import com.reyun.util.*;
import org.apache.commons.collections.CollectionUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Nullable;
import java.io.IOException;
import java.math.BigInteger;
import java.util.*;

@Service
public class EventServiceImpl implements EventService {
    private static final Logger logger = LoggerFactory.getLogger(EventServiceImpl.class);

    @Autowired
    EventRepository eventRepository;

    @Autowired
    AppRepository appRepository;

    @Autowired
    EventViewAttrRepository eventViewAttrRepository;

    @Autowired
    CommonEventRepository commonEventRepository;

    @Autowired
    CommonParamService commonParamService;

    @Autowired
    UserGroupService usergroupService;

    @Autowired
    EventMetaRepository eventMetaRepository;

    @Autowired
    EventAttributeMetaRepository eventAttributeMetaRepository;

    @Autowired
    ComplicatedParamRepository complicatedParamRepository;

    @Autowired
    AttributeRestrictRepository attributeRestrictRepository;

    @Autowired
    ProfileRepository profileRepository;

    @Autowired
    CommonParamRepository commonParamRepository;

    @Autowired
    VirtualEventService virtualEventService;

    @Autowired
    ProfileService profileService;

    @Autowired
    EventService eventService;


    private static final String EVENT_ATTR_CID = "_cid";

    private static final String EVENT_ATTR_CAMPAIGNID = "_campaignid";

    //默认统计属性
    private final static int VIEW_ATTR_DEFAULT = 1;
    private final static int VIEW_ATTR_CUSTOM = 2;
    private final static String ATTR_TYPE_DEFAULT = "default";

    @Override
    public List<CommonParam> listAllAttributes(Long appId) {

/*      String appkey = appRepository.findAppkeyById(appId);
        ArrayList<String> attrName = new ArrayList<>();
        ArrayList<EventAttr4Web> attr4WebArrayList = new ArrayList<>();
        if (!StringUtils.isEmpty(eventList)) {
            String[] events = eventList.split(",");
            for (String event : events) {
                List<EventAttr4Web> eventAttr4Webs = eventService.listOneEvent(appId, event);
                for (EventAttr4Web eventAttr4Web : eventAttr4Webs) {
                    if (!attrName.contains(eventAttr4Web.getAttr())) {
                        attrName.add(eventAttr4Web.getAttr());
                        attr4WebArrayList.add(eventAttr4Web);
                    }
                }
            }
        }*/

        List<Profile> profiles = this.listByAppkeyBugFix(appId);
        ArrayList<CommonParam> allAttributes = new ArrayList<>();
        List<CommonParam> eventParams = commonParamService.listAllByType("event");
        List<CommonParam> profileParams = commonParamService.listAllByType("profile");

        Map<String, CommonParam> eventParamsMap = Maps.uniqueIndex(eventParams, new Function<CommonParam, String>() {
            @Nullable
            @Override
            public String apply(@Nullable CommonParam eventParams) {
                return eventParams.getParam();
            }
        });

        Map<String, CommonParam> profileParamsMap = Maps.uniqueIndex(profileParams, new Function<CommonParam, String>() {
            @Nullable
            @Override
            public String apply(@Nullable CommonParam profileParams) {
                return profileParams.getParam();
            }
        });

        String appkey = appRepository.findAppkeyById(appId);
        List<EventAttr4Web> eventAttr4WebsAll = eventService.listOneEvent(appId, null);
        List<EventAttr4Web> eventAttr4Webs = new ArrayList<>();
        for (EventAttr4Web eventAttr4Web : eventAttr4WebsAll) {
            if ((eventAttr4Web.getStatus() && eventAttr4Web.getAddStatsCondition()) || eventParamsMap.containsKey(eventAttr4Web.getAttr())) {
                eventAttr4Webs.add(eventAttr4Web);
            }
        }

        int i = 33;
        Integer j = commonParamRepository.findNumByType("profile").intValue();
        for (Profile profile : profiles) {
            CommonParam commonParam = new CommonParam();
            AttributeRestrict allRestrict = attributeRestrictRepository.findIsAllRestrictByNameAndType(profile.getAttr(), "profile", "all");
            AttributeRestrict singleRestrict = attributeRestrictRepository.findIsRestrictByAppIdAndType(appkey, "profile", profile.getAttr());

            boolean isAllRestrict = allRestrict == null ? false : (allRestrict.isAllRestrict() || allRestrict.isProfileRestrict());
            boolean isSingleRestrict = singleRestrict == null ? false : (singleRestrict.isRootRestrict() || singleRestrict.isParentRestrict() || singleRestrict.isAppRestrict() || singleRestrict.isProfileRestrict());
            if (!isAllRestrict && !isSingleRestrict) {
                if (profileParamsMap.containsKey(profile.getAttr())) {
                    allAttributes.add(profileParamsMap.get(profile.getAttr()));
                } else if (profile.isAdd_stats_condition() && profile.getStatus()) {
                    i++;
                    j++;
                    commonParam.setId(new Long(i));
                    commonParam.setSortId(j);
                    commonParam.setAlias(profile.getAttrAlias());
                    commonParam.setParam(profile.getAttr());
                    commonParam.setType("profile");
                    commonParam.setDataType("string");
                    allAttributes.add(commonParam);
                }
            }
        }

        Integer n = commonParamRepository.findNumByType("event").intValue();
        int m = 5;
        for (EventAttr4Web event4Web : eventAttr4Webs) {
            AttributeRestrict allRestrict = attributeRestrictRepository.findIsAllRestrictByNameAndType(event4Web.getAttr(), "event", "all");
            AttributeRestrict singleRestrict = attributeRestrictRepository.findIsRestrictByAppIdAndType(appkey, "event", event4Web.getAttr());
            boolean isAllRestrict = allRestrict == null ? false : (allRestrict.isAllRestrict() || allRestrict.isProfileRestrict());
            boolean isSingleRestrict = singleRestrict == null ? false : (singleRestrict.isRootRestrict() || singleRestrict.isParentRestrict() || singleRestrict.isAppRestrict() || singleRestrict.isProfileRestrict());
            if (!isAllRestrict && !isSingleRestrict) {
                CommonParam commonParam = new CommonParam();
                if (eventParamsMap.containsKey(event4Web.getAttr())) {
                    allAttributes.add(eventParamsMap.get(event4Web.getAttr()));
                } else {
                    n++;
                    m++;
                    commonParam.setId(new Long(m));
                    commonParam.setSortId(n);
                    commonParam.setAlias(event4Web.getAttrAlias());
                    commonParam.setParam(event4Web.getAttr());
                    commonParam.setType("event");
                    commonParam.setDataType(event4Web.getDataType());
                    allAttributes.add(commonParam);
                }
            }
        }
        return allAttributes;
    }


    @Override
    public List<EventAttr4Web> listAllEventAttributesTop50(Long appId, String propertiesType) {
        ArrayList<CommonParam> allAttributes = new ArrayList<>();
        List<CommonParam> eventParams = commonParamService.listAllByType("event");
        Map<String, CommonParam> eventParamsMap = Maps.uniqueIndex(eventParams, new Function<CommonParam, String>() {
            @Nullable
            @Override
            public String apply(@Nullable CommonParam eventParams) {
                return eventParams.getParam();
            }
        });

        List<EventAttr4Web> eventAttr4WebsAll = eventService.listOneEvent(appId, null);

        List<EventAttr4Web> eventAttr4Webs2 = new ArrayList<>();

        for (EventAttr4Web eventAttr4Web : eventAttr4WebsAll) {
            if ((eventAttr4Web.getStatus() && eventAttr4Web.getAddStatsCondition()) || eventParamsMap.containsKey(eventAttr4Web.getAttr())) {
                eventAttr4Webs2.add(eventAttr4Web);
            }
        }


        Integer n = commonParamRepository.findNumByType("event").intValue();
        int m = 5;
        for (EventAttr4Web event4Web : eventAttr4Webs2) {
            CommonParam commonParam = new CommonParam();
            if (eventParamsMap.containsKey(event4Web.getAttr())) {
                allAttributes.add(eventParamsMap.get(event4Web.getAttr()));
            } else {
                n++;
                m++;
                String s;
                commonParam.setId(new Long(m));
                commonParam.setSortId(n);
                commonParam.setAlias(event4Web.getAttrAlias());
                commonParam.setParam(event4Web.getAttr());
                commonParam.setType("event");
                commonParam.setDataType(event4Web.getDataType());
                allAttributes.add(commonParam);
            }
        }

        List<EventAttr4Web> allEventAttrProperties = new ArrayList<>();
        for (CommonParam commonParam : allAttributes) {
            EventAttr4Web eventAttr4Web = new EventAttr4Web();

            eventAttr4Web.setAttr(commonParam.getParam());
            eventAttr4Web.setAttrAlias(commonParam.getAlias());
            eventAttr4Web.setType(commonParam.getType());
            eventAttr4Web.setDataType(commonParam.getDataType());

            //填充渠道
            if (EVENT_ATTR_CID.equals(commonParam.getParam())) {
                eventAttr4Web.setWebType("string");
            }
            allEventAttrProperties.add(eventAttr4Web);
        }
        return allEventAttrProperties;
    }


    @Override
    public List<Profile> listByAppkeyBugFix(Long appid) {
        String appkey = appRepository.findAppkeyById(appid);
        List<Profile> oldResult = profileRepository.findAllByAppkey(appkey);
        List<CommonParam> profileCommonParams = commonParamRepository.findAllByType("profile");
        Map<String, CommonParam> profileCommonParamsMaps = Maps.uniqueIndex(profileCommonParams, new Function<CommonParam, String>() {
            @Nullable
            @Override
            public String apply(@Nullable CommonParam commonParam) {
                return commonParam.getParam();
            }
        });

        List<Profile> newResult = new ArrayList<Profile>();
        for (CommonParam commonParam : profileCommonParams) {
            Profile profile = new Profile();
            profile.setAppkey(appkey);
            profile.setAttrAlias(commonParam.getAlias());
            profile.setAttr(commonParam.getParam());
            profile.setCommon(true);
            profile.setStatus(true);
            profile.setDataType(commonParam.getDataType());
            newResult.add(profile);
        }

        for (Profile temp : oldResult) {
            if (!profileCommonParamsMaps.containsKey(temp.getAttr())) {
                if (ValidateUtil.validNotChinese(temp.getAttr())) {
                    if (!ValidateUtil.isValid(temp.getAttrAlias())) {
                        temp.setAttrAlias(temp.getAttr());
                    }
                    newResult.add(temp);
                }
            }
        }
        return newResult;
    }



    @Override
    public List<Event4Web> listEvent(Long app) {

        String appkey = appRepository.findAppkeyById(app);
        List<Event> eventList = eventRepository.findByAppkey(appkey);
        List<EventMeta> metas = eventMetaRepository.findByAppkey(appkey);
        List<CommonEvent> commonEventList = commonEventRepository.findAll();

        Map<String, EventMeta> metaMap = new HashMap<>();
        if (ValidateUtil.isValid(metas)) {
            for (EventMeta e : metas) {
                metaMap.put(e.getEventId(), e);
            }
        }

        Map<String, CommonEvent> commonMap = new HashMap<>();
        if (ValidateUtil.isValid(commonEventList)) {
            for (CommonEvent e : commonEventList) {
                commonMap.put(e.getEvent(), e);
            }
        }

        LinkedList<Event4Web> result = new LinkedList<>();
        LinkedList<Event4Web> temp = new LinkedList<>();
        List<String> nameList = new ArrayList<>();
        if (ValidateUtil.isValid(eventList)) {
            for (Event e : eventList) {
                if (!nameList.contains(e.getEventName())) {
                    if (commonMap.containsKey(e.getEventName())) {
                        nameList.add(e.getEventName());

                        CommonEvent commonEvent = commonMap.get(e.getEventName());
                        Event4Web event4Web = commonEventTo4Web(commonEvent);
                        result.add(event4Web);
                    } else {
                        nameList.add(e.getEventName());
                        if (metaMap.containsKey(e.getEventName())) {
                            EventMeta eventMeta = metaMap.get(e.getEventName());
                            Event4Web event4Web = eventMetaTo4Web(eventMeta);
                            temp.add(event4Web);
                        } else {
                            Event4Web event4Web = eventTo4Web(e);
                            temp.add(event4Web);
                        }
                    }
                }
            }
            result.addAll(temp);
        }
        return result;
    }


    @Override
    public List<Event4Tracking> listEvent4Tracking(Long app) {

        String appkey = appRepository.findAppkeyById(app);
        List<Event> eventList = eventRepository.findByAppkey(appkey);
        List<EventMeta> metas = eventMetaRepository.findByAppkey(appkey);
        List<CommonEvent> commonEventList = commonEventRepository.findAll();

        Map<String, EventMeta> metaMap = new HashMap<>();
        if (ValidateUtil.isValid(metas)) {
            for (EventMeta e : metas) {
                metaMap.put(e.getEventId(), e);
            }
        }

        Map<String, CommonEvent> commonMap = new HashMap<>();
        if (ValidateUtil.isValid(commonEventList)) {
            for (CommonEvent e : commonEventList) {
                commonMap.put(e.getEvent(), e);
            }
        }

        LinkedList<Event4Tracking> result = new LinkedList<>();
        LinkedList<Event4Tracking> temp = new LinkedList<>();
        List<String> nameList = new ArrayList<>();
        if (ValidateUtil.isValid(eventList)) {
            for (Event e : eventList) {
                if (!nameList.contains(e.getEventName())) {
                    if (commonMap.containsKey(e.getEventName())) {
                        nameList.add(e.getEventName());

                        CommonEvent commonEvent = commonMap.get(e.getEventName());
                        Event4Web event4Web = commonEventTo4Web(commonEvent);
                        result.add(new Event4Tracking(event4Web));
                    } else {
                        nameList.add(e.getEventName());
                        if (metaMap.containsKey(e.getEventName())) {
                            EventMeta eventMeta = metaMap.get(e.getEventName());
                            Event4Web event4Web = eventMetaTo4Web(eventMeta);
                            temp.add(new Event4Tracking(event4Web));
                        } else {
                            Event4Web event4Web = eventTo4Web(e);
                            temp.add(new Event4Tracking(event4Web));
                        }
                    }
                }
            }
            result.addAll(temp);
        }
        return result;
    }


    @Override
    public List<EventAttr4Web> listOneEvent(Long app, String name) {

        String appkey = appRepository.findAppkeyById(app);
        List<Event> eventList = null;
        if (name != null) {
            eventList = eventRepository.findByEventName(appkey, name);
        } else {
            eventList = eventRepository.findByAppkey(appkey);
        }

        Map<String, CommonParam> map = commonParamService.findAllByType("event");
        List<EventAttributeMeta> metas = eventAttributeMetaRepository.findByAppkey(appkey);

        Map<String, EventAttributeMeta> metaMap = new HashMap<>();
        if (ValidateUtil.isValid(metas)) {
            for (EventAttributeMeta e : metas) {
                metaMap.put(e.getAttribute(), e);
            }
        }

        LinkedList<EventAttr4Web> result = new LinkedList<>();
        LinkedList<EventAttr4Web> temp = new LinkedList<>();
        TreeMap<Integer, EventAttr4Web> commonMap = new TreeMap<>();
        if (ValidateUtil.isValid(eventList)) {

            List<String> eventAttrNameList = new ArrayList<>();

            for (Event event : eventList) {
                if (!eventAttrNameList.contains(event.getEventAttr())) {
                    eventAttrNameList.add(event.getEventAttr());

                    if (map.containsKey(event.getEventAttr())) {
                        CommonParam commonParam = map.get(event.getEventAttr());
                        EventAttr4Web eventAttr4Web = coomonEventAttrTo4Web(commonParam);
                        eventAttr4Web.setDataType(event.getDataType());
                        commonMap.put(commonParam.getSortId(), eventAttr4Web);
                    } else {
                        if (metaMap.containsKey(event.getEventAttr())) {
                            EventAttributeMeta eventAttributeMeta = metaMap.get(event.getEventAttr());
                            EventAttr4Web eventAttr4Web = eventAttrMetaTo4Web(eventAttributeMeta);
                            eventAttr4Web.setDataType(event.getDataType());
                            temp.add(eventAttr4Web);
                        } else {
                            EventAttr4Web eventAttr4Web = eventAttrTo4Web(event);
                            eventAttr4Web.setDataType(event.getDataType());
                            temp.add(eventAttr4Web);
                        }
                    }
                }
            }
            if (ValidateUtil.isValid(commonMap)) {
                for (Integer i : commonMap.keySet()) {
                    result.add(commonMap.get(i));
                }
            }
            result.addAll(temp);
        }

        return result;
    }

    public EventAttr4Web eventAttrTo4Web(Event e) {
        EventAttr4Web ew = new EventAttr4Web();

        ew.setStatus(true);
        ew.setAddStatsCondition(false);
        ew.setAddStatsView(false);
        ew.setAttr(e.getEventAttr());
        ew.setAttrAlias(e.getEventAttr());
        ew.setCommon(false);

        return ew;
    }

    public EventAttr4Web coomonEventAttrTo4Web(CommonParam e) {
        EventAttr4Web ew = new EventAttr4Web();

        ew.setStatus(true);
        ew.setAddStatsCondition(false);
        ew.setAddStatsView(false);
        ew.setAttr(e.getParam());
        ew.setAttrAlias(e.getAlias());
        ew.setCommon(true);
        return ew;
    }

    public EventAttr4Web eventAttrMetaTo4Web(EventAttributeMeta e) {
        EventAttr4Web ew = new EventAttr4Web();

        ew.setStatus(e.getStatus());
        ew.setAddStatsCondition(e.getAddStatsCondition());
        ew.setAddStatsView(e.getAddStatsView());
        ew.setAttr(e.getAttribute());
        ew.setAttrAlias(e.getAlias() == null ? e.getAttribute() : e.getAlias());
        ew.setCommon(false);
        return ew;
    }

    @Override
    public Map<String, String> findEventNameAliasMap(String appKey, List<String> eventNameList) {

        Map<String, String> resultMap = new HashMap<>();

        //自定义别名
        List<EventMeta> eventMetaList = eventMetaRepository.findByEventIds(appKey, eventNameList);
        Map<String, EventMeta> eventMetaMap = Maps.uniqueIndex(eventMetaList, new Function<EventMeta, String>() {
            @Override
            public String apply(EventMeta eventMeta) {
                return eventMeta.getEventId();
            }
        });

        //通用事件别名
        Map<String, CommonEvent> commonEventMap = commonParamService.findAllCommonEvent();

        for (String eventName : eventNameList) {

            if (eventMetaMap.containsKey(eventName) && !StringUtils.isEmpty(eventMetaMap.get(eventName).getAlias())) {

                resultMap.put(eventName, eventMetaMap.get(eventName).getAlias());

            } else if (commonEventMap.containsKey(eventName) && !StringUtils.isEmpty(commonEventMap.get(eventName).getAlias())) {

                resultMap.put(eventName, commonEventMap.get(eventName).getAlias());

            } else {

                resultMap.put(eventName, eventName);
            }
        }

        return resultMap;
    }

    @Override
    public EventMeta updateEvent(Long app, String name, String nameAlias, Long account) {
        String appkey = appRepository.findAppkeyById(app);
        EventMeta event = eventMetaRepository.findByEventId(appkey, name);

        if (event == null) {
            EventMeta eventMeta = new EventMeta();
            eventMeta.setStatus(true);
            eventMeta.setAlias(nameAlias);
            eventMeta.setAppkey(appkey);
            eventMeta.setEventId(name);
            eventMeta.setModifyAccount(account);
            eventMeta.setModifyTime(new Date());

            return eventMetaRepository.save(eventMeta);
        } else {
            event.setModifyTime(new Date());
            event.setModifyAccount(account);
            event.setAlias(nameAlias);

            return eventMetaRepository.save(event);
        }
    }

    @Override
    public EventAttributeMeta updateEventAttr(String eventname, String attrnameAlias, Long account, Long app) {
        String appkey = appRepository.findAppkeyById(app);
        EventAttributeMeta attributeMeta = eventAttributeMetaRepository.findByAttribute(appkey, eventname);

        if (attributeMeta == null) {
            EventAttributeMeta attr = new EventAttributeMeta();
            attr.setAttribute(eventname);
            attr.setAlias(attrnameAlias);
            attr.setStatus(true);
            attr.setAddStatsView(false);
            attr.setAddStatsCondition(false);
            attr.setAppkey(appkey);
            attr.setModifyAccount(account);
            attr.setModifyTime(new Date());
            return eventAttributeMetaRepository.save(attr);
        } else {
            attributeMeta.setModifyTime(new Date());
            attributeMeta.setModifyAccount(account);
            attributeMeta.setAlias(attrnameAlias);

            return eventAttributeMetaRepository.save(attributeMeta);
        }
    }

    @Override
    public void enableEvent(Long app, String name, Long account) {
        String appkey = appRepository.findAppkeyById(app);
        EventMeta event = eventMetaRepository.findByEventId(appkey, name);

        event.setStatus(true);

        eventMetaRepository.save(event);
    }

    @Override
    public void forbiddenEvent(Long app, String name, Long account) {
        String appkey = appRepository.findAppkeyById(app);
        EventMeta event = eventMetaRepository.findByEventId(appkey, name);

        if (event == null) {
            EventMeta eventMeta = new EventMeta();
            eventMeta.setStatus(false);
            eventMeta.setEventId(name);
            eventMeta.setAlias(name);
            eventMeta.setAppkey(appkey);
            eventMeta.setModifyAccount(account);
            eventMeta.setModifyTime(new Date());

            eventMetaRepository.save(eventMeta);
        } else {
            event.setModifyTime(new Date());
            event.setModifyAccount(account);
            event.setStatus(false);

            eventMetaRepository.save(event);
        }
    }

    @Override
    public EventAttributeMeta enableAttr(Long app, String name, Long account) {
        String appkey = appRepository.findAppkeyById(app);
        EventAttributeMeta attributeMeta = eventAttributeMetaRepository.findByAttribute(appkey, name);

        attributeMeta.setStatus(true);
        EventAttributeMeta save = eventAttributeMetaRepository.save(attributeMeta);
        return save;
    }

    @Override
    public EventAttributeMeta forbiddenAttr(Long app, String name, Long account) {
        String appkey = appRepository.findAppkeyById(app);
        EventAttributeMeta attributeMeta = eventAttributeMetaRepository.findByAttribute(appkey, name);

        if (attributeMeta == null) {
            EventAttributeMeta attr = new EventAttributeMeta();
            attr.setAttribute(name);
            attr.setAlias(name);
            attr.setStatus(false);
            attr.setAddStatsView(false);
            attr.setAddStatsCondition(false);
            attr.setAppkey(appkey);
            attr.setModifyAccount(account);
            attr.setModifyTime(new Date());

            return eventAttributeMetaRepository.save(attr);
        } else {
            attributeMeta.setStatus(false);
            attributeMeta.setModifyTime(new Date());
            attributeMeta.setModifyAccount(account);

            return eventAttributeMetaRepository.save(attributeMeta);
        }
    }

    /**
     * 修改是否加入事件分析
     * modify by sunhao 20170504
     */
    @Override
    public EventAttributeMeta updateEventStatsView(Long appId, Long account, String attrName, Boolean addFlag) {

        String appkey = appRepository.findAppkeyById(appId);
        EventAttributeMeta attributeMeta = eventAttributeMetaRepository.findByAttribute(appkey, attrName);

        if (attributeMeta == null) {
            EventAttributeMeta attr = new EventAttributeMeta();
            attr.setAttribute(attrName);
            attr.setAlias(attrName);
            attr.setStatus(true);
            attr.setAddStatsView(true);
            attr.setAddStatsCondition(false);
            attr.setAppkey(appkey);
            attr.setModifyAccount(account);
            attr.setModifyTime(new Date());

            return eventAttributeMetaRepository.save(attr);
        } else {
            attributeMeta.setAddStatsView(addFlag);
            attributeMeta.setModifyTime(new Date());
            attributeMeta.setModifyAccount(account);

            return eventAttributeMetaRepository.save(attributeMeta);
        }
    }

    /**
     * 修改是否加入事件分析条件
     */
    @Override
    public EventAttributeMeta updateEventStatsCondition(Long appId, Long account, String attrName, Boolean addFlag) {

        String appkey = appRepository.findAppkeyById(appId);
        EventAttributeMeta attributeMeta = eventAttributeMetaRepository.findByAttribute(appkey, attrName);

        if (attributeMeta == null) {
            EventAttributeMeta attr = new EventAttributeMeta();
            attr.setAttribute(attrName);
            attr.setAlias(attrName);
            attr.setStatus(true);
            attr.setAddStatsView(false);
            attr.setAddStatsCondition(true);
            attr.setAppkey(appkey);
            attr.setModifyAccount(account);
            attr.setModifyTime(new Date());

            return eventAttributeMetaRepository.save(attr);
        } else {
            attributeMeta.setAddStatsCondition(addFlag);
            attributeMeta.setModifyTime(new Date());
            attributeMeta.setModifyAccount(account);

            return eventAttributeMetaRepository.save(attributeMeta);
        }
    }

    public List<Event4Web> listAllNew(Long app, String names, String params) throws JSONException {

        List<Event4Web> resultList = new ArrayList<>();
        Map<String, Event4Web> valueEventMap = new HashMap<>();

        String[] nameArr = names.split(",");
        List<String> nameList = Arrays.asList(nameArr);
        String appKey = appRepository.findAppkeyById(app);
        List<Event> events = eventRepository.findByAppkeyAndNames(appKey, nameList);
        List<EventMeta> eventMetaFalseList = eventMetaRepository.findByAppkeyAndStatusIsFalse(appKey);
        List<EventMeta> eventMetaTrueList = eventMetaRepository.findByAppkeyAndStatusIsTrue(appKey);
        List<EventAttributeMeta> attrMetaList = eventAttributeMetaRepository.findByAppkeyAndCondition(appKey);
        Map<String, CommonParam> commonAttrMap = commonParamService.findAllByType("event");
        Map<String, CommonEvent> commonEventMap = commonParamService.findAllCommonEvent();

        Map<String, EventMeta> eventMetaFalseMap = new HashMap<>();
        if (ValidateUtil.isValid(eventMetaFalseList)) {
            for (EventMeta e : eventMetaFalseList) {
                eventMetaFalseMap.put(e.getEventId(), e);
            }
        }
        Map<String, EventMeta> eventMetaTrueMap = new HashMap<>();
        if (ValidateUtil.isValid(eventMetaTrueList)) {
            for (EventMeta e : eventMetaTrueList) {
                eventMetaTrueMap.put(e.getEventId(), e);
            }
        }
        Map<String, EventAttributeMeta> attrMetaMap = new HashMap<>();
        if (ValidateUtil.isValid(attrMetaList)) {
            for (EventAttributeMeta e : attrMetaList) {
                attrMetaMap.put(e.getAttribute(), e);
            }
        }

        //筛选所有的通用事件
        Map<String, List<Event>> eventMap = new HashMap<>();
        if (ValidateUtil.isValid(events)) {
            for (Event e : events) {
                if ((commonEventMap.containsKey(e.getEventName()) || !eventMetaFalseMap.containsKey(e.getEventName())) &&
                        (commonAttrMap.containsKey(e.getEventAttr()) || attrMetaMap.containsKey(e.getEventAttr()))) {
                    if (eventMap.containsKey(e.getEventName())) {
                        List<Event> list = eventMap.get(e.getEventName());
                        list.add(e);
                        eventMap.put(e.getEventName(), list);
                    } else {
                        List<Event> list = new ArrayList<>();
                        list.add(e);
                        eventMap.put(e.getEventName(), list);
                    }
                }
            }
        }

        //事件显示属性
        List<EventAttr4Web> firstLevelAttr = new ArrayList<>();
        List<EventAttr4Web> secondLevelAttr = new ArrayList<>();
        setEventViewAttrList(firstLevelAttr, secondLevelAttr);

        Set<String> set = eventMap.keySet();
        if (ValidateUtil.isValid(set)) {
            for (String eventName : set) {
                List<EventAttr4Web> arrList = new ArrayList<>();
                Event4Web ew = new Event4Web();
                ew.setEventName(eventName);
                ew.setFirstLevelAttr(firstLevelAttr);
                ew.setProfiles(arrList);
                ew.setSecondLevelAttr(new ArrayList<EventAttr4Web>());
                if (commonEventMap.containsKey(eventName)) {
                    CommonEvent commonEvent = commonEventMap.get(eventName);
                    ew.setEventNameAlias(commonEvent.getAlias());
                } else if (eventMetaTrueMap.containsKey(eventName)) {
                    EventMeta eventMeta = eventMetaTrueMap.get(eventName);
                    ew.setEventNameAlias(eventMeta.getAlias() == null ? eventName : eventMeta.getAlias());
                } else {
                    ew.setEventNameAlias(eventName);
                }

                List<Event> list = eventMap.get(eventName);
                for (Event e : list) {
                    String eventAttr = e.getEventAttr();
                    if (commonAttrMap.containsKey(eventAttr)) {
                        CommonParam commonParam = commonAttrMap.get(eventAttr);
                        EventAttr4Web eaw = new EventAttr4Web();
                        eaw.setAttr(eventAttr);
                        eaw.setAttrAlias(commonParam.getAlias());
                        eaw.setSortId(commonParam.getSortId());
                        eaw.setDataType(e.getDataType());
                        //填充渠道
                        if (EVENT_ATTR_CID.equals(eventAttr)) {
                            eaw.setWebType("string");
                        }
                        List<EventAttr4Web> profiles = ew.getProfiles();
                        profiles.add(eaw);
                        ew.setProfiles(profiles);
                    } else {
                        EventAttributeMeta meta = attrMetaMap.get(eventAttr);

                        if (meta.getAddStatsCondition()) {
                            EventAttr4Web eaw = new EventAttr4Web();
                            eaw.setAttr(eventAttr);
                            eaw.setDataType(e.getDataType());
                            eaw.setAttrAlias(meta.getAlias() == null ? eventAttr : meta.getAlias());

                            List<EventAttr4Web> profiles = ew.getProfiles();
                            profiles.add(eaw);
                            ew.setProfiles(profiles);
                        }
                        if (meta.getAddStatsView()) {
                            EventAttr4Web eaw = new EventAttr4Web();
                            eaw.setAttr(eventAttr);
                            eaw.setDataType(e.getDataType());
                            eaw.setType("custom");
                            eaw.setAttrAlias(meta.getAlias() == null ? eventAttr : meta.getAlias());

                            List<EventAttr4Web> first = ew.getFirstLevelAttr();
                            first.add(eaw);
                            ew.setFirstLevelAttr(first);

                            ew.setSecondLevelAttr(secondLevelAttr);
                        }
                    }

                }
                List<EventAttr4Web> profiles1 = ew.getProfiles();
                TreeMap<Integer, EventAttr4Web> map = new TreeMap<>();
                LinkedList<EventAttr4Web> common = new LinkedList<>();
                List<EventAttr4Web> temp = new ArrayList<>();
                if (ValidateUtil.isValid(profiles1)) {
                    for (EventAttr4Web e : profiles1) {
                        if (e.getSortId() != 0) {
                            map.put(e.getSortId(), e);
                        } else {
                            temp.add(e);
                        }
                    }
                }
                if (ValidateUtil.isValid(map)) {
                    for (Integer i : map.keySet()) {
                        common.add(map.get(i));
                    }
                }
                common.addAll(temp);
                ew.setProfiles(common);
                valueEventMap.put(ew.getEventName(),ew);

            }
        }

        Map<String, Map<String, Map<String, List>>> valMap = new HashMap<>();
        if (ValidateUtil.isValid(params)) {
            JSONArray arr = new JSONArray(params);
            if(ValidateUtil.isValid(arr)){
                for(int i =0 ; i< arr.length(); i++){
                    String event = arr.getJSONObject(i).getString("event");
                    JSONArray param = arr.getJSONObject(i).getJSONArray("param");
                    if (ValidateUtil.isValid(param)) {
                        for (int j = 0; j < param.length(); j++) {
                            String attr = param.getString(j);
                            Map<String, List> map = listAllValue(app, event, attr);
                            if (valMap.containsKey(event)) {
                                Map<String, Map<String, List>> attrMap = valMap.get(event);
                                attrMap.put(attr, map);
                                valMap.put(event, attrMap);
                            } else {
                                Map<String, Map<String, List>> attrMap = new HashMap<>();
                                attrMap.put(attr, map);
                                valMap.put(event, attrMap);
                            }
                        }
                    }
                }
            }
        }

        if (ValidateUtil.isValid(valueEventMap)) {
            for (String eventName : valueEventMap.keySet()) {
                if (valMap.containsKey(eventName)) {
                    Map<String, Map<String, List>> map = valMap.get(eventName);
                    Event4Web event4Web = valueEventMap.get(eventName);
                    LinkedList<EventAttr4Web> profiles = (LinkedList<EventAttr4Web>) event4Web.getProfiles();
                    LinkedList<EventAttr4Web> profilesNew = new LinkedList<>();
                    if (ValidateUtil.isValid(profiles)) {
                        for (EventAttr4Web ea : profiles) {
                            if (map.containsKey(ea.getAttr())) {
                                Map<String, List> map1 = map.get(ea.getAttr());
                                if (map1.containsKey("key")) {
                                    ea.setKey(map1.get("key"));
                                }
                                ea.setValue(map1.get("value"));
                                profilesNew.add(ea);
                            } else {
                                profilesNew.add(ea);
                            }
                        }
                    }
                    event4Web.setProfiles(profilesNew);
                    resultList.add(event4Web);
                } else {
                    resultList.add(valueEventMap.get(eventName));
                }
            }
        }
        //没有属性 另行处理
        if (!ValidateUtil.isValid(resultList)) {
            if (ValidateUtil.isValid(events)) {
                List<String> name = new ArrayList<>();
                for (Event e : events) {
                    if(!name.contains(e.getEventName())){
                        EventAttr4Web eaw = new EventAttr4Web();
                        Event4Web ew = new Event4Web();
                        ew.setEventName(e.getEventName());
                        ew.setFirstLevelAttr(firstLevelAttr);
                        ew.setProfiles(new ArrayList<>());
                        ew.setSecondLevelAttr(new ArrayList<EventAttr4Web>());
                        if (commonEventMap.containsKey(e.getEventName())) {
                            CommonEvent commonEvent = commonEventMap.get(e.getEventName());
                            ew.setEventNameAlias(commonEvent.getAlias());
                        } else if (eventMetaTrueMap.containsKey(e.getEventName())) {
                            EventMeta eventMeta = eventMetaTrueMap.get(e.getEventName());
                            ew.setEventNameAlias(eventMeta.getAlias() == null ? e.getEventName() : eventMeta.getAlias());
                        } else {
                            ew.setEventNameAlias(e.getEventName());
                        }
                        resultList.add(ew);
                        name.add(ew.getEventName());
                    }

                }
            }

        }

        return resultList;
    }

    @Override
    public Map<String, List> listAllValue(Long app, String eventName, String attrName) {
        Map<String, List> result = new HashMap<>();

        String appKey = appRepository.findAppkeyById(app);
        Event event = eventRepository.findNumberAttrByEventAttr(appKey, attrName, eventName);
        if (event != null) {
            List<Event> byAppkey = eventRepository.findByAppkey(appKey);


//            String key = appKey+","+eventName+","+attrName+","+event.getDataType()+","+(event.isCommon() ? "1" : "0");
            String key = String.format("%s,%s,%s,%s,%s", appKey, eventName, attrName, event.getDataType(), (event.isCommon() ? "1" : "0"));
            Set<String> set = (Set<String>) EventRedisUtil.getInstance().get(key);
            set.add("6043");
            if (ValidateUtil.isValid(set)) {
                List<String> list = new ArrayList<>();
                for (String s : set) {
                    list.add(s);
                }

                if (attrName.equals("_cid") || attrName.equals("_campaignid")) {
                    String values = String.join(",", set);
                    String url = Constant.trackingUrl + "/api/"+ app +"/event/find/valuespecail?attrName=" + attrName + "&values=" + values;
                    try {
                        String response = HttpClientUtil.doHttpGetRequest(url, "io");
                        if (!StringUtil.isEmpty(response)) {
                                JSONObject ob = new JSONObject(response);
                                JSONObject content = ob.getJSONObject("content");
                                ObjectMapper mapper = new ObjectMapper();
                                result = mapper.readValue(content.toString(), Map.class);
                        } else {
                            result.put("value", list);
                        }
                    } catch (Exception e) {
                        result.put("value", list);
                    }
                } else {
                    result.put("value", list);
                }
            }
        }
        return result;
    }

    @Override
    public Map<String, List> listAllValueByAttr(Long appId, String attrName) {

        Map<String, List> result = new LinkedHashMap<>();

        if (!"usergroup".equals(attrName)) {
            String appKey = appRepository.findAppkeyById(appId);
            Event event = eventRepository.findOneEventByAttr(appKey, attrName);
            List<Event> eventList = eventRepository.findAllEventByAppKey(appKey);

            String commonEvent = (event.isCommon() ? "1" : "0");

            //生成redis的KEY LIST
            List<String> keyList = new ArrayList<>();
            for (Event e : eventList) {
                String key = String.format("%s,%s,%s,%s,%s", appKey, e.getEventName(), attrName, event.getDataType(), commonEvent);
                keyList.add(key);
            }

            //获取结果集
            Set<String> set = EventRedisUtil.getInstance().getZsetByKeys(keyList);

            if (!CollectionUtils.isEmpty(set)) {

                List<String> valueList = new ArrayList<>(set);
                if (attrName.equals("_cid") || attrName.equals("_campaignid")) {
                    String values = String.join(",", set);
                    String url = Constant.trackingUrl + "/api/"+ appId +"/event/find/valuespecail?attrName=" + attrName + "&values=" + values;
                    String response = HttpClientUtil.doHttpGetRequest(url, "io");
                    if (!StringUtil.isEmpty(response)) {
                        try {
                            JSONObject ob = new JSONObject(response);
                            JSONObject content = ob.getJSONObject("content");
                            ObjectMapper mapper = new ObjectMapper();
                            result = mapper.readValue(content.toString(), Map.class);

                        } catch (Exception e) {
                            result.put("value", valueList);
                        }
                    } else {
                        result.put("value", valueList);
                    }
                } else {
                    result.put("value", valueList);
                }


            }

        } else {

            //查询用户群
            List<UserGroup> userGroupList = usergroupService.list(appId);

            List<Long> keyList = new ArrayList<>();
            List<String> valueList = new ArrayList<>();

            for (UserGroup userGroup : userGroupList) {
                keyList.add(userGroup.getId());
                valueList.add(userGroup.getName());
            }

            result.put("key", keyList);
            result.put("value", valueList);
        }


        return result;
    }

    @Override
    public Map<String, List> listAllValueByAttrTop50(Long appId, String attrName) {
        Map<String, List> stringListMap = listAllValueByAttr(appId, attrName);
        LinkedHashMap<String, List> result = new LinkedHashMap<>();
        int i = 0;
        for (String s : stringListMap.keySet()) {
            result.put(s, stringListMap.get(s));
            if (i == 50) break;
            i++;
        }
        return result;
    }

    @Override
    public Map<String, Map<String, List>> listAllValueByAttrs(Long app, String attrNames) {
        Map<String, Map<String, List>> result = new HashMap<>();
        if (null != attrNames) {
            String[] attrArr = attrNames.split(",");
            for (int i = 0; i < attrArr.length; i++) {
                Map<String, List> map = listAllValueByAttr(app, attrArr[i]);
                result.put(attrArr[i], map);
            }
        }

        return result;
    }


    /**
     * 获取显示属性一二级菜单
     * 填充传入参数firstLevelAttr,secondLevelAttr
     * created by sunhao 2017-04-19
     */
    private void setEventViewAttrList(List<EventAttr4Web> firstLevelAttr, List<EventAttr4Web> secondLevelAttr) {

        //公共属性
        List<EventViewAttr> eventViewAttrList = eventViewAttrRepository.findEventViewAttr();
        //分离第一二级属性
        for (EventViewAttr eventViewAttr : eventViewAttrList) {

            EventAttr4Web eventAttr4Web = new EventAttr4Web();

            eventAttr4Web.setAttr(eventViewAttr.getViewAttr());
            eventAttr4Web.setAttrAlias(eventViewAttr.getViewAttrName());
            eventAttr4Web.setDataType(eventViewAttr.getAttrType());

            //默认属性
            if (VIEW_ATTR_DEFAULT == eventViewAttr.getAttrLevel()) {

                eventAttr4Web.setType(ATTR_TYPE_DEFAULT);
                firstLevelAttr.add(eventAttr4Web);

            } else if (VIEW_ATTR_CUSTOM == eventViewAttr.getAttrLevel()) {

                secondLevelAttr.add(eventAttr4Web);
            }
        }
    }


    @Override
    public List<Dimension4Web> listAllAttr(Long app) {
        List<Dimension4Web> dimension4WebList = new ArrayList<>();
        Map<String, Event> eventAttrMap = new HashMap<>();

        String appKey = appRepository.findAppkeyById(app);
        List<Event> eventList = eventRepository.listCommonByApp(appKey);
        List<CommonParam> commonParamList = this.commonParamService.listAllByType(null);

        if (ValidateUtil.isValid(eventList)) {
            for (Event event : eventList) {
                if (!eventAttrMap.containsKey(event.getEventAttr())) {
                    eventAttrMap.put(event.getEventAttr(), event);
                }
            }
        }

        if (ValidateUtil.isValid(commonParamList) && ValidateUtil.isValid(eventAttrMap)) {
            dimension4WebList = buildDimensionForWebAllAttr(eventAttrMap, commonParamList, dimension4WebList, app);
        }

        return dimension4WebList;
    }

    /**
     * 获取分类维度(通用事件属性)
     */
    @SuppressWarnings("deprecation")
    @Override
    public List<Dimension4Web> listValues(Long app) {

        List<Dimension4Web> dimension4WebList = new ArrayList<>();
        Map<String, Event> eventAttrMap = new HashMap<>();

        String appKey = appRepository.findAppkeyById(app);
        List<Event> eventList = eventRepository.listCommonByApp(appKey);
        List<CommonParam> commonParamList = this.commonParamService.listAllByType("event");

        //构建eventAttrMap,聚合value
        if (ValidateUtil.isValid(eventList)) {
            for (Event event : eventList) {

                if (!eventAttrMap.containsKey(event.getEventAttr())) {

                    eventAttrMap.put(event.getEventAttr(), event);

                }
            }
        }

        //对属性排序
        if (ValidateUtil.isValid(commonParamList) && ValidateUtil.isValid(eventAttrMap)) {

            //生成结果jason
            dimension4WebList = buildDimensionForWeb(eventAttrMap, commonParamList, dimension4WebList, app);
        }

        return dimension4WebList;
    }

    @Override
    public List<EventAttr4Web> listCommonProperties(Long app, String propertiesType) {

        List<EventAttr4Web> commonProperties = new ArrayList<>();

        Map<String, Event> eventAttrMap = new HashMap<>();

        String appKey = appRepository.findAppkeyById(app);
        List<Event> eventList = eventRepository.listCommonByApp(appKey);
        List<CommonParam> commonParamList = this.commonParamService.listAllByType(propertiesType);

        //构建eventAttrMap,聚合value
        if (ValidateUtil.isValid(eventList)) {

            for (Event event : eventList) {

                if (!eventAttrMap.containsKey(event.getEventAttr())) {

                    eventAttrMap.put(event.getEventAttr(), event);

                }
            }
        }

        //构建通用属性
        if (ValidateUtil.isValid(commonParamList) && ValidateUtil.isValid(eventAttrMap)) {
            commonProperties = buildEventAttrForWeb(eventAttrMap, commonParamList);
        }

        return commonProperties;
    }

    @Override
    public List<CommonParam> listCommonGroupProperties() {
        return this.commonParamService.listAllByType(null);
    }

    /**
     * 通过event名称和appkey获取attribute meta list
     *
     * @param eventName
     * @param appId
     * @return
     */
    @Override
    public List<EventAttr4Web> listAllEventAttribute(String eventName, Long appId) {

        Map<String, EventAttr4Web> eventAttr4WebMap = new HashMap<>();

        List<Event> eventAttrList = new ArrayList<>();

        String appKey = appRepository.findAppkeyById(appId);

        if (eventName.startsWith("vir_")) {

            List<String> eventList = virtualEventService.findVirtualEventList(eventName);
            eventAttrList = eventRepository.findEventAliasByEvent(appKey, eventList);

        } else {

            eventAttrList = this.eventRepository.findByEventName(appKey, eventName);
        }

        if (!CollectionUtils.isEmpty(eventAttrList)) {

            List<EventAttributeMeta> attrMetaList = eventAttributeMetaRepository.findByAppkeyAndCondition(appKey);

            Map<String, EventAttributeMeta> attributeMetaMap = Maps.uniqueIndex(attrMetaList, new Function<EventAttributeMeta, String>() {
                @Override
                public String apply(EventAttributeMeta eventAttributeMeta) {
                    return eventAttributeMeta.getAttribute();
                }
            });

            Map<String, CommonParam> commonAttrMap = commonParamService.findAllByType("event");
            int m = 0;
            int n = 20;

            for (Event event : eventAttrList) {

                String attr = event.getEventAttr();

                //属性排重
                if (!eventAttr4WebMap.containsKey(attr)) {

                    EventAttr4Web eventAttr4Web = new EventAttr4Web();
                    eventAttr4Web.setAttr(attr);
                    eventAttr4Web.setDataType(event.getDataType());

                    //属性别名
                    String attrAlias = "";
                    int sortId = 0;
                    if (event.isCommon()) {
                        attrAlias = commonAttrMap.containsKey(attr) ? commonAttrMap.get(attr).getAlias() : attrAlias;
                        sortId = commonAttrMap.containsKey(attr) ? commonAttrMap.get(attr).getSortId() : m;
                        m++;
                    } else {
                        attrAlias = attributeMetaMap.containsKey(attr) ? attributeMetaMap.get(attr).getAlias() : attr;
                        sortId = n;
                        n++;
                    }

                    eventAttr4Web.setAttrAlias(StringUtils.isEmpty(attrAlias) ? attr : attrAlias);
                    eventAttr4Web.setSortId(sortId);

                    //CID特殊处理
                    if (EVENT_ATTR_CID.equals(attr)) {
                        eventAttr4Web.setWebType("string");
                    }

                    eventAttr4WebMap.put(attr, eventAttr4Web);
                }

            }
        }

        return Lists.newArrayList(eventAttr4WebMap.values());
    }

    @Override
    public List<ComplicatedParam> findAllComplicatedPatram() {
        return complicatedParamRepository.findAllParam();
    }

    private List<EventAttr4Web> buildEventAttrForWeb(Map<String, Event> eventAttrMap, List<CommonParam> commonParamList) {

        List<EventAttr4Web> eventAttr4WebList = new ArrayList<>();

        //用户群
        EventAttr4Web userGroupAttr = new EventAttr4Web();
        userGroupAttr.setAttr("usergroup");
        userGroupAttr.setAttrAlias("用户分群");
        userGroupAttr.setDataType("number");
        userGroupAttr.setWebType("string");
        userGroupAttr.setAttrAlias("usergroup");

        eventAttr4WebList.add(userGroupAttr);

        //通用属性
        for (CommonParam commonParam : commonParamList) {

            EventAttr4Web eventAttr4Web = new EventAttr4Web();

            eventAttr4Web.setAttr(commonParam.getParam());
            eventAttr4Web.setAttrAlias(commonParam.getAlias());
            eventAttr4Web.setType(commonParam.getType());

            Event eve = eventAttrMap.get(commonParam.getParam());
            if (eve != null) {
                //数据类型
                eventAttr4Web.setDataType(eve.getDataType());
            }

            //填充渠道
            if (EVENT_ATTR_CID.equals(commonParam.getParam())) {
                eventAttr4Web.setWebType("string");
            }

            eventAttr4WebList.add(eventAttr4Web);
        }

        return eventAttr4WebList;
    }

    /**
     * 生成分类维度页面显示列表
     */
    private List<Dimension4Web> buildDimensionForWeb(Map<String, Event> eventAttrMap, List<CommonParam> commonParamList,
                                                     List<Dimension4Web> dimension4WebList, Long app) {

        for (CommonParam commonParam : commonParamList) {

            Dimension4Web dimension4Web = new Dimension4Web();

            //替换通用事件属性的名称
            dimension4Web.setName(commonParam.getAlias());
            dimension4Web.setDimensionType(commonParam.getDimension());

            Event eve = eventAttrMap.get(commonParam.getParam());
            if (eve != null) {
                //数据类型
                dimension4Web.setType(eve.getDataType());
            }

            //设置ID和属性值列表
            dimension4Web.setId(commonParam.getParam());

            dimension4WebList.add(dimension4Web);
        }
        List<UserGroup> list = usergroupService.list(app);
        if (!list.isEmpty()) {
            Dimension4Web dimension4Web = new Dimension4Web();
            dimension4Web.setId("usergroup");
            List<Long> keys = new ArrayList<>();
            List<String> values = new ArrayList<>();
            for (UserGroup ug : list) {
                keys.add(ug.getId());
                values.add(ug.getName());
            }

            dimension4Web.setKey(keys);
            dimension4Web.setValue(values);
            dimension4Web.setName("用户分群");
            dimension4Web.setType("number");
            dimension4Web.setDimensionType("usergroup");
            dimension4WebList.add(0, dimension4Web);
        }

        return dimension4WebList;
    }

    /**
     * @param eventAttrMap
     * @param commonParamList
     * @param dimension4WebList
     * @param app
     * @return 漏斗转化列出所有的事件通用属性和用户通用属性以及用户分群
     */
    private List<Dimension4Web> buildDimensionForWebAllAttr(Map<String, Event> eventAttrMap, List<CommonParam> commonParamList,
                                                            List<Dimension4Web> dimension4WebList, Long app) {

        for (CommonParam commonParam : commonParamList) {

            Dimension4Web dimension4Web = new Dimension4Web();
            dimension4Web.setEventType(commonParam.getType());
            dimension4Web.setSortId(commonParam.getSortId());
            dimension4Web.setName(commonParam.getAlias());
            dimension4Web.setDimensionType(commonParam.getDimension());

            //设置数据类型
            if ("event".equals(commonParam.getType())) {
                Event eve = eventAttrMap.get(commonParam.getParam());
                if (eve != null) {
                    dimension4Web.setType(eve.getDataType());
                }
            } else {
                dimension4Web.setType(commonParam.getDataType());
            }
            //设置ID和属性值列表
            dimension4Web.setId(commonParam.getParam());

            dimension4WebList.add(dimension4Web);
        }
        List<UserGroup> list = usergroupService.list(app);
        if (!list.isEmpty()) {
            List<Long> keys = new ArrayList<>();
            List<String> values = new ArrayList<>();
            Dimension4Web dimension4Web = new Dimension4Web();
            dimension4Web.setId("usergroup");
            for (UserGroup ug : list) {
                keys.add(ug.getId());
                values.add(ug.getName());
            }
            dimension4Web.setKey(keys);
            dimension4Web.setValue(values);
            dimension4Web.setName("用户分群");
            dimension4Web.setType("number");
            dimension4Web.setDimensionType("usergroup");
            dimension4WebList.add(0, dimension4Web);
        }
        return dimension4WebList;
    }


    /**
     * _campaignid 获取活动名称列表
     * add by sunhao 2017-04-06
     *//*
    private List<String> getCampaignNameList(List<String> campaignKeyList) {

        List<String> nameList = new ArrayList<>();

        Map<String, Campaign> campaignMap = new HashMap<>();

        List<Campaign> campaignList = campaignRepository.findAllByCampaignId(campaignKeyList);

        campaignList.add(new Campaign("_default_", "自然量"));

        if (!CollectionUtils.isEmpty(campaignList)) {
            campaignMap = Maps.uniqueIndex(campaignList, new Function<Campaign, String>() {
                @Override
                public String apply(Campaign campaign) {
                    return campaign.getCampaignid();
                }
            });
        }

        //填充values
        for (String campaignid : campaignKeyList) {

            if (campaignMap.containsKey(campaignid)) {
                nameList.add(campaignMap.get(campaignid).getName());
            } else {
                nameList.add(campaignid);
            }
        }

        return nameList;
    }*/



    /**
     * 查出所有的时间和属性
     */
    @Override
    public Map<String, List<String>> findAllEventWithAttr(Long appId) {

        Map<String, List<String>> resultMap = new HashMap<>();

        String appKey = appRepository.findAppkeyById(appId);
        List<Event> events = eventRepository.findByAppkey(appKey);
        List<EventMeta> eventMetaFalseList = eventMetaRepository.findByAppkeyAndStatusIsFalse(appKey);
        List<EventAttributeMeta> attrMetaList = eventAttributeMetaRepository.findByAppkeyAndCondition(appKey);
        Map<String, CommonParam> commonAttrMap = commonParamService.findAllByType("event");

        Map<String, EventMeta> eventMetaFalseMap = new HashMap<>();
        if (ValidateUtil.isValid(eventMetaFalseList)) {
            for (EventMeta e : eventMetaFalseList) {
                eventMetaFalseMap.put(e.getEventId(), e);
            }
        }

        Map<String, EventAttributeMeta> attrMetaMap = new HashMap<>();
        if (ValidateUtil.isValid(attrMetaList)) {
            for (EventAttributeMeta e : attrMetaList) {
                attrMetaMap.put(e.getAttribute(), e);
            }
        }

        if (ValidateUtil.isValid(events)) {
            for (Event e : events) {
                String event = e.getEventName();
                String attr = e.getEventAttr();
                if (!eventMetaFalseMap.containsKey(event)) {
                    if (attrMetaMap.containsKey(attr) || commonAttrMap.containsKey(attr)) {
                        if (resultMap.containsKey(event)) {
                            List<String> list = resultMap.get(event);
                            list.add(attr);
                            resultMap.put(event, list);
                        } else {
                            List<String> list = new ArrayList<>();
                            list.add(attr);
                            resultMap.put(event, list);
                        }
                    }
                }

            }
        }

        return resultMap;
    }


    /**
     * 查询所有的事件以及名字,排重后
     */
    @Override
    public List<Event4Web> listAllEvent(Long app) {

        List<Event4Web> result = new ArrayList<>();

        List<Event4Web> event4Webs = listEvent(app);
        if (ValidateUtil.isValid(event4Webs)) {
            for (Event4Web e : event4Webs) {
                if (e.getStatus()) {
                    result.add(e);
                }
            }
        }
        return result;
    }

    @Override
    public List<Event4Web> listAllEventToCallback(Long app) {
        List<Event4Web> result = new ArrayList<>();

        List<Event4Web> event4Webs = listEvent(app);
        if (ValidateUtil.isValid(event4Webs)) {
            for (Event4Web e : event4Webs) {
                if (e.getStatus() && !e.getEventName().equals("reged")
                        && !e.getEventName().equals("loggedin") && !e.getEventName().equals("payment")) {
                    result.add(e);
                }
            }
        }
        return result;
    }

    private Event4Web eventMetaTo4Web(EventMeta e) {
        Event4Web ew = new Event4Web();
        ew.setCommon(false);
        ew.setEventName(e.getEventId());
        ew.setEventNameAlias(e.getAlias() == null ? e.getEventId() : e.getAlias());
        ew.setStatus(e.getStatus());

        return ew;
    }

    private Event4Web eventTo4Web(Event e) {
        Event4Web ew = new Event4Web();
        ew.setCommon(false);
        ew.setEventName(e.getEventName());
        ew.setEventNameAlias(e.getEventName());
        ew.setStatus(true);
        return ew;
    }

    public Event4Web commonEventTo4Web(CommonEvent e) {
        Event4Web ew = new Event4Web();
        ew.setCommon(true);
        ew.setEventName(e.getEvent());
        ew.setEventNameAlias(e.getAlias());
        ew.setStatus(true);
        return ew;
    }
}
