package com.reyun.service.impl;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.reyun.dic.VirtualEventType;
import com.reyun.model.Account;
import com.reyun.model.App;
import com.reyun.model.CommonEvent;
import com.reyun.model.Event4Web;
import com.reyun.model.EventMeta;
import com.reyun.model.VirtualEvent;
import com.reyun.repository.AppRepository;
import com.reyun.repository.CommonEventRepository;
import com.reyun.repository.EventMetaRepository;
import com.reyun.repository.VirtualEventRepository;
import com.reyun.service.CommonParamService;
import com.reyun.service.ConfigParamService;
import com.reyun.service.EventService;
import com.reyun.service.VirtualEventService;
import com.reyun.util.PinYinUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * Created by song on 2017/9/4.
 */
@Service
public class VirtualEventImpl implements VirtualEventService {

    private static final String H5_ACTIVE_DEFAULT_EVENT = "h5_default_event";
    private static final String NOT_H5_ACTIVE_DEFAULT_EVENT = "default_event";
    private static final String H5_APP_PLATFROM = "H5";
    private static final String ACTIVE_EVENT_ENG = "vir_active_event";
    private static final String ACTIVE_EVENT_CH = "活跃事件";
    private static final String PREFIX = "vir_";
    private static final String NOT_INCLUDE_EVENT = "install";


    @Autowired
    private VirtualEventRepository virtualEventRepository;

    @Autowired
    private ConfigParamService configParamService;

    @Autowired
    private EventMetaRepository eventMetaRepository;

    @Autowired
    CommonParamService commonParamService;

    @Autowired
    EventService eventService;

    @Autowired
    CommonEventRepository commonEventRepository;

    @Autowired
    AppRepository appRepository;


    @Override
    public List<VirtualEvent> findEventList(Long appId, Account account) {
        List<VirtualEvent> virtualEventList = virtualEventRepository.findEventListByAppIdAndType(appId, VirtualEventType.ACTIVEEVENT.getCode());

        String default_key;

        if (CollectionUtils.isEmpty(virtualEventList)) {
            String platform = appRepository.findPlatformByAppId(appId);
            if (platform.equals(H5_APP_PLATFROM)) {
                default_key = configParamService.getConfigParamByKey(H5_ACTIVE_DEFAULT_EVENT);
            } else {
                default_key = configParamService.getConfigParamByKey(NOT_H5_ACTIVE_DEFAULT_EVENT);
            }
            VirtualEvent virtualEvent = new VirtualEvent();
            virtualEvent.setName(ACTIVE_EVENT_ENG + appId);
            virtualEvent.setCh_name(ACTIVE_EVENT_CH);
            virtualEvent.setCreateAccount(account.getId());
            virtualEvent.setType(VirtualEventType.ACTIVEEVENT.getCode());
            virtualEvent.setCreateTime(new Date());
            virtualEvent.setModifyTime(new Date());
            virtualEvent.setAppId(appId);
            virtualEvent.setEventList(default_key);
            virtualEventRepository.save(virtualEvent);
        }

        List<VirtualEvent> eventList = virtualEventRepository.findEventListByAppId(appId);
        for (VirtualEvent virtualEvent : eventList) {
            String ev = virtualEvent.getEventList();
            String s = parseEventList(ev, appId);
            virtualEvent.setEventListName(s);
        }
        return eventList;
    }

    @Override
    public List<Event4Web> findActiveEventList(Long appId, Long activeEventId) {

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

        App app = appRepository.findOne(appId);
        VirtualEvent activeVirtualEvent = virtualEventRepository.findOne(activeEventId);
        String[] eventList = activeVirtualEvent.getEventList().split(",");
        List<String> eventArrayList = Lists.newArrayList(eventList);

        Map<String, EventMeta> eventMetaMap = new HashMap<>();

        List<EventMeta> eventMetaList = eventMetaRepository.findByEventIds(app.getAppkey(), eventArrayList);

        if (!CollectionUtils.isEmpty(eventMetaList)) {
            eventMetaMap = Maps.uniqueIndex(eventMetaList, new Function<EventMeta, String>() {
                @Override
                public String apply(EventMeta eventMeta) {
                    return eventMeta.getEventId();
                }
            });

            for (String event : eventArrayList) {
                Event4Web event4Web = new Event4Web();
                event4Web.setEventName(event);
                String alias = eventMetaMap.containsKey(event) ? eventMetaMap.get(event).getAlias() : event;
                event4Web.setEventNameAlias(StringUtils.isEmpty(alias) ? event : alias);
                resultList.add(event4Web);
            }
        }
        return resultList;
    }

    @Override
    public List<Event4Web> unselectedEvent(Long app) {
        List<Event4Web> event4Webs = eventService.listEvent(app);
        List<CommonEvent> commonEventList = commonEventRepository.findAll();
        Map<String, CommonEvent> commonEventMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(commonEventList)) {
            commonEventMap = Maps.uniqueIndex(commonEventList, new Function<CommonEvent, String>() {
                @Override
                public String apply(CommonEvent commonEvent) {
                    return commonEvent.getEvent();
                }
            });
        }

        HashSet<String> eventNameSet = new HashSet<>();
        LinkedList<Event4Web> temp = new LinkedList<>();
        for (Event4Web event4Web : event4Webs) {
            String eventName = event4Web.getEventName();
            eventNameSet.add(eventName);
            if (!NOT_INCLUDE_EVENT.equals(eventName)) {
                temp.add(event4Web);
            }
        }

