package com.microservices.pms.project.service;

import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.httpClient.util.GitLinkRequestHelper;
import com.microservices.pms.enums.PmsIssueTransformationCommentType;
import com.microservices.pms.project.domain.PmsIssueTransformationCommentRecord;
import com.microservices.pms.project.domain.PmsIssuesLinkedCount;
import com.microservices.pms.project.domain.SimpleRepository;
import com.microservices.pms.project.domain.vo.PmsRepoIssueLinkProjectIssuesVo;
import com.microservices.pms.project.mapper.ForgeIssuesMapper;
import com.microservices.pms.project.mapper.PmsIssueTransformationCommentRecordMapper;
import com.microservices.pms.utils.PmsGitLinkRequestUrl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@Service
public class PmsLinkIssuesAsyncCommentService {

    @Autowired
    private PmsIssueTransformationCommentRecordMapper pmsIssueTransformationCommentRecordMapper;
    @Autowired
    private ForgeIssuesMapper forgeIssuesMapper;

    @Lazy
    @Autowired
    private PmsProjectIssuesService pmsProjectIssuesService;
    @Autowired
    private GitLinkRequestHelper gitLinkRequestHelper;

    @Autowired
    private IPmsIssueTransformationCommentRecordService  pmsIssueTransformationCommentRecordService;


    @Async
    public void asyncIssueComment(PmsRepoIssueLinkProjectIssuesVo pmsRepoIssueLinkProjectIssuesVo, Long issueId, Long[] linkIssueIds) {
        List<PmsIssueTransformationCommentRecord> records = pmsIssueTransformationCommentRecordMapper.selectByGitlinkIssueId(issueId);
        boolean requirementCommented = false;
        boolean developmentCommented = false;
        boolean testingCommented = false;

        // 检查已存在的评论记录
        for (PmsIssueTransformationCommentRecord record : records) {
            if (PmsIssueTransformationCommentType.REQUIREMENT.getKey().equals(record.getCommentType()) && record.getHasComment()) {
                requirementCommented = true;
            }
            if (PmsIssueTransformationCommentType.DEVELOPMENT.getKey().equals(record.getCommentType()) && record.getHasComment()) {
                developmentCommented = true;
            }
            if (PmsIssueTransformationCommentType.TESTING.getKey().equals(record.getCommentType()) && record.getHasComment()) {
                testingCommented = true;
            }
        }

        // 获取关联项数量
        Set<Long> linkIssueIdSet = this.getAllLinkedIssueIds(issueId, "Issue", "Issue");
        if (linkIssueIdSet.isEmpty()) {
            return;
        }
        PmsIssuesLinkedCount linkedCounts = forgeIssuesMapper.getIssuesLinkedCount(linkIssueIdSet);
        boolean requirementCreated = linkedCounts.getLinkedRequirementsCount() > 0;
        boolean developmentCreated = linkedCounts.getLinkedTasksCount() > 0;
        boolean testingCreated = linkedCounts.getLinkedBugsCount() > 0;

        // 获取仓库信息
        SimpleRepository simpleRepository = pmsProjectIssuesService.getSimpleRepository(pmsRepoIssueLinkProjectIssuesVo.getProjectRepositoryId());

        // 处理需求阶段评论
        requirementCommented = handleCommentIfNeeded(requirementCommented, requirementCreated, "本疑修已纳入需求", issueId, simpleRepository);

        // 处理开发阶段评论
        developmentCommented = handleCommentIfNeeded(developmentCommented, developmentCreated, "本疑修正在开发中", issueId, simpleRepository);

        // 处理测试阶段评论
        testingCommented = handleCommentIfNeeded(testingCommented, testingCreated, "本疑修正在测试中", issueId, simpleRepository);

        // 更新评论状态记录
        updateCommentRecordIfNecessary(requirementCommented, issueId, PmsIssueTransformationCommentType.REQUIREMENT);
        updateCommentRecordIfNecessary(developmentCommented, issueId, PmsIssueTransformationCommentType.DEVELOPMENT);
        updateCommentRecordIfNecessary(testingCommented, issueId, PmsIssueTransformationCommentType.TESTING);
    }

    /**
     * 如果需要，则添加评论
     */
    private boolean handleCommentIfNeeded(boolean isComment, boolean isCreated, String note, Long issueId, SimpleRepository simpleRepository) {
        if (!isComment && isCreated) {
            JSONObject journalsJson = new JSONObject();
            journalsJson.put("notes", note);
            gitLinkRequestHelper.doPost(
                    PmsGitLinkRequestUrl.ADD_REPO_ISSUE_JOURNAL(issueId,
                            simpleRepository.getRepoOwner(),
                            simpleRepository.getRepoIdentifier()),
                    journalsJson
            );
            return true;
        }
        return false;
    }

    /**
     * 如有必要，更新评论记录状态
     */
    private void updateCommentRecordIfNecessary(boolean commented, Long issueId, PmsIssueTransformationCommentType type) {
        if (commented) {
            PmsIssueTransformationCommentRecord update = new PmsIssueTransformationCommentRecord();
            update.setGitlinkIssueId(issueId);
            update.setCommentType(type.getKey());
            update.setHasComment(true);
            pmsIssueTransformationCommentRecordService.updateByGitlinkIssueId(update);
        }
    }

    /**
     * 递归查询所有关联的工作项ID
     * @param linkableId 起始工作项ID
     * @param linkableType 起始工作项类型
     * @param beLinkableType 关联工作项类型
     * @return 所有关联的工作项ID列表（去重）
     */
    public Set<Long> getAllLinkedIssueIds(Long linkableId, String linkableType, String beLinkableType) {
        Set<Long> allLinkedIssueIds = new HashSet<>();

        // 递归查询所有关联的工作项
        findLinkedIssuesRecursively(Arrays.asList(linkableId), linkableType, beLinkableType, allLinkedIssueIds, 0, 10);

        // 移除起始工作项自身（如果在结果中）
        allLinkedIssueIds.remove(linkableId);

        return allLinkedIssueIds;
    }

    /**
     * 递归查询关联的工作项
     * @param linkableIds 当前层级的工作项ID列表
     * @param linkableType 工作项类型
     * @param beLinkableType 关联工作项类型
     * @param result 结果集合
     * @param currentDepth 当前递归深度
     * @param maxDepth 最大递归深度
     */
    private void findLinkedIssuesRecursively(List<Long> linkableIds,
                                             String linkableType,
                                             String beLinkableType,
                                             Set<Long> result,
                                             int currentDepth,
                                             int maxDepth) {
        // 防止无限递归
        if (currentDepth >= maxDepth || linkableIds == null || linkableIds.isEmpty()) {
            return;
        }

        // 查询当前层级关联的工作项
        List<Long> linkedIssueIds;
        // 后续层级查询多个工作项关联的工作项
        linkedIssueIds = forgeIssuesMapper.selectLinkedIssueIdsByLinkableIds(linkableIds, linkableType, beLinkableType);

        // 如果没有更多关联的工作项，结束递归
        if (linkedIssueIds == null || linkedIssueIds.isEmpty() || linkedIssueIds.size() == result.size()) {
            return;
        }

        // 将新发现的关联工作项添加到结果中
        result.addAll(linkedIssueIds);

        // 递归查询下一层级
        findLinkedIssuesRecursively(linkedIssueIds, linkableType, beLinkableType, result, currentDepth + 1, maxDepth);
    }

}
