package com.yeejoin.amos.knowledgebase.face.service;


import com.yeejoin.amos.knowledgebase.face.model.KnowledgeTagGroupModel;
import com.yeejoin.amos.knowledgebase.face.orm.dao.TagGroupMapper;
import com.yeejoin.amos.knowledgebase.face.orm.entity.KnowledgeTag;
import com.yeejoin.amos.knowledgebase.face.orm.entity.KnowledgeTagGroup;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.exception.BaseException;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.StringUtil;
import org.typroject.tyboot.core.foundation.utils.TreeBuilder;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.annotation.Condition;
import org.typroject.tyboot.core.rdbms.annotation.Operator;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.exception.instance.DataNotFound;
import org.typroject.tyboot.core.restful.exception.instance.RequestForbidden;

import java.util.*;


/**
 * <p>
 * 标签分组 服务类
 * </p>
 *
 * @author 子杨
 * @since 2020-08-05
 */
@Component
public class TagGroupService extends BaseService<KnowledgeTagGroupModel, KnowledgeTagGroup, TagGroupMapper> {

    public static final Long ROOT = 0L;

    @Autowired
    private TagService tagService;


    /**
     * @return com.yeejoin.amos.knowledgebase.face.model.KnowledgeTagGroupModel
     * @author 杨博超
     * @description 创建标签分类
     * @Param [groupModel]
     **/
    public KnowledgeTagGroupModel createGroup(KnowledgeTagGroupModel groupModel) {
        KnowledgeTagGroupModel oldModel = this.queryByGroupName(RequestContext.getAgencyCode(), groupModel.getGroupName());
        if (!ValidationUtil.isEmpty(oldModel)) {
            throw new BadRequest("分类名称已存在.");
        }
        groupModel.setAgencyCode(RequestContext.getAgencyCode());

        if (ValidationUtil.isEmpty(groupModel.getParentId())) {
            groupModel.setParentId(ROOT);
        }

        return this.createWithModel(groupModel);
    }


    /**
     * @return com.yeejoin.amos.knowledgebase.face.model.KnowledgeTagGroupModel
     * @author 杨博超
     * @description 更新分组.
     * @Param [groupModel]
     **/
    public KnowledgeTagGroupModel updateGroup(KnowledgeTagGroupModel groupModel) {

        KnowledgeTagGroupModel oldModel = this.queryBySeq(groupModel.getSequenceNbr());
        if (ValidationUtil.isEmpty(oldModel)) {
            throw new DataNotFound("找不到指定的分组.");
        }

        KnowledgeTagGroupModel oldModelByName = this.queryByGroupName(RequestContext.getAgencyCode(), groupModel.getGroupName());
        if (!ValidationUtil.isEmpty(oldModelByName) && !oldModelByName.getSequenceNbr().equals(oldModel.getSequenceNbr())) {
            throw new BadRequest("分类名称已存在.");
        }

        Bean.copyExistPropertis(groupModel, oldModel);
        return this.updateWithModel(oldModel);
    }


    /**
     * @return java.util.List<java.lang.Long>
     * @author 杨博超
     * @description 删除分类
     * @Param [ids]
     **/
    @Transactional(rollbackFor = {Exception.class, BaseException.class})
    public List<Long> deleteGroup(String ids) {
        List<Long> seqs = StringUtil.String2LongList(ids);
        for (Long seq : seqs) {
            KnowledgeTagGroupModel tagGroupModel = this.queryBySeq(seq);
            //所有子分类
            List<Long> childGroupSequenceList = getChildGroupSequenceList(tagGroupModel);
            List<KnowledgeTag> existTags = tagService.queryTagListWithGroup(seq, null, null, null);
            if (!ValidationUtil.isEmpty(existTags)) {
                throw new RequestForbidden("分组下存在标签，不允许删除！");
            }
            this.deleteBatchSeq(childGroupSequenceList);
        }
        return seqs;
    }

    private List<KnowledgeTagGroupModel> queryByParentId(Long parentId) {
        return this.queryForList("", false, parentId);
    }


    /**
     * @return com.yeejoin.amos.knowledgebase.face.model.KnowledgeTagGroupModel
     * @author 杨博超
     * @description 根据名称查询分类
     * @Param [groupName]
     **/
    public KnowledgeTagGroupModel queryByGroupName(String agencyCode, String groupName) {
        return this.queryModelByParams(agencyCode, groupName);
    }


    /**
     * @return java.util.Collection<com.yeejoin.amos.knowledgebase.face.model.KnowledgeTagGroupModel>
     * @author 杨博超
     * @description 查询标签分类树结构
     * @Param [agencyCode]
     **/
    public Collection<KnowledgeTagGroupModel> queryGroupTree(String agencyCode, @Condition(Operator.like) String groupName) {
        List<KnowledgeTagGroupModel> list = this.queryForList("GROUP_NAME", true, agencyCode, groupName);

        Map<Object, KnowledgeTagGroupModel> map = Bean.listToMap(list, "sequenceNbr", KnowledgeTagGroupModel.class);

        SortedSet<KnowledgeTagGroupModel> completeList = new TreeSet<>();
        for (KnowledgeTagGroupModel model : list) {
            completeList.addAll(buildWithParent(model, map));
        }
        return TreeBuilder.buildByRecursive(completeList, ROOT);
    }


    /**
     * @author 杨博超
     * @description 构建不完整的树
     * @Param [groupModel, map]
     * @return java.util.List<com.yeejoin.amos.knowledgebase.face.model.KnowledgeTagGroupModel>
     **/
    private List<KnowledgeTagGroupModel> buildWithParent(KnowledgeTagGroupModel groupModel, Map<Object, KnowledgeTagGroupModel> map) {

        List<KnowledgeTagGroupModel> completeList = new ArrayList<>();
        completeList.add(groupModel);

        if (groupModel.getParentId().equals(ROOT)) {
            completeList.add(groupModel);
            return completeList;
        }

        KnowledgeTagGroupModel parent = map.get(groupModel.getParentId());
        if (ValidationUtil.isEmpty(parent)) {
            parent = this.queryBySeq(groupModel.getParentId());

            if (ValidationUtil.isEmpty(parent)) {
                return completeList;
            }
        }
        completeList.add(parent);
        completeList.addAll(this.buildWithParent(parent, map));
        return completeList;
    }


    /**
     * 获取标签分组的所有子分组id
     *
     * @param parentTagGroupModel
     * @return
     */
    public List<Long> getChildGroupSequenceList(KnowledgeTagGroupModel parentTagGroupModel) {
        List<Long> sequenceList = new ArrayList<>();
        List<KnowledgeTagGroupModel> childList = new ArrayList<>();
        this.getAllChildList(parentTagGroupModel, childList);
        for (KnowledgeTagGroupModel tagGroupModel : childList) {
            sequenceList.add(tagGroupModel.getSequenceNbr());
        }
        return sequenceList;
    }

    private void getAllChildList(KnowledgeTagGroupModel currentTagGroupModel, List<KnowledgeTagGroupModel> resList) {
        if (null == currentTagGroupModel) {
            return;
        }
        Long parentId = currentTagGroupModel.getSequenceNbr();
        List<KnowledgeTagGroupModel> childList = queryByParentId(parentId);
        if (!childList.isEmpty()) {
            for (KnowledgeTagGroupModel tagGroupModel : childList) {
                this.getAllChildList(tagGroupModel, resList);
            }
        }
        resList.add(currentTagGroupModel);
    }

}