        if(!appRepository.findPlatformByAppId(app).equals(H5_APP_PLATFROM)) {
            String configParamByKey = configParamService.getConfigParamByKey(NOT_H5_ACTIVE_DEFAULT_EVENT);
            String[] notSelect = configParamByKey.split(",");
            for (String un_event : notSelect) {
                if (!eventNameSet.contains(un_event)) {
                    CommonEvent commonEvent = commonEventMap.get(un_event);
                    EventServiceImpl eventService = new EventServiceImpl();
                    Event4Web event4Web = eventService.commonEventTo4Web(commonEvent);
                    temp.add(event4Web);
                }
            }
        }
        return temp;
    }

    private String parseEventList(String events, Long appId) {
        String[] eventList = events.split(",");
        List<String> eventArrayList = Lists.newArrayList(eventList);

        Map<String, EventMeta> eventMetaMap = new HashMap<>();
        App app = appRepository.findOne(appId);
        List<EventMeta> eventMetaList = eventMetaRepository.findByEventIds(app.getAppkey(), eventArrayList);
        if (!CollectionUtils.isEmpty(eventMetaList)) {
            eventMetaMap = Maps.uniqueIndex(eventMetaList, new Function<EventMeta, String>() {
                @Override
                public String apply(EventMeta eventMeta) {
                    return eventMeta.getEventId();
                }
            });
        }

        StringBuilder str = new StringBuilder();
        Map<String, CommonEvent> allCommonEvent = commonParamService.findAllCommonEvent();
        for (String event : eventArrayList) {
            if (eventMetaMap.containsKey(event) && !StringUtils.isEmpty(eventMetaMap.get(event).getAlias())) {
                str.append(eventMetaMap.get(event).getAlias()).append(",");
            } else {
                CommonEvent commonEvent = allCommonEvent.get(event);
                if (commonEvent != null) {
                    str.append(commonEvent.getAlias()).append(",");
                } else {
                    str.append(event).append(",");
                }
            }
        }
        str.deleteCharAt(str.length() - 1);
        return str.toString();
    }

    @Override
    public VirtualEvent updateEvent(Long appId, Account account, VirtualEvent virtualEvent) {
        VirtualEvent virEvent = virtualEventRepository.findOne(virtualEvent.getId());
        virEvent.setEventList(virtualEvent.getEventList());
        virEvent.setModifyTime(new Date());
        virEvent.setModifyAccount(account.getId());
        String type = virtualEvent.getType();
        if (type.equals(VirtualEventType.USERDEFINEDEVENT.getCode())) {
            virEvent.setCh_name(virtualEvent.getCh_name());
            String name_pingYin = PinYinUtil.getPingYin(PREFIX + virtualEvent.getCh_name().replace(" ", "") + "_" + appId);
            virEvent.setName(name_pingYin);
        }
        return virtualEventRepository.save(virEvent);
    }


    @Override
    public VirtualEvent userDefineVirtual(Long appId, VirtualEvent virtualEvent1, Account account) {
        String name_pingYin = PinYinUtil.getPingYin(PREFIX + virtualEvent1.getCh_name().replace(" ", "") + "_" + appId);
        VirtualEvent virtualEvent = new VirtualEvent();
        virtualEvent.setName(name_pingYin);
        virtualEvent.setCh_name(virtualEvent1.getCh_name().replace(" ", ""));
        virtualEvent.setCreateAccount(account.getId());
        virtualEvent.setType(VirtualEventType.USERDEFINEDEVENT.getCode());
        virtualEvent.setCreateTime(new Date());
        virtualEvent.setAppId(appId);
        virtualEvent.setEventList(virtualEvent1.getEventList());
        virtualEvent.setEnable(true);
        return virtualEventRepository.save(virtualEvent);
    }


    @Override
    public List<VirtualEvent> findCustomEventList(Long appId, Account loginAccount) {
        List<VirtualEvent> eventList = virtualEventRepository.findEventListByAppIdAndType(appId, VirtualEventType.USERDEFINEDEVENT.getCode());
        for (VirtualEvent virtualEvent : eventList) {
            String ev = virtualEvent.getEventList();
            String s = parseEventList(ev, appId);
            virtualEvent.setEventList(s);
        }
        return eventList;
    }

    @Override
    public List<VirtualEvent> enableEvent(Long id) {
        List<VirtualEvent> eventListById = virtualEventRepository.findEventListById(id);
        for (VirtualEvent virtualEvent : eventListById) {
            virtualEvent.setEnable(true);
        }
        return eventListById;
    }

    @Override
    public List<VirtualEvent> disableEvent(Long id) {
        List<VirtualEvent> eventListById = virtualEventRepository.findEventListById(id);
        for (VirtualEvent virtualEvent : eventListById) {
            virtualEvent.setEnable(false);
        }
        return eventListById;
    }

    /**
     * 查询虚拟事件
     * @param virtualEventId
     * @return
     */
    @Override
    public String findVirtualEvents(String virtualEventId) {

        String result = "";

        VirtualEvent virtualEvent = virtualEventRepository.findVirtualEventByEventId(virtualEventId);

        if(null != virtualEvent){
            result = "'" + virtualEvent.getEventList().replace(",", "','") + "'";
        }

        return result;
    }

    @Override
    public List<String> findVirtualEventList(String virtualEventId) {

        VirtualEvent virtualEvent = virtualEventRepository.findVirtualEventByEventId(virtualEventId);

        if(null != virtualEvent){
            return Arrays.asList(virtualEvent.getEventList().split(","));
        }

        return new ArrayList<String>();
    }

    @Override
    public VirtualEvent getVirtualEvent(String appKey, String eventChName) {
        return virtualEventRepository.findVirtualEventByChName(appKey, eventChName);
    }
}


