package com.mortals.xhx.module.site.service.impl;

import com.alibaba.fastjson.JSON;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.model.PageInfo;
import com.mortals.framework.service.impl.AbstractCRUDCacheServiceImpl;
import com.mortals.framework.util.StringUtils;
import com.mortals.xhx.common.code.PlatformTypeEnum;
import com.mortals.xhx.common.key.Constant;
import com.mortals.xhx.common.utils.SyncTreeSiteThread;
import com.mortals.xhx.feign.site.ISiteFeign;
import com.mortals.xhx.feign.user.IUserFeign;
import com.mortals.xhx.module.area.model.AreaEntity;
import com.mortals.xhx.module.area.model.AreaQuery;
import com.mortals.xhx.module.area.service.AreaService;
import com.mortals.xhx.module.site.dao.SiteDao;
import com.mortals.xhx.module.site.model.SiteEntity;
import com.mortals.xhx.module.site.model.SiteQuery;
import com.mortals.xhx.module.site.model.SiteTreeSelect;
import com.mortals.xhx.module.site.service.SiteService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.*;
import java.util.stream.Collectors;

/**
 * SiteService
 * 站点 service实现
 *
 * @author zxfei
 * @date 2022-01-12
 */
@Service("siteService")
@Slf4j
public class SiteServiceImpl extends AbstractCRUDCacheServiceImpl<SiteDao, SiteEntity, Long> implements SiteService {

    // private List<SiteTreeSelect> siteTreeList;
    /**
     * 根据用户id 暂存对应站点树 默认0为全站点树
     */
    private Map<Long, List<SiteTreeSelect>> siteTreeMap = new HashMap<>();

    @Autowired
    private AreaService areaService;
    @Autowired
    private IUserFeign userFeign;
    @Value("${platform.type:cloud}")
    private String platFormType;//版本，默认云服务版本
    @Autowired
    private ISiteFeign siteFeign;

    @Override
    protected void validData(SiteEntity entity, Context context) throws AppException {
        if (ObjectUtils.isEmpty(entity.getAreaCode())) {
            throw new AppException("区域编码不能为空！");
        }
        AreaEntity areaEntity = areaService.getCache(entity.getAreaCode());
        if (ObjectUtils.isEmpty(areaEntity)) {
            throw new AppException(String.format("区域不存在！区域编码：%s", entity.getAreaCode()));
        }
        super.validData(entity, context);
    }

    @Override
    protected void saveBefore(SiteEntity entity, Context context) throws AppException {
        List<SiteEntity> siteEntities = this.find(new SiteQuery().areaCode(entity.getAreaCode()));
        entity.setSiteCode(entity.getAreaCode() + Constant.SITE_SPLIT_MARK + StringUtils.lpad(siteEntities.size() + 1, Constant.SITE_CODE_NUM));
        super.saveBefore(entity, context);
    }

    @Override
    public List<SiteTreeSelect> siteTree(Context context) {
        Map<String, AreaEntity> areaMap = new HashMap<>();
        SiteQuery siteQuery = new SiteQuery();
        Set<String> siteSet = Arrays.stream(context.getUser().getSiteIds().split(",")).filter(f -> !f.equals("")).collect(Collectors.toSet());

        if (!ObjectUtils.isEmpty(siteSet)) {
            List<Long> siteIdList = siteSet.stream().map(Long::parseLong).collect(Collectors.toList());
            if (!ObjectUtils.isEmpty(siteIdList)) {
                siteQuery.idList(siteIdList);
            }
        }
        //查詢指定的站點ids
        List<SiteEntity> siteList = this.find(siteQuery);
        //turn to sitemap
        Map<String, SiteEntity> siteMap = siteList.parallelStream().collect(Collectors.toMap(x -> x.getSiteCode(), y -> y, (o, n) -> n));
        //遍历过滤站点树
        for (SiteEntity siteEntity : siteList) {
            AreaEntity areaEntity = areaService.getExtCache(siteEntity.getAreaCode());
            //根据区域添加父节点
            if (!ObjectUtils.isEmpty(areaEntity)
                    && !ObjectUtils.isEmpty(areaEntity.getPid())) {
                //递归查找父节点并添加
                areaMap.put(areaEntity.getAreaCode(), areaEntity);
                //递归
                recursionFn(areaMap, areaEntity);
            }
        }
        log.debug("rebuildAreaMap==>{}", JSON.toJSONString(areaMap));
        //areaMap 为当前站点相关区域树结构 已经剔除不必要的分支结构
        return buildSiteTreeSelect(areaMap, siteMap);
    }

