package com.microservices.cms.doc.service.impl;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.microservices.cms.doc.domain.CmsDoc;
import com.microservices.cms.doc.domain.CmsDocCommentInputDto;
import com.microservices.cms.doc.domain.CmsDocCommentUpdateDto;
import com.microservices.cms.doc.domain.gitlink.IssueInputDto;
import com.microservices.cms.doc.domain.gitlink.JournalDataVo;
import com.microservices.cms.doc.mapper.CmsDocMapper;
import com.microservices.cms.doc.service.ICmsDocCommentService;
import com.microservices.cms.doc.service.ICmsDocService;
import com.microservices.cms.project.domain.CmsProject;
import com.microservices.cms.project.service.ICmsProjectService;
import com.microservices.cms.utils.CmsGitLinkRequestUrl;
import com.microservices.common.core.constant.HttpStatus;
import com.microservices.common.core.enums.DocAuditStatus;
import com.microservices.common.core.enums.SystemRole;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.utils.JSONUtils;
import com.microservices.common.httpClient.util.GitLinkRequestHelper;
import com.microservices.common.security.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author otto
 */
@Service
public class CmsDocCommentServiceImpl implements ICmsDocCommentService {
    @Autowired
    private GitLinkRequestHelper gitLinkRequestHelper;
    @Autowired
    private ICmsDocService cmsDocService;
    @Autowired
    private CmsDocMapper cmsDocMapper;
    @Autowired
    private ICmsProjectService cmsProjectService;

    @Override
    public JSONObject addCmsDocComment(Long docId, CmsDocCommentInputDto cmsDocCommentInputDto) {
        CmsDoc cmsDoc = cmsDocService.selectBaseCmsDocById(docId);
        if (!DocAuditStatus.AUDIT_PASS.getAuditCode().equals(cmsDoc.getAuditStatus())) {
            throw new ServiceException("待审核/未通过文章不能进行评论");
        }
        CmsProject cmsProject = cmsProjectService.selectCmsProjectByDeptId(cmsDoc.getDeptId());
        Long issueIndex = getIssueIndex(cmsDoc.getIssueId(), cmsProject);
        if (issueIndex == null) {
            String zoneDocUrl = cmsDocService.getDocDetailUrl(cmsProject.getDeptId(), cmsDoc.getId());
            // 若关联的Issue不存在，则创建Issue
            IssueInputDto issueInputDto = new IssueInputDto(cmsDoc, zoneDocUrl);
            JSONObject issueJson = new JSONObject();
            Map<Class<?>, String> formatPatterns = new HashMap<>();
            formatPatterns.put(Date.class, "yyyy-MM-dd"); // 添加Date类型的格式化pattern
            JSONUtils.convertObjectToJSONObject(issueInputDto, issueJson, formatPatterns);
            JSONObject issueRes = gitLinkRequestHelper.doPost(CmsGitLinkRequestUrl.CREATE_ISSUE(cmsProject.getUsername(), cmsProject.getIdentifier()), issueJson);
            cmsDoc.setIssueId(issueRes.getLong("id"));
            cmsDocMapper.updateCmsDoc(cmsDoc);
            issueIndex = getIssueIndex(cmsDoc.getIssueId(), cmsProject);
        }
        JSONObject journalsJson = new JSONObject();
        JSONUtils.convertObjectToJSONObject(cmsDocCommentInputDto, journalsJson, null);
        return gitLinkRequestHelper.doPost(
                CmsGitLinkRequestUrl.ADD_ISSUE_JOURNAL_BY_ISSUE_INDEX(issueIndex, cmsProject.getUsername(), cmsProject.getIdentifier()),
                journalsJson
        );
    }

    @Override
    public JSONObject getCommentList(Long docId, Integer page, Integer limit) {
        JSONObject journalDataJson = new JSONObject();
        CmsDoc cmsDoc = cmsDocService.selectBaseCmsDocById(docId);
        CmsProject cmsProject = cmsProjectService.selectCmsProjectByDeptId(cmsDoc.getDeptId());
        Long issueIndex = getIssueIndex(cmsDoc.getIssueId(), cmsProject);
        if (issueIndex == null) {
            JournalDataVo journalDataVo = new JournalDataVo();
            JSONUtils.convertObjectToJSONObject(journalDataVo, journalDataJson, null);
            return journalDataJson;
        }
        journalDataJson = gitLinkRequestHelper.doGet(CmsGitLinkRequestUrl.GET_JOURNALS_BY_ISSUE_INDEX(
                cmsProject.getUsername(), cmsProject.getIdentifier(),
                issueIndex,
                page, limit
        ));
        JSONArray journals = journalDataJson.getJSONArray("journals");
//        if (journals != null) {
//            // 设置评论可删除权限
//            for (int i = 0; i < journals.size(); i++) {
//                JSONObject journal = journals.getJSONObject(i);
//                setJournalCanDelete(cmsDoc, journal);
//                journals.set(i, journal);
//                // 检查评论是否存在回复
//                JSONArray childrenJournals = journal.getJSONArray("children_journals");
//                if (childrenJournals != null) {
//                    for (int j = 0; j < childrenJournals.size(); j++) {
//                        JSONObject childrenJournal = childrenJournals.getJSONObject(j);
//                        setJournalCanDelete(cmsDoc, childrenJournal);
//                        childrenJournals.set(j, childrenJournal);
//                    }
//                    journal.put("children_journals", childrenJournals);
//                }
//            }
//        }
        journalDataJson.put("journals", journals);
        return journalDataJson;
    }

