package com.gitee.sop.admin.service.doc;

import com.alibaba.fastjson2.JSON;
import com.gitee.fastmybatis.core.util.TreeUtil;
import com.gitee.sop.admin.common.constants.YesOrNo;
import com.gitee.sop.admin.common.exception.BizException;
import com.gitee.sop.admin.common.support.ServiceSupport;
import com.gitee.sop.admin.common.util.CopyUtil;
import com.gitee.sop.admin.dao.entity.DocApp;
import com.gitee.sop.admin.dao.entity.DocInfo;
import com.gitee.sop.admin.dao.mapper.DocAppMapper;
import com.gitee.sop.admin.dao.mapper.DocInfoMapper;
import com.gitee.sop.admin.service.doc.dto.DocInfoPublishUpdateDTO;
import com.gitee.sop.admin.service.doc.dto.DocInfoTreeDTO;
import com.gitee.sop.admin.service.doc.dto.torna.TornaDocInfoViewDTO;
import com.gitee.sop.admin.service.sys.SysUserService;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;


/**
 * @author 六如
 */
@Service
public class DocInfoService implements ServiceSupport<DocInfo, DocInfoMapper> {

    @Autowired
    private DocAppMapper docAppMapper;
    @Autowired
    private DocContentService docContentService;
    @Autowired
    private SysUserService sysUserService;

    public List<DocInfo> listChildDoc(Long parentId) {
        return this.list(DocInfo::getParentId, parentId);
    }

    public List<DocInfoTreeDTO> listDocTree(Long docAppId) {
        List<DocInfo> list = this.list(DocInfo::getDocAppId, docAppId);
        if (CollectionUtils.isEmpty(list)) {
            return new ArrayList<>(0);
        }
        Set<Long> userIds = list.stream().flatMap(docInfo -> Lists.newArrayList(docInfo.getAddBy(), docInfo.getUpdateBy()).stream())
                .filter(val -> val != null && val > 0)
                .collect(Collectors.toSet());
        List<DocInfoTreeDTO> docInfoTreeDTOS = CopyUtil.copyList(list, DocInfoTreeDTO::new);
        sysUserService.fillShowName(docInfoTreeDTOS);
        return TreeUtil.convertTree(docInfoTreeDTOS, 0L);
    }

    public int publish(DocInfoPublishUpdateDTO docInfoUpdateDTO) {
        DocInfo docInfo = this.getById(docInfoUpdateDTO.getId());
        Integer isPublish = docInfoUpdateDTO.getIsPublish();

        // 如果是文件夹,发布下面所有的文档
        int i;
        if (YesOrNo.yes(docInfo.getIsFolder())) {
            List<DocInfo> children = this.listChildDoc(docInfo.getDocId());
            Set<Long> ids = children.stream().map(DocInfo::getId).collect(Collectors.toSet());
            i = this.query()
                    .in(DocInfo::getId, ids)
                    .set(DocInfo::getIsPublish, isPublish)
                    .update();
        } else {
            // 发布单个文档
            i = this.query()
                    .eq(DocInfo::getId, docInfoUpdateDTO.getId())
                    .set(DocInfo::getIsPublish, isPublish)
                    .update();
        }

        // 发布一个接口自动发布所属应用
        Long docAppId = docInfo.getDocAppId();
        if (YesOrNo.yes(isPublish)) {
            docAppMapper.query()
                    .eq(DocApp::getId, docAppId)
                    .set(DocApp::getIsPublish, isPublish)
                    .update();
        } else {
            // 如果应用下的接口都未发布,应用也改成未发布
            long count = this.query()
                    .eq(DocInfo::getDocAppId, docAppId)
                    .eq(DocInfo::getIsFolder, YesOrNo.NO)
                    .eq(DocInfo::getIsPublish, YesOrNo.YES)
                    .getCount();
            if (count == 0) {
                docAppMapper.query()
                        .eq(DocApp::getId, docAppId)
                        .set(DocApp::getIsPublish, YesOrNo.NO)
                        .update();
            }
        }

        return i;
    }


    public TornaDocInfoViewDTO getDocDetail(Long id) {
        DocInfo docInfo = this.getById(id);
        if (docInfo == null || !YesOrNo.yes(docInfo.getIsPublish())) {
            throw new BizException("文档不存在");
        }
        String content = docContentService.getContent(docInfo.getId());
        return JSON.parseObject(content, TornaDocInfoViewDTO.class);
    }


}
