package com.microservices.pms.journals.service.impl;

import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.utils.DateUtils;
import com.microservices.common.security.utils.SecurityUtils;
import com.microservices.pms.common.service.IPmsCommonService;
import com.microservices.pms.journals.domain.PmsJournals;
import com.microservices.pms.journals.domain.vo.PmsJournalsChildrenDataVo;
import com.microservices.pms.journals.domain.vo.PmsJournalsParentDataVo;
import com.microservices.pms.journals.mapper.PmsJournalsMapper;
import com.microservices.pms.journals.service.IPmsJournalsService;
import com.microservices.pms.product.service.IPmsProductRequirementService;
import com.microservices.pms.project.service.IPmsProjectTestsheetCasesService;
import com.microservices.pms.utils.PmsConstants;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 评论功能Service业务层处理
 * 
 * @author otto
 * @date 2023-11-01
 */
@Service
public class PmsJournalsServiceImpl implements IPmsJournalsService 
{
    @Autowired
    private PmsJournalsMapper pmsJournalsMapper;
    @Autowired
    private IPmsProductRequirementService pmsProductRequirementService;
    @Autowired
    private IPmsCommonService pmsCommonService;
    @Autowired
    private IPmsProjectTestsheetCasesService pmsProjectTestsheetCasesService;

    /**
     * 查询评论功能
     * 
     * @param id 评论功能主键
     * @return 评论功能
     */
    @Override
    public PmsJournals selectPmsJournalsById(Long id)
    {
        PmsJournals pmsJournals= pmsJournalsMapper.selectPmsJournalsById(id);
        if(pmsJournals==null){
            throw new ServiceException("该评论不存在(评论Id[%d])",id);
        }
        if (PmsConstants.JOURNAL_TYPE_PRODUCT_REQUIREMENT.equals(pmsJournals.getJournalized_type())) {
            pmsProductRequirementService.selectPmsProductRequirementById(pmsJournals.getJournalized_id(), false);
        } else {
            //校验项目数据权限
        }
        return pmsJournals;
    }

    /**
     * 查询评论功能列表
     * 
     * @param pmsJournals 评论功能
     * @return 评论功能
     */
    @Override
    public List<PmsJournalsParentDataVo> selectPmsJournalsList(PmsJournals pmsJournals)
    {
        if (PmsConstants.JOURNAL_TYPE_PRODUCT_REQUIREMENT.equals(pmsJournals.getJournalized_type())) {
            pmsProductRequirementService.selectPmsProductRequirementById(pmsJournals.getJournalized_id(), false);
        } else {
            //校验项目数据权限
        }
        List<PmsJournals> partentPmsJournalsList=pmsJournalsMapper.selectPmsJournalsList(pmsJournals);
        return partentPmsJournalsList.stream().map(this::toPmsJournalsParentDataVo).collect(Collectors.toList());
    }

    private PmsJournalsParentDataVo toPmsJournalsParentDataVo(PmsJournals pmsJournals){
        PmsJournalsParentDataVo pmsJournalsParentDataVo=pmsJournals.toPmsJournalsParentDataVo();
        pmsJournalsParentDataVo.setUser(pmsCommonService.getSimpleGitlinkUserByGitlinkUserId(pmsJournals.getUser_id()));
        pmsJournalsParentDataVo.setAttachments(pmsCommonService.getAllGitlinkFileInfoByFileIdentifiers(pmsJournals.getAttachment_identifiers()));
        List<PmsJournals> childrenPmsJournalsList=pmsJournalsMapper.selectChildrenPmsJournalsList(pmsJournals.getId());
        pmsJournalsParentDataVo.setChildren_journals(childrenPmsJournalsList.stream().map(this::toPmsJournalsChildrenDataVo).collect(Collectors.toList()));
        pmsJournalsParentDataVo.setComments_count(childrenPmsJournalsList.size());
        return pmsJournalsParentDataVo;
    }

    private PmsJournalsChildrenDataVo toPmsJournalsChildrenDataVo(PmsJournals pmsJournals){
        PmsJournalsChildrenDataVo pmsJournalsChildrenDataVo=pmsJournals.toPmsJournalsChildrenDataVo();
        pmsJournalsChildrenDataVo.setUser(pmsCommonService.getSimpleGitlinkUserByGitlinkUserId(pmsJournals.getUser_id()));
        pmsJournalsChildrenDataVo.setAttachments(pmsCommonService.getAllGitlinkFileInfoByFileIdentifiers(pmsJournals.getAttachment_identifiers()));
        // 回复评论可能已被删除，所以存在回复评论id查找不到评论的情况
        PmsJournals replyPmsJournals=pmsJournalsMapper.selectPmsJournalsById(pmsJournals.getReply_id());
        if(replyPmsJournals!=null){
            pmsJournalsChildrenDataVo.setReply_user(pmsCommonService.getSimpleGitlinkUserByGitlinkUserId(replyPmsJournals.getUser_id()));
        }
        return pmsJournalsChildrenDataVo;
    }

