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

import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.exception.ServiceException;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.httpClient.util.GitLinkRequestHelper;
import com.microservices.pms.enterprise.domain.PmsEnterprise;
import com.microservices.pms.enterprise.service.IPmsEnterpriseService;
import com.microservices.pms.project.domain.PmsProjectRepository;
import com.microservices.pms.project.domain.vo.PmsProjectRepositorySearchVo;
import com.microservices.pms.project.domain.vo.PmsProjectUnlinkedRepositorySearchVo;
import com.microservices.pms.project.mapper.PmsProjectRepositoryMapper;
import com.microservices.pms.project.service.IPmsProjectRepositoryService;
import com.microservices.pms.project.service.IPmsProjectService;
import com.microservices.pms.utils.PmsGitLinkRequestUrl;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.validation.constraints.NotNull;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 项目-代码库Service业务层处理
 * 
 * @author wanjia
 * @date 2023-10-11
 */
@Service
public class PmsProjectRepositoryServiceImpl implements IPmsProjectRepositoryService 
{
    @Autowired
    private PmsProjectRepositoryMapper pmsProjectRepositoryMapper;

    @Autowired
    private GitLinkRequestHelper gitLinkRequestHelper;

    @Lazy
    @Autowired
    private IPmsEnterpriseService pmsEnterpriseService;

    @Lazy
    @Autowired
    private IPmsProjectService pmsProjectService;

    /**
     * 查询项目-代码库
     * 
     * @param id 项目-代码库主键
     * @return 项目-代码库
     */
    @Override
    public PmsProjectRepository selectPmsProjectRepositoryById(Long id)
    {
        PmsProjectRepository pmsProjectRepository = pmsProjectRepositoryMapper.selectPmsProjectRepositoryById(id);
        if (pmsProjectRepository == null) {
            throw new ServiceException("该项目仓库不存在(项目仓库ID[%s])", id);
        }
        pmsProjectService.selectAndCheckPmsProjectById(pmsProjectRepository.getPmsProjectId());
        return pmsProjectRepository;
    }

    /**
     * 查询项目-代码库列表
     * 
     * @param pmsProjectRepositorySearchVo 项目-代码库搜索类
     * @return 项目-代码库
     */
    @Override
    public JSONObject selectPmsProjectRepositoryList(PmsProjectRepositorySearchVo pmsProjectRepositorySearchVo)
    {
        pmsProjectService.selectAndCheckPmsProjectById(pmsProjectRepositorySearchVo.getPmsProjectId());
        PmsProjectRepository pmsProjectRepository = new PmsProjectRepository();
        BeanUtils.copyProperties(pmsProjectRepositorySearchVo, pmsProjectRepository);
        List<PmsProjectRepository> list = pmsProjectRepositoryMapper.selectPmsProjectRepositoryList(pmsProjectRepository);
        if (list.isEmpty()) {
            return new JSONObject();
        }
        List<Long> projectRepositoryIdList = list.stream()
                .map(PmsProjectRepository::getProjectRepositoryId)
                .collect(Collectors.toList());
        String projectRepositoryIds =  StringUtils.join(projectRepositoryIdList, ",");
        Map<String, String> queryParams = convertToGetRepoListQueryParam(pmsProjectRepositorySearchVo.getSearch(),
                pmsProjectRepositorySearchVo.getPage(),
                pmsProjectRepositorySearchVo.getLimit(),
                pmsProjectRepositorySearchVo.getSortBy(),
                projectRepositoryIds,
                null,
                pmsProjectRepositorySearchVo.getActived());
        try {
            return  gitLinkRequestHelper.doGet(PmsGitLinkRequestUrl.GET_ORGANIZATION_REPO_LIST(pmsProjectRepositorySearchVo.getEnterpriseIdentifier(), queryParams));
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public JSONObject selectUnlinkedPmsRepositoryListByEnterpriseIdentifier(PmsProjectUnlinkedRepositorySearchVo pmsProjectUnlinkedRepositorySearchVo) {
        PmsEnterprise pmsEnterprise = pmsEnterpriseService.selectPmsEnterpriseByIdentifier(pmsProjectUnlinkedRepositorySearchVo.getEnterpriseIdentifier());
        Long[] linkedRepositoryIds = pmsProjectRepositoryMapper.selectLinkedRepositoryIdsByEnterpriseId(pmsEnterprise.getId());
        String linkedRepositoryIdsString = StringUtils.join(linkedRepositoryIds, ",");
        Map<String, String> queryParams = convertToGetRepoListQueryParam(pmsProjectUnlinkedRepositorySearchVo.getSearch(),
                pmsProjectUnlinkedRepositorySearchVo.getPage(),
                pmsProjectUnlinkedRepositorySearchVo.getLimit(),
                pmsProjectUnlinkedRepositorySearchVo.getSortBy(),
                null,
                linkedRepositoryIdsString,
                pmsProjectUnlinkedRepositorySearchVo.getActived());
        try {
            return gitLinkRequestHelper.doGet(PmsGitLinkRequestUrl.GET_ORGANIZATION_REPO_LIST(pmsProjectUnlinkedRepositorySearchVo.getEnterpriseIdentifier(), queryParams));
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 新增项目-代码库
     * 
     * @param pmsProjectRepository 项目-代码库
     * @return 结果
     */
    @Override
    public int insertPmsProjectRepository(PmsProjectRepository pmsProjectRepository) {
        pmsProjectService.selectAndCheckPmsProjectById(pmsProjectRepository.getPmsProjectId());
        //仓库已被关联，返回错误提示
        if (pmsProjectRepositoryMapper.countPmsProjectRepositoryByProjectRepositoryId(pmsProjectRepository.getProjectRepositoryId()) > 0) {
            throw new ServiceException("代码库id:[%s]已被关联", pmsProjectRepository.getProjectRepositoryId());
        }
        return pmsProjectRepositoryMapper.insertPmsProjectRepository(pmsProjectRepository);
    }

    /**
     * 修改项目-代码库
     *
     * @param pmsProjectRepositoryUpdate 项目-代码库
     * @return 结果
     */
    @Override
    public int updatePmsProjectRepository(PmsProjectRepository pmsProjectRepositoryUpdate)
    {
        selectPmsProjectRepositoryById(pmsProjectRepositoryUpdate.getId());
        return pmsProjectRepositoryMapper.updatePmsProjectRepository(pmsProjectRepositoryUpdate);
    }

    /**
     * 批量删除项目-代码库
     * 
     * @param ids 需要删除的项目-代码库主键
     * @return 结果
     */
    @Override
    public int deletePmsProjectRepositoryByIds(Long[] ids)
    {
        int success = 0;
        for (Long id : ids) {
            selectPmsProjectRepositoryById(id);
            success += pmsProjectRepositoryMapper.deletePmsProjectRepositoryById(id);
        }
        return success;
    }

    @Override
    public JSONObject selectPmsProjectRepoInfoListByProjectId(Long pmsProjectId, Long pmsEnterpriseId) {
        pmsProjectService.selectAndCheckPmsProjectById(pmsProjectId);
        PmsEnterprise pmsEnterprise = pmsEnterpriseService.selectPmsEnterpriseById(pmsEnterpriseId);
        List<Integer> repositoryIds = pmsProjectRepositoryMapper.selectPmsProjectRepoIdsByProjectId(pmsProjectId);
        if (pmsEnterprise == null || repositoryIds == null || repositoryIds.isEmpty()) {
            return null;
        }
        String projectRepositoryIds =  StringUtils.join(repositoryIds, ",");
        Map<String, String> queryParams = new HashMap<>();
        queryParams.put("page" , "1");
        queryParams.put("limit", "1000");
        queryParams.put("sort_by", "updated_on");
        queryParams.put("sort_direction", "desc");
        queryParams.put("pm_project_repository_ids", projectRepositoryIds);
        try {
            return  gitLinkRequestHelper.doGet(PmsGitLinkRequestUrl.GET_ORGANIZATION_REPO_LIST(pmsEnterprise.getEnterpriseIdentifier(), queryParams));
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        }
    }

    private static Map<String, String> convertToGetRepoListQueryParam(String search, @NotNull Long page, @NotNull Long limit,
                                                                      String sortBy, String projectRepositoryIds,
                                                                      String linkedRepositoryIdsString, Boolean actived) {
        Map<String, String> queryParams = new HashMap<>();
        queryParams.put("search", search);
        queryParams.put("page" , String.valueOf(page));
        queryParams.put("limit", String.valueOf(limit));
        queryParams.put("sort_by", sortBy);
        queryParams.put("sort_direction", "desc");
        if (actived != null) {
            queryParams.put("actived", actived ? "true" : "false");
        }
        if (StringUtils.isNotEmpty(projectRepositoryIds)) {
            queryParams.put("pm_project_repository_ids", projectRepositoryIds);
        }
        if (StringUtils.isNotEmpty(linkedRepositoryIdsString)) {
            queryParams.put("exclude_ids", linkedRepositoryIdsString);
        }
        return queryParams;
    }
}