    public List<SiteTreeSelect> buildSiteTreeSelect(Map<String, AreaEntity> areaMap, Map<String, SiteEntity> siteMap) {
        List<AreaEntity> areaList = areaMap.values().stream().collect(Collectors.toList());
        List<AreaEntity> returnList = new ArrayList<>();
        //区域id
        List<String> tempList = areaList.stream().map(AreaEntity::getIid).collect(Collectors.toList());
        for (AreaEntity areaEntity : areaList) {
            //查询当前区域列表中最顶级的节点 并构建树
            if (!tempList.contains(areaEntity.getPid())) {
                recursion(areaList, areaEntity);
                returnList.add(areaEntity);
            }
        }
        //区域树
        if (returnList.isEmpty()) {
            returnList = areaList;
        }

        //构建站点树
        List<SiteTreeSelect> collect = returnList.parallelStream().map(item ->
                new SiteTreeSelect(item, siteMap)
        ).collect(Collectors.toList());
        //this.siteTreeList = collect;
        return collect;

    }

    private void recursion(List<AreaEntity> list, AreaEntity entity) {
        // 得到子节点列表
        List<AreaEntity> childList = getChildList(list, entity);
        entity.setChildren(childList);
        for (AreaEntity tChild : childList) {
            if (hasChild(list, tChild)) {
                recursion(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<AreaEntity> getChildList(List<AreaEntity> list, AreaEntity entity) {
        return list.stream()
                .filter(item -> item.getPid().equals(entity.getIid()))
                .collect(Collectors.toList());
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<AreaEntity> list, AreaEntity t) {
        return getChildList(list, t).size() > 0 ? true : false;
    }


    /**
     * 递归列表
     */
    private void recursionFn(Map<String, AreaEntity> areaMap, AreaEntity t) {
        // 得到父节点并加入
        AreaEntity areaEntity = areaService.selectOne(new AreaQuery().iid(t.getPid()));
        if (!ObjectUtils.isEmpty(areaEntity)) {
            areaMap.put(areaEntity.getAreaCode(), areaEntity);
            recursionFn(areaMap, areaEntity);
        }
    }


    @Override
    protected void updateAfter(SiteEntity entity, Context context) throws AppException {
        //刷新站点树
        new Thread(new SyncTreeSiteThread(this, context)).start();
        super.updateAfter(entity, context);
    }

    @Override
    protected void saveAfter(SiteEntity entity, Context context) throws AppException {
        //刷新站点树
        new Thread(new SyncTreeSiteThread(this, context)).start();
        super.saveAfter(entity, context);
    }


    @Override
    protected void removeAfter(Long[] ids, Context context, int result) throws AppException {
        new Thread(new SyncTreeSiteThread(this, context)).start();
        super.removeAfter(ids, context, result);
    }

    @Override
    public List<SiteTreeSelect> getSiteTree(Context context) {
        //判断是单机还是云
        List<SiteTreeSelect> siteTreeSelects =new ArrayList<>();
        if (platFormType.equalsIgnoreCase(PlatformTypeEnum.STANDALONE.getValue())) {
             siteTreeSelects = siteTreeMap.get(context.getUser().getId());
            //如果所属站点为空返回全节点树
            if (!ObjectUtils.isEmpty(siteTreeSelects)) {
                return siteTreeSelects;
            } else {
                return siteTreeMap.get(0);
            }
        }else{
            //云服务版本，获取站点树
           // siteFeign.siteTree()



        }

        return siteTreeSelects;
    }

    @Override
    public List<SiteEntity> getFlatSitesByAreaCode(String areaCode, Context context) {
        if (ObjectUtils.isEmpty(areaCode)) {
            throw new AppException("区域编码不能为空！");
        }
        AreaEntity areaEntity = areaService.getExtCache(areaCode);
        if (ObjectUtils.isEmpty(areaEntity)) {
            throw new AppException(String.format("区域不存在！区域编码：%s", areaCode));
        }
        String matchCode = areaCode.replaceAll("(0)+$", "");
        SiteQuery siteQuery = new SiteQuery();
        siteQuery.setAreaCode(matchCode+"%");
        List<SiteEntity> siteEntities = this.find(siteQuery);

        //List<SiteEntity> siteEntities = this.find(new SiteQuery()).stream().peek(site -> changeUrlPath(site)).collect(Collectors.toList());
//        for (SiteEntity siteEntity : siteEntities) {
//            boolean bool = getSite(areaCode, siteEntity.getAreaCode(), siteList, siteEntity);
//            if (bool) continue;
//        }
        return siteEntities;
    }

    @Override
    public List<SiteEntity> getFlatSitesBySiteId(Long siteId, Context context) {
        List<SiteEntity> siteList = new ArrayList<>();
        if (ObjectUtils.isEmpty(siteId)) {
            throw new AppException("站点Id不能为空！");
        }
        SiteEntity siteCache = this.getCache(siteId.toString());
        if (ObjectUtils.isEmpty(siteCache)) {
            throw new AppException("站点不存在，siteId:" + siteId);
        }
        AreaEntity areaEntity = areaService.getExtCache(siteCache.getAreaCode());
        if (ObjectUtils.isEmpty(areaEntity)) {
            throw new AppException(String.format("区域不存在！区域编码：%s", siteCache.getAreaCode()));
        }

        String matchCode = siteCache.getAreaCode().replaceAll("(0)+$", "");
        SiteQuery siteQuery = new SiteQuery();
        siteQuery.setAreaCode(matchCode+"%");
        List<SiteEntity> siteEntities = this.find(siteQuery);
//
//        List<SiteEntity> siteEntities = this.find(new SiteQuery()).stream().peek(site -> changeUrlPath(site)).collect(Collectors.toList());
//        ;
//        for (SiteEntity siteEntity : siteEntities) {
//            boolean bool = getSite(siteCache.getAreaCode(), siteEntity.getAreaCode(), siteList, siteEntity);
//            if (bool) continue;
//
//        }
        return siteEntities;
    }

    private boolean getSite(String rootAreaCode, String areaCode, List<SiteEntity> siteList, SiteEntity siteEntity) {
        // AreaEntity areaTemp = areaService.getExtCache(siteEntity.getAreaCode());
        if (rootAreaCode.equals(areaCode)) {
            siteList.add(siteEntity);
            //log.info("add site:{}", siteEntity.getSiteCode());
            return true;
        } else {
            AreaEntity areaTemp = areaService.getExtCache(areaCode);
            if (!ObjectUtils.isEmpty(areaTemp) && !ObjectUtils.isEmpty(areaTemp.getPid())) {
                //根据子节点查找父节点
                AreaEntity areaEntity = areaService.selectOne(new AreaQuery().iid(areaTemp.getPid()));
                if (!ObjectUtils.isEmpty(areaEntity)) {
                    return getSite(rootAreaCode, areaEntity.getAreaCode(), siteList, siteEntity);
                }
            }
            return false;
        }
    }

    @Override
    public void setSiteTree(List<SiteTreeSelect> list, Context context) {
        siteTreeMap.put(context.getUser().getId(), list);
    }

    @Override
    public void removeSiteTree(List<SiteTreeSelect> list, Context context) {
        siteTreeMap.remove(context.getUser().getId());
    }

    @Override
    public List<SiteEntity> getListAllInfoByQuery(SiteQuery query, Context context) throws AppException {
        List<SiteEntity> list = this.find(query, context);
        return list;
    }


    @Override
    protected void findAfter(SiteEntity params, PageInfo pageInfo, Context context, List<SiteEntity> list) throws AppException {
        list.stream().forEach(site -> changeUrlPath(site));
        super.findAfter(params, pageInfo, context, list);
    }

    @Override
    public void changeUrlPath(SiteEntity siteEntity) {

    }
}