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


import com.baomidou.mybatisplus.core.toolkit.Sequence;
import com.yeejoin.amos.knowledgebase.face.model.KnowledgeInteractionCountModel;
import com.yeejoin.amos.knowledgebase.face.orm.dao.InteractionCountMapper;
import com.yeejoin.amos.knowledgebase.face.orm.entity.KnowledgeInteractionCount;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
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.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;


/**
 * <p>
 * 知识库内容交互计数表 服务类
 * </p>
 *
 * @author 子杨
 * @since 2020-08-05
 */
@Component
public class InteractionCountService extends BaseService<KnowledgeInteractionCountModel, KnowledgeInteractionCount, InteractionCountMapper> {

    /*@Autowired
    private TagInstanceService tagInstanceService;*/
    @Autowired
    private Sequence sequence;

    /**
     * 统计方式-标签全部引用
     */
    public static final String QUOTE_TYPE_ALL = "ALL";
    /**
     * 统计方式-标签发布引用
     */
    public static final String QUOTE_TYPE_PUBLISH = "PUBLISH";

    /**
     * 统计目标类型-标签
     */
    public static final String QUOTE_ENTITY_TAG = "TAG";
    /**
     * 统计目标类型-文档
     */
    public static final String QUOTE_ENTITY_DOCUMENT = "DOCUMENT";

    /**
     * 获取统计数
     *
     * @param operateType 统计类型
     * @param entityType  关联对象类型
     * @param entityId    关联对象id
     * @return 数量
     */
    public int getOperateCount(String operateType, String entityType, String entityId) {
        KnowledgeInteractionCountModel model = queryByEntity(operateType, entityType, entityId);
        return ValidationUtil.isEmpty(model) ? 0 : model.getOperateCount();
    }

    /**
     * 文档引用总数改变
     *
     * @param tagSeq    标签id
     * @param changeNum 改变数量
     */
    /*public void changeOneDocumentCount(Long tagSeq, int changeNum) {
        KnowledgeInteractionCountModel countModel = queryByEntity(QUOTE_TYPE_ALL, QUOTE_ENTITY_DOCUMENT, tagSeq.toString());
        int count;
        if (ValidationUtil.isEmpty(countModel)) {
            count = changeNum;
        } else {
            count = countModel.getOperateCount() + changeNum;
        }
        updateOneCount(QUOTE_TYPE_ALL, QUOTE_ENTITY_DOCUMENT, tagSeq.toString(), count);
    }*/

    /*public void flushOneTagCountAll(Long tagSeq) {
        int count = tagInstanceService.queryCountByTagSeq(tagSeq);
        //更新
        updateOneCount(QUOTE_TYPE_ALL, QUOTE_ENTITY_TAG, tagSeq.toString(), count);
    }

    public void flushOneTagCountPublished(Set targets, Long tagSeq) {
        int count = tagInstanceService.countByTagSeqAndTargetSeqs(tagSeq, targets);
        //更新
        updateOneCount(QUOTE_TYPE_PUBLISH, QUOTE_ENTITY_TAG, tagSeq.toString(), count);
    }*/

    //刷新某个统计目标的引用数
    private void updateOneCount(String operateType, String entityType, String entityId, int count) {
        KnowledgeInteractionCountModel countModel = queryByEntity(operateType, entityType, entityId);
        if (ValidationUtil.isEmpty(countModel)) {
            countModel = new KnowledgeInteractionCountModel();
            countModel.setOperateType(operateType);
            countModel.setEntityType(entityType);
            countModel.setEntityId(entityId);
            countModel.setOperateCount(count);
            countModel.setAgencyCode(RequestContext.getAgencyCode());
            this.createWithModel(countModel);
        } else {
            countModel.setOperateCount(count);
            this.updateWithModel(countModel);
        }
    }

    private KnowledgeInteractionCountModel queryByEntity(String operateType, String entityType, String entityId) {
        List<KnowledgeInteractionCountModel> list = this.queryForTopList(1, null, false, operateType, entityType, entityId);
        if (list.isEmpty()) {
            return null;
        }
        return list.get(0);
    }

    /**
     * 获取总数前top个
     */
    public List<KnowledgeInteractionCountModel> queryTop(int top, String operateType, String entityType, String agencyCode) {
        return this.queryForTopList(top, "operate_count", false, operateType, entityType, agencyCode);
    }

    @Transactional(rollbackFor = {Exception.class, BaseException.class})
    public void deleteByEntity(String entityType, String entityId) {
        List<KnowledgeInteractionCountModel> countModels = this.queryForList(null, false, entityType, entityId);
        for (KnowledgeInteractionCountModel countModel : countModels) {
            this.deleteBySeq(countModel.getSequenceNbr());
        }
    }

    public void deleteAllTagQuote() {
        this.getBaseMapper().deleteByEntityType(QUOTE_ENTITY_TAG);
    }

    public List<KnowledgeInteractionCount> getAllTagQuoteRecords() {
        List<KnowledgeInteractionCount> resList = new ArrayList<>();
        List<KnowledgeInteractionCount> tagQuoteAll = this.getBaseMapper().queryTagQuoteAll();
        List<KnowledgeInteractionCount> tagQuotePublish = this.getBaseMapper().queryTagQuotePublish();
        resList.addAll(interactionCountList2ModelList(tagQuoteAll, QUOTE_ENTITY_TAG, QUOTE_TYPE_ALL));
        resList.addAll(interactionCountList2ModelList(tagQuotePublish, QUOTE_ENTITY_TAG, QUOTE_TYPE_PUBLISH));
        return resList;
    }

    private List<KnowledgeInteractionCount> interactionCountList2ModelList(List<KnowledgeInteractionCount> list, String entityType, String operateType) {
        Date now = new Date();
        List<KnowledgeInteractionCount> modelList = new ArrayList<>();
        if (!ValidationUtil.isEmpty(list)) {
            list.forEach(model -> {
                model.setSequenceNbr(sequence.nextId());
                model.setRecDate(now);
                model.setRecUserId("system");
                model.setEntityType(entityType);
                model.setOperateType(operateType);
            });
            modelList = list;
        }
        return modelList;
    }
}
