package com.microservices.pms.utils;

import com.alibaba.fastjson2.JSONObject;
import com.microservices.common.core.utils.DateUtils;
import com.microservices.common.core.utils.StringUtils;
import com.microservices.common.httpClient.domain.GitLinkRequestUrl;

import java.net.URISyntaxException;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @author otto
 */
public class PmsGitLinkRequestUrl extends GitLinkRequestUrl {

    /**
     * 获取组织团队下用户列表
     */
    public static String USER_LIST_BY_ORGANIZATION_TEAM_URL(String orgIdentify, Long teamId) {
        return String.format("/api/organizations/%s/teams/%d/team_users.json", orgIdentify, teamId);
    }

    /**
     * 获取或更新组织
     */
    public static GitLinkRequestUrl GET_OR_PATCH_ORGANIZATION(Long gitlinkOrgId) {
        return getAdminGitLinkRequestUrl(String.format("/api/organizations/%d.json", gitlinkOrgId));
    }

    /**
     * 查询组织下团队列表
     */
    public static String TEAMS_BY_ORGANIZATION_URL(Long orgId) {
        return String.format("/api/organizations/%s/teams.json", orgId);
    }

    /**
     * 获取组织详情
     */
    public static GitLinkRequestUrl DELETE_ORGANIZATION(Long gitlinkOrgId, String password) {
        return getGitLinkRequestUrl(String.format("/api/organizations/%d.json?password=%s", gitlinkOrgId, password));
    }

    /**
     * 创建组织团队
     */
    public static GitLinkRequestUrl CREATE_ORGANIZATION_TEAM(String orgIdentifier) {
        return getAdminGitLinkRequestUrl(String.format("/api/organizations/%s/teams.json", orgIdentifier));
    }

    /**
     * 添加用户到组织团队（重复添加不会报错）
     */
    public static GitLinkRequestUrl ADD_USER_TO_ORGANIZATION_TEAM(String orgIdentifier, Long teamId) {
        return getAdminGitLinkRequestUrl(String.format("/api/organizations/%s/teams/%d/team_users.json", orgIdentifier, teamId));
    }

    /**
     * 从gitlink组织中移除用户
     */
    public static GitLinkRequestUrl DELETE_USER_FROM_ORGANIZATION_TEAM(String orgIdentifier, Long teamId, String username) {
        return getAdminGitLinkRequestUrl(String.format("/api/organizations/%s/teams/%d/team_users/%s.json", orgIdentifier, teamId, username));
    }

    /**
     * 删除组织团队
     */
    public static GitLinkRequestUrl DELETE_ORGANIZATION_TEAM(Long orgId, Long teamId) {
        return getAdminGitLinkRequestUrl(String.format("/api/organizations/%d/teams/%d.json", orgId, teamId));
    }

    /**
     * 根据仓库id获取owner和repo
     */
    public static GitLinkRequestUrl GET_OWNER_AND_REPO_BY_REPO_ID(Long repoId) {
        return getGitLinkRequestUrl(String.format(
                "/api/pm/projects/convert.json?project_id=%s", repoId
        ));
    }

    /**
     * 获取仓库详情
     */
    public static GitLinkRequestUrl GET_REPO_DETAILS(String owner, String repo) {
        return getGitLinkRequestUrl(String.format(
                "/api/%s/%s/detail.json", owner, repo
        ));
    }

    public static GitLinkRequestUrl GET_ORGANIZATION_REPO_LIST(String enterpriseIdentifier, Map<String, String> params) throws URISyntaxException {
        String path = String.format("/api/organizations/%s/projects.json", enterpriseIdentifier);
        return getGitLinkRequestUrl(
                buildUri(path, params));
    }

    /**
     * 获取仓库中issue初始状态
     */
    public static GitLinkRequestUrl GET_REPO_ISSUE_DEFAULT_STATUS() {
        return getGitLinkRequestUrl(
                "/api/pm/issues/statues"
        );
    }

    /**
     * 获取仓库中issue初始优先级
     */
    public static GitLinkRequestUrl GET_REPO_ISSUE_DEFAULT_PRIORITIES() {
        return getGitLinkRequestUrl(
                "/api/pm/issues/priorities"
        );
    }

    /**
     * 获取仓库中issue初始标记
     */
    public static GitLinkRequestUrl GET_REPO_ISSUE_DEFAULT_TAGS(Map<String, String> params) throws URISyntaxException {
        return getGitLinkRequestUrl(buildUri("/api/pm/issues/tags", params));
    }

    public static GitLinkRequestUrl GET_BRANCHES_BY_REPO_ID(String owner, String repo) {
        return getGitLinkRequestUrl(String.format(
                "/api/%s/%s/branches.json", owner, repo
        ));
    }

    public static GitLinkRequestUrl CREATE_ISSUE() {
        return getGitLinkRequestUrl("/api/pm/issues");
    }

    public static GitLinkRequestUrl UPDATE_ISSUE(Long id) {
        return getGitLinkRequestUrl(String.format(
                "/api/pm/issues/%s", id
        ));
    }

    public static GitLinkRequestUrl UPDATE_ISSUE_BATCH(Long pmProjectId) {
        return getGitLinkRequestUrl(String.format(
                "/api/pm/issues/batch_update?pm_project_id=%s", pmProjectId
        ));
    }

    public static GitLinkRequestUrl GET_ISSUE(Long id, Long pmProjectId) throws URISyntaxException {
        Map<String, String> params = new HashMap<>();
        params.put("pm_project_id", String.valueOf(pmProjectId));
        return getGitLinkRequestUrl(buildUri(String.format(
                "/api/pm/issues/%s", id), params
        ));
    }

    public static GitLinkRequestUrl GET_ISSUE_LIST(JSONObject params) throws URISyntaxException {

        return getGitLinkRequestUrl(
                buildUri("/api/pm/issues", params));
    }

    public static GitLinkRequestUrl DELETE_ISSUE(Long id, Long pmProjectId) {
        return getGitLinkRequestUrl(String.format(
                "/api/pm/issues/%s?pm_project_id=%s", id, pmProjectId
        ));
    }

    public static GitLinkRequestUrl DELETE_ISSUES_BATCH(Long pmProjectId) {
        String path = String.format("/api/pm/issues/batch_destroy?pm_project_id=%s", pmProjectId);
        return getGitLinkRequestUrl(path);
    }

    public static GitLinkRequestUrl GET_ISSUE_COUNT(List<String> projectIdList, String participantCategory, String category) {
        String path = "/api/pm/projects/issues_count";
        path = concatenateParametersAfterUrl(path, "pm_project_id[]", projectIdList);
        if (participantCategory != null) {
            path = path + "&participant_category=" + participantCategory;
        }
        if (category != null) {
            path = path + "&category=" + category;
        }
        return getGitLinkRequestUrl(path);
    }

    public static GitLinkRequestUrl DELETE_ISSUE_LINK(Long issueId, String linkIssueId, Long pmProjectId) throws URISyntaxException {
        String path = String.format("/api/pm/issues/%s/issue_links/%s?pm_project_id=%s", issueId, linkIssueId, pmProjectId);
        return getGitLinkRequestUrl(path);
    }

    public static GitLinkRequestUrl GET_ISSUE_LINK(Long issueId, Long pmProjectId) {
        String path = String.format("/api/pm/issues/%s/issue_links?pm_project_id=%s", issueId, pmProjectId);
        return getGitLinkRequestUrl(path);
    }

    public static GitLinkRequestUrl GET_ISSUE_UNLINK(Long issueId, Long pmProjectId, Integer pmIssueType,
                                                     String issueFilterType, Integer pageNum, Integer pageSize) {
        String path = String.format("/api/pm/issues/%s/link_index?pm_project_id=%s&pm_issue_type=%s&issue_filter_type=%s",
                issueId, pmProjectId, pmIssueType, issueFilterType);
        if (pageNum != null && pageSize != null) {
            path = path + "&page=" + pageNum + "&limit=" + pageSize;
        }
        return getGitLinkRequestUrl(path);
    }

    public static GitLinkRequestUrl ADD_ISSUE_LINK(Long issueId, Long pmProjectId) {
        String path = String.format("/api/pm/issues/%s/issue_links?pm_project_id=%s", issueId, pmProjectId);
        return getGitLinkRequestUrl(path);
    }

    public static GitLinkRequestUrl IMPORT_ISSUES(Long pmProjectId, Long organizationId) {
        String path = String.format("/api/pm/issues/import?pm_project_id=%s&organization_id=%s", pmProjectId, organizationId);
        return getGitLinkRequestUrl(path);
    }

    public static GitLinkRequestUrl EXPORT_ISSUES(Long pmProjectId) {
        String path = "/api/pm/issues/export?pm_project_id=" + pmProjectId;
        return getGitLinkRequestUrl(path);
    }

    /**
     * 获取组织下代码库列表
     */
    public static GitLinkRequestUrl PROJECTS(String identifier, String query) {
        return getGitLinkRequestUrl(String.format("/api/organizations/%s/projects.json%s", identifier, query));
    }

    public static GitLinkRequestUrl ADD_ISSUE_JOURNAL(Long issueId, Long pmProjectId, Long pmProjectRepositoryId) {
        String path = String.format("/api/pm/issues/%s/journals?pm_project_id=%s", issueId, pmProjectId);
        if (pmProjectRepositoryId != null) {
            path = path + "&project_id=" + pmProjectRepositoryId;
        }
        return getGitLinkRequestUrl(path);
    }

    public static GitLinkRequestUrl DELETE_ISSUE_JOURNAL(Long issueId, Long journalId, Long pmProjectId, Long pmProjectRepositoryId) {
        String path = String.format("/api/pm/issues/%s/journals/%s?pm_project_id=%s", issueId, journalId, pmProjectId);
        if (pmProjectRepositoryId != null) {
            path = path + "&project_id=" + pmProjectRepositoryId;
        }
        return getGitLinkRequestUrl(path);
    }

    public static GitLinkRequestUrl GET_ISSUE_JOURNALS(Long issueId, JSONObject pmsProjectIssueJournalSearchObj) throws URISyntaxException {
        String path = String.format("/api/pm/issues/%s/journals", issueId);
        return getGitLinkRequestUrl(buildUri(path, pmsProjectIssueJournalSearchObj));
    }

    public static GitLinkRequestUrl GET_SPRINT_ISSUES(JSONObject pmsProjectSprintLinkIssuesSearchObj) throws URISyntaxException {
        String path = "/api/pm/sprint_issues";
        return getGitLinkRequestUrl(buildUri(path, pmsProjectSprintLinkIssuesSearchObj));
    }

    public static GitLinkRequestUrl GET_SPRINT_ISSUES_STATISTICS(String projectSprintIds) {
        String path = "/api/pm/sprint_issues/statistics?pm_sprint_ids=" + projectSprintIds;
        return getGitLinkRequestUrl(path);
    }

    public static GitLinkRequestUrl COMPLETE_SPRINT() {
        return getGitLinkRequestUrl("/api/pm/sprint_issues/complete");
    }

    public static GitLinkRequestUrl GET_OPTIONAL_PARENT_ISSUES(Long issueId, String pmIssueType, String pmProjectId,
                                                               String keyword, Integer pageNum, Integer pageSize) {
        String path = String.format("/api/pm/issues/%s/parent_issues?pm_issue_type=%s&pm_project_id=%s", issueId, pmIssueType, pmProjectId);
        if (StringUtils.isNotEmpty(keyword)) {
            path = path + "&keyword=" + keyword;
        }
        if (pageNum != null && pageSize != null) {
            path = path + String.format("&page=%s&limit=%s", pageNum, pageSize);
        }
        return getGitLinkRequestUrl(path);
    }

    public static GitLinkRequestUrl GET_ORGANIZATION_ISSUE_TAGS_LIST(JSONObject issueTagsSearchParams) throws URISyntaxException {
        String path = "/api/pm/issue_tags";
        return getGitLinkRequestUrl(buildUri(path, issueTagsSearchParams));
    }

    public static GitLinkRequestUrl CREATE_ORGANIZATION_ISSUE_TAG() {
        return getGitLinkRequestUrl("/api/pm/issue_tags");
    }

    public static GitLinkRequestUrl UPDATE_ORGANIZATION_ISSUE_TAG(Long tagId) {
        return getGitLinkRequestUrl("/api/pm/issue_tags/" + tagId);
    }

    public static GitLinkRequestUrl DELETE_ORGANIZATION_ISSUE_TAG(Long tagId) {
        return getGitLinkRequestUrl("/api/pm/issue_tags/" + tagId);
    }

    public static GitLinkRequestUrl GET_SPRINT_BURN_DOWN_CHART(Long pmSprintId, Date startTime, Date endTime) {
        String startTimeParam = DateUtils.dateTime(startTime);
        String endTimeParam = DateUtils.dateTime(endTime);
        String path = String.format("/api/pm/sprint_issues/burndown_charts?pm_sprint_id=%s&start_time=%s&end_time=%s", pmSprintId, startTimeParam, endTimeParam);
        return getGitLinkRequestUrl(path);
    }

    public static GitLinkRequestUrl GET_PROJECT_STATISTICS(Long pmProjectId) {
        return getGitLinkRequestUrl("/api/pm/projects/statistics?pm_project_id=" + pmProjectId);
    }

    public static GitLinkRequestUrl GET_PROJECT_POLYLINE(Long pmProjectId) {
        return getGitLinkRequestUrl("/api/pm/projects/polyline?pm_project_id=" + pmProjectId);
    }

    public static GitLinkRequestUrl CHECK_PASSWORD(String username) {
        return getGitLinkRequestUrl(String.format("/api/v1/%s/check_password.json", username));
    }

    public static GitLinkRequestUrl GET_PIPELINE_FILE_LIST(String owner, String repoIdentifier){
        return getGitLinkRequestUrl(String.format("/api/v1/%s/%s/actions", owner, repoIdentifier));
    }

    public static GitLinkRequestUrl GET_PIPELINE_RUNS_LIST(String owner, String repoIdentifier, JSONObject pmsCiPipelineRunsListQueryParams) throws URISyntaxException {
        String path = String.format("/api/v1/%s/%s/actions/runs", owner, repoIdentifier);
        return getGitLinkRequestUrl(buildUri(path, pmsCiPipelineRunsListQueryParams));
    }

    public static GitLinkRequestUrl GET_PIPELINE_RUNS_JOB(String owner, String repoIdentifier, String run, String job){
        return getGitLinkRequestUrl(String.format("/api/v1/%s/%s/actions/runs/%s/jobs/%s", owner, repoIdentifier, run, job));
    }

    public static GitLinkRequestUrl RERUN_PIPELINE_RUNS_JOB(String owner, String repoIdentifier, String run, String job){
        return getGitLinkRequestUrl(String.format("/api/v1/%s/%s/actions/runs/%s/jobs/%s/rerun", owner, repoIdentifier, run, job));
    }

    public static GitLinkRequestUrl RUN_PIPELINE_RUNS_JOB(String owner, String repoIdentifier, String workflow, String ref){
        return getGitLinkRequestUrl(String.format("/api/v1/%s/%s/actions/runs?workflow=%s&ref=%s", owner, repoIdentifier, workflow, ref));
    }

    public static GitLinkRequestUrl RERUN_ALL_JOBS_IN_PIPELINE_RUN(String owner, String repoIdentifier, String run){
        return getGitLinkRequestUrl(String.format("/api/v1/%s/%s/actions/runs/%s/rerun", owner, repoIdentifier, run));
    }

    public static GitLinkRequestUrl GET_PIPELINE_RUN_JOB_LOGS(String owner, String repoIdentifier, String run, String job){
        return getGitLinkRequestUrl(String.format("/api/v1/%s/%s/actions/runs/%s/jobs/%s/logs", owner, repoIdentifier, run, job));
    }

    public static GitLinkRequestUrl ENABLE_PIPELINE_FILE(String owner, String repoIdentifier, String fileName) {
        return getGitLinkRequestUrl(String.format("/api/v1/%s/%s/actions/enable?workflow=%s", owner, repoIdentifier, fileName));
    }

    public static GitLinkRequestUrl DISABLE_PIPELINE_FILE(String owner, String repoIdentifier, String fileName) {
        return getGitLinkRequestUrl(String.format("/api/v1/%s/%s/actions/disable?workflow=%s", owner, repoIdentifier, fileName));
    }

    public static GitLinkRequestUrl UPDATE_REPO_ACTION_MODULE(String repoOwner, String repoIdentifier) {
        return getGitLinkRequestUrl(String.format("/api/%s/%s.json", repoOwner, repoIdentifier));
    }

    public static GitLinkRequestUrl GET_NODES() {
        return getGitLinkRequestUrl("/api/action/nodes.json");
    }

    public static GitLinkRequestUrl GET_TEMPLATES() {
        return getGitLinkRequestUrl("/api/action/templates.json");
    }

    public static GitLinkRequestUrl BUILD_PIPELINE_YAML(String owner, String repoIdentifier) {
        return getGitLinkRequestUrl(String.format("/api/v1/%s/%s/pipelines/build_yaml", owner, repoIdentifier));
    }

    public static GitLinkRequestUrl SAVE_PIPELINE_YAML(String owner, String repoIdentifier) {
        return getGitLinkRequestUrl(String.format("/api/v1/%s/%s/pipelines/save_yaml", owner, repoIdentifier));
    }

    public static GitLinkRequestUrl GET_REQ_SPECS_LINK_ISSUES(Long reqSpecsIssueId, Long projectId) {
        return getGitLinkRequestUrl(String.format("/api/pm/issues/%d/link_issues?pm_project_id=%d", reqSpecsIssueId, projectId));
    }
}