    @Override
    public JSONObject removeComment(Long docId, Long journalId) {
        JSONObject res;
        CmsDoc cmsDoc = cmsDocService.selectBaseCmsDocById(docId);
        CmsProject cmsProject = cmsProjectService.selectCmsProjectByDeptId(cmsDoc.getDeptId());
        Long issueIndex = getIssueIndex(cmsDoc.getIssueId(), cmsProject);
        if (issueIndex == null) {
            throw new ServiceException("该评论不存在");
        }
        // 当用户为文章创建者或为当前专区管理员时调用管理员权限删除评论
        if (SecurityUtils.getUsername().equals(cmsDoc.getCreateBy()) || isCurrentZoneAdmin(cmsDoc.getDeptId())) {
            res = gitLinkRequestHelper.doDelete(CmsGitLinkRequestUrl.DELETE_JOURNAL_BY_ADMIN_AND_ISSUE_INDEX(
                    cmsProject.getUsername(), cmsProject.getIdentifier(),
                    issueIndex, journalId
            ));
        } else {
            res = gitLinkRequestHelper.doDelete(CmsGitLinkRequestUrl.DELETE_AND_UPDATE_JOURNAL_BY_ISSUE_INDEX(
                    cmsProject.getUsername(), cmsProject.getIdentifier(),
                    issueIndex, journalId
            ));
        }
        return res;
    }

    @Override
    public JSONObject editComment(Long docId, Long journalId, CmsDocCommentUpdateDto cmsDocCommentUpdateDto) {
        CmsDoc cmsDoc = cmsDocService.selectBaseCmsDocById(docId);
        CmsProject cmsProject = cmsProjectService.selectCmsProjectByDeptId(cmsDoc.getDeptId());
        Long issueIndex = getIssueIndex(cmsDoc.getIssueId(), cmsProject);
        if (issueIndex == null) {
            throw new ServiceException("该评论不存在");
        }
        JSONObject journalsJson = new JSONObject();
        JSONUtils.convertObjectToJSONObject(cmsDocCommentUpdateDto, journalsJson, null);
        return gitLinkRequestHelper.doPatch(CmsGitLinkRequestUrl.DELETE_AND_UPDATE_JOURNAL_BY_ISSUE_INDEX(
                cmsProject.getUsername(), cmsProject.getIdentifier(),
                issueIndex, journalId
        ), journalsJson);
    }

    @Override
    public void deleteCommentIssueByDocId(CmsDoc cmsDoc) {
        CmsProject cmsProject = cmsProjectService.selectCmsProjectByDeptId(cmsDoc.getDeptId());
        Long issueIndex = getIssueIndex(cmsDoc.getIssueId(), cmsProject);
        if (issueIndex == null) {
            return;
        }
        gitLinkRequestHelper.doDelete(CmsGitLinkRequestUrl.DELETE_ISSUE_BY_ADMIN_AND_ISSUE_INDEX(
                cmsProject.getUsername(), cmsProject.getIdentifier(), issueIndex
        ));
    }

    private Boolean isCurrentZoneAdmin(Long deptId) {
        if (SystemRole.PLATFORM_ADMIN.getRoleKey().equals(SecurityUtils.getRoleKey())) {
            return true;
        }
        // 判断是否为当前组织下的专区管理员
        return deptId.equals(SecurityUtils.getDeptId())
                && SystemRole.ZONE_ADMIN.getRoleKey().equals(SecurityUtils.getRoleKey());
    }

    private void setJournalCanDelete(CmsDoc cmsDoc, JSONObject journal) {
        JSONObject user = journal.getJSONObject("user");
        if (user != null && user.getLong("id").equals(SecurityUtils.getGitlinkUserId())) {
            journal.put("can_delete", true);
            journal.put("can_edit", true);
        } else if (cmsDoc.getCreateBy().equals(SecurityUtils.getUsername())) {
            journal.put("can_delete", true);
            journal.put("can_edit", false);
        } else if (isCurrentZoneAdmin(cmsDoc.getDeptId())) {
            journal.put("can_delete", true);
            journal.put("can_edit", false);
        } else {
            journal.put("can_delete", false);
            journal.put("can_edit", false);
        }
    }


    /**
     * 获取Issue Index
     *
     * @param issueId    issueId
     * @param cmsProject 专区对应项目
     * @return Issue Index
     */
    private Long getIssueIndex(Long issueId, CmsProject cmsProject) {
        if (issueId == null) {
            return null;
        }
        // 检查关联Issue是否存在
        try {
            JSONObject jsonObject = gitLinkRequestHelper.doGet(CmsGitLinkRequestUrl.GET_ISSUE_BY_ISSUE_ID(
                    cmsProject.getUsername(), cmsProject.getIdentifier(), issueId
            ));
            return jsonObject.getLong("project_issues_index");
        } catch (ServiceException e) {
            if (e.getCode() != null && e.getCode() == HttpStatus.NOT_FOUND) {
                return null;
            }
        }
        return null;
    }
}