    private void checkByType(PmsJournals pmsJournals) {
        switch (pmsJournals.getJournalized_type()) {
            case PmsConstants.JOURNAL_TYPE_PRODUCT_REQUIREMENT: {
                // 检查评论对象是否存在
                pmsProductRequirementService.selectPmsProductRequirementById(pmsJournals.getJournalized_id(), false);
                // 产品需求评论更新时需更新产品需求的更新时间
                pmsProductRequirementService.updatePmsProductRequirementChange(pmsJournals.getJournalized_id());
                break;
            }
            case PmsConstants.JOURNAL_TYPE_PROJECT_TESTSHEET_CASES: {
                // 检查评论对象是否存在
                pmsProjectTestsheetCasesService.selectPmsProjectTestsheetCasesById(pmsJournals.getJournalized_id());
                pmsProjectTestsheetCasesService.updatePmsProjectTestsheetCasesUpdateById(pmsJournals.getJournalized_id());
                break;
            }
            default: {
                throw new ServiceException("当前不支持该类型评论(评论类型[%s])", pmsJournals.getJournalized_type());
            }
        }
    }

    /**
     * 新增评论功能
     * 
     * @param pmsJournals 评论功能
     * @return 结果
     */
    @Override
    public int insertPmsJournals(PmsJournals pmsJournals)
    {
        checkByType(pmsJournals);
        if(pmsJournals.getParent_id()!=null){
            PmsJournals parentPmsJournals=selectPmsJournalsById(pmsJournals.getParent_id());
            if(parentPmsJournals.getParent_id()!=null){
                throw new ServiceException("该评论非父级评论(评论ID[%d])",parentPmsJournals.getId());
            }
            if(!parentPmsJournals.getJournalized_type().equals(pmsJournals.getJournalized_type())){
                throw new ServiceException("当前父级评论与当前评论类型不相同");
            }
            if(!parentPmsJournals.getJournalized_id().equals(pmsJournals.getJournalized_id())){
                throw new ServiceException("当前父级评论与当前评论对象不相同");
            }
        }
        if(pmsJournals.getReply_id()!=null){
            if(pmsJournals.getParent_id()==null){
                throw new ServiceException("一级评论不能进行回复操作");
            }
            PmsJournals replyPmsJournals=selectPmsJournalsById(pmsJournals.getReply_id());
            if(!replyPmsJournals.getJournalized_type().equals(pmsJournals.getJournalized_type())){
                throw new ServiceException("当前回复评论与当前评论类型不相同");
            }
            if(!replyPmsJournals.getJournalized_id().equals(pmsJournals.getJournalized_id())){
                throw new ServiceException("当前回复评论与当前评论对象不相同");
            }
        }
        checkPmsJournals(pmsJournals);
        pmsJournals.setCreated_on(DateUtils.getNowDate());
        Long gitlinkUserId=SecurityUtils.getGitlinkUserId();
        if(gitlinkUserId==null||gitlinkUserId==0){
            throw new ServiceException("该用户非Gitlink用户，无法发起评论(用户名[%s])",SecurityUtils.getUsername());
        }
        pmsJournals.setUser_id(gitlinkUserId);
        return pmsJournalsMapper.insertPmsJournals(pmsJournals);
    }

    private void checkPmsJournals(PmsJournals pmsJournals){
        // 检查附件列表是否有异常数据
        pmsCommonService.getAllFileByFileIdentifiers(pmsJournals.getAttachment_identifiers());
    }

    /**
     * 修改评论功能
     * 
     * @param pmsJournals 评论功能
     * @return 结果
     */
    @Override
    public int updatePmsJournals(PmsJournals pmsJournals)
    {
        PmsJournals oldPmsJournals=selectPmsJournalsById(pmsJournals.getId());
        checkByType(oldPmsJournals);
        checkPmsJournals(pmsJournals);
        pmsJournals.setUpdated_on(DateUtils.getNowDate());
        return pmsJournalsMapper.updatePmsJournals(pmsJournals);
    }

    /**
     * 批量删除评论功能
     * 
     * @param ids 需要删除的评论功能主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deletePmsJournalsByIds(Long[] ids)
    {
        int success = 0;
        for (Long id : ids
        ) {
            success += deletePmsJournalsById(id);
        }
        return success;
    }

    /**
     * 删除评论功能信息
     * 
     * @param id 评论功能主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deletePmsJournalsById(Long id)
    {
        PmsJournals pmsJournals=selectPmsJournalsById(id);
        checkByType(pmsJournals);
        if(pmsJournals.getParent_id()==null){
            // 删除父级评论时，子评论一并删除
            List<PmsJournals> childrenPmsJournalsList=pmsJournalsMapper.selectChildrenPmsJournalsList(pmsJournals.getId());
            for (PmsJournals childrenPmsJournals:childrenPmsJournalsList) {
                pmsJournalsMapper.deletePmsJournalsById(childrenPmsJournals.getId());
            }
        }
        return pmsJournalsMapper.deletePmsJournalsById(id);
    }

    @Override
    public void deletePmsJournalsByTypeAndJournalId(String type, Long journalId) {
        pmsJournalsMapper.deletePmsJournalsByTypeAndJournalId(type, journalId);
    }

    @Override
    public void updateJournalsIdByTypeAndOldId(String type, Long oldJournalId, Long journalId) {
        pmsJournalsMapper.updateJournalsIdByTypeAndOldId(type, oldJournalId, journalId);
    }
}
