# shellcheck shell=sh
# shellcheck disable=SC2039,3043

# Should be like this.
# gt repo issue add el:admin
# gt repo issue remove user-a
# gt repo issue add user-b

# gt repo issue +el:admin -user-a +user-b
___x_cmd_gt_issue(){
    param:scope         ___x_cmd_gt
    param:subcmd ___x_cmd_gt_issue                  \
        ls              "List issue"                \
        info            "Get issue info"            \
        create          "Create issue"              \
        "edit|ed"       "Edit issue"
    param:subcmd:try
    param:run

    ___x_cmd_gt_issue _param_help_doc
    return 1
}

# Section: List
# shellcheck disable=SC2154
___x_cmd_gt_issue_ls(){
    param:scope     ___x_cmd_gt
    param:dsl       '
options:
    #1              "owner path(enterprise|owner/repo) (empty: use current user)"        <>=""
    --direction     "direction"                                                          <>:Direction="desc"
    --state         "issue state"                                                        <>:IssueState="open"
    --labels        "labels"                                                             <>=""
    --page          "page"                                                               <>="1"
    --per_page      "per_page"                                                           <>="20"
    --json|-j       "output origin json data"
'
    param:run

    if [ -z "$1" ]; then
        ___x_cmd_gt_user_issue --direction "$direction" --state "$state" ${labels:+"--labels"} ${labels:+$labels}
    else
        case "$(___x_cmd_gt_owner_type_query "$1")" in
            repo)           ___x_cmd_gt_repo_issue_ls        --repo "$1"       --direction "$direction" --state "$state" ${labels:+"--labels"} ${labels:+$labels} ;;
            enterprise)     ___x_cmd_gt_enterprise_issue_ls  --enterprise "$1" --direction "$direction" --state "$state" ${labels:+"--labels"} ${labels:+$labels} ;;
            org)            gt:warn  "Not support list org issue. Please use 'x gt org issue'"; return 1    ;;
            user)           gt:error "Not support list $1 user issue"; return 1                             ;;
            *)              gt:error "Not fonund owner_type. Please check the owner $1 exsit"; return 1     ;;
        esac
    fi
}
# EndSection

# Section: Info
# shellcheck disable=SC2154
___x_cmd_gt_issue_info(){
    param:scope     ___x_cmd_gt
    param:dsl       '
options:
    #1              "issue number(Case sensitive.Not with #)"                            <>
    --owner         "Provide owner path(enterprise, or repo path)"                       <>=""
    --json|-j       "output origin json data"
'
    param:run

    if [ -n "$owner" ]; then
        case "$(___x_cmd_gt_owner_type_query "$owner")" in
            repo)           ___x_cmd_gt_repo_issue_info --repo "$owner" "$1" ;;
            enterprise)     ___x_cmd_gt_enterprise_issue_info --enterprise "$owner" "$1" ;;
            org|user)       gt:error  "Not support get owner $owner issue info. Please check the owner path is enterprise or repo path"; return 1   ;;
            *)              gt:error "Not fonund owner_type. Please check the owner $owner exsit"; return 1  ;;
        esac
    else
        case "$1" in
            */*/*)      local _issue="${1##*/}" ; local _owner_repo="${1%/*}"; ___x_cmd_gt_repo_issue_info --repo "$_owner_repo" "$_issue"    ;;
            */*)        local _issue="${1#*/}"  ; local _ent="${1%/*}" ; ___x_cmd_gt_enterprise_issue_info --enterprise "$_ent" "$_issue"   ;;
            *)          gt:error "Please provide --owner or add (repo/owner) | (enterprise path) prefix before issue number"
                        return
        esac
    fi
}
# EndSection

# Section: Create

# shellcheck disable=SC2154,SC2034
# https://gitee.com/api/v5/swagger#/postV5ReposOwnerIssues
___x_cmd_gt_issue_create(){
    param:scope         ___x_cmd_gt
    param:dsl      '
options:
    --owner         "Provide owner name(enterprise,ownerPath/RepoPath)"                  <>
    --title         "title"                                                              <>

    --body          "issue describe (support md)"                                        <>=""
    --type          "issue type"                                                         <>=""
    --assignee      "assignee space address"                                             <>=""
    --collaborators "collaborators space address"                                        <>=""
    --milestone     "milestone serial number"                                            <>=""
    --labels        "labels"                                                             <>=""
    --program       "project ID"                                                         <>=""
    --security      "is it private"
    --json|-j       "output origin json data"
'
    param:run

    local repo=""
    case ${owner} in
        */*) repo="${owner##*/}" ;;
    esac
    local gen_gt_json=""
    gen_gt_json="$(param:option2json ${repo:+"+repo"} 'security_hole=^^security' issue_type=type -security -type -owner)"
    gt:debug "$gen_gt_json"

    ___x_cmd_gt_curl post "/repos/${owner%%/*}/issues" "gen_gt_json" | ___x_cmd_gt_issue____ui_handler Creating
}
# EndSection

# Section: Edit

# shellcheck disable=SC2154,SC2034
# https://gitee.com/api/v5/swagger#/patchV5ReposOwnerIssuesNumber
___x_cmd_gt_issue_edit(){
    param:scope     ___x_cmd_gt
    param:dsl       '
type:
    State = open progressing closed
options:
    #1              "issue number(Case sensitive.Not with #)"                            <>
    --owner         "Provide owner name(enterprise path,ownerPath/RepoPath)"             <>
    --state         "issue state "                                                       <>:State

    --title         "title"                                                              <>=""
    --body          "issue describe (support md)"                                        <>=""
    --assignee      "assignee space address"                                             <>=""
    --collaborators "collaborators space address"                                        <>=""
    --milestone     "milestone serial number"                                            <>=""
    --labels        "labels"                                                             <>=""
    --program       "project ID"                                                         <>=""
    --security      "is it private"
    --json|-j       "output origin json data"
'
    param:run
    [ -n "$1" ] || M='accepts 1 arg(issue number), received empty' arg:ret:64
    local number="${1}"
    local security="${security:-false}"
    local repo=""
    case ${owner} in
        */*) repo="${owner##*/}" ;;
    esac
    local gen_gt_json=""
    gen_gt_json="$(param:option2json ${repo:+"+repo"} 'security_hole=^^security' -security -owner)"
    gt:debug "$gen_gt_json"

    ___x_cmd_gt_curl patch "/repos/${owner%%/*}/issues/${number}" "gen_gt_json" | ___x_cmd_gt_issue____ui_handler Modify
}
# EndSection

___x_cmd_gt_repo_issue(){
    param:scope         ___x_cmd_gt
    param:subcmd ___x_cmd_gt_repo_issue             \
        ls              "List repo issue"           \
        info            "Get  repo issue info"      \
        log             "Get  repo issue logs"      \
        comment         "issue comment management"

    param:subcmd:try
    param:run

    ___x_cmd_gt_repo_issue _param_help_doc
    return 1
}
# Section: Repo Issue List Info
# shellcheck disable=SC2039,3043,SC2154
# https://gitee.com/api/v5/swagger#/getV5ReposOwnerRepoIssues
___x_cmd_gt_repo_issue_ls(){
    param:scope     ___x_cmd_gt
    param:dsl       '
options:
    --repo|-r       "<owner_path>/<repo_path>"              <>:RepoPath
    --direction     "direction"                             <>:Direction="desc"
    --sort          "sort"                                  <>:Sort="created"
    --state         "issue state"                           <>:IssueState="open"
    --labels        "labels"                                <>=""
    --assignee      "assignee"                              <>=""
    --creator       "creator"                               <>=""
    --program       "program"                               <>=""
    --page          "page"                                  <>="1"
    --per_page      "per_page"                              <>="20"
    --json|-j       "output origin json data"
'
    param:run
    ___x_cmd_gt_param_init_owner_repo
    if [ -n "$json" ] || [ -n "$ENFORCE_JSON" ]; then
        ___x_cmd_gt_get_multi "/repos/${owner_repo}/issues" state labels milestone assignee creator program sort direction number
    else
        ___x_cmd_gt_get_multi "/repos/${owner_repo}/issues" state labels milestone assignee creator program sort direction number | \
            x jo 2c             .number         .issue_state .assignee.name .title | \
            x csv header --add   Issue_Number    State        Assigner       Title | \
            x csv static_tab
    fi
}

# https://gitee.com/api/v5/swagger#/getV5ReposOwnerRepoIssuesNumber
___x_cmd_gt_repo_issue_info(){
    param:scope     ___x_cmd_gt
    param:dsl       '
options:
    #1              "issue number(Case sensitive.Not with #)"               <>
    --repo|-r       "<owner_path>/<repo_path>"                              <>:RepoPath
    --json|-j       "output origin json data"
'
    param:run
    [ -n "$1" ] || M='accepts 1 arg(issue number), received empty' arg:ret:64
    local number="$1"
    ___x_cmd_gt_param_init_owner_repo
    ___x_cmd_gt_curl get "/repos/${owner_repo}/issues/${number}" | ___x_cmd_gt_issue_info_status_handler
}

# EndSection

# Section: Repo Issue Log

# shellcheck disable=SC2154
# https://gitee.com/api/v5/swagger#/getV5ReposOwnerIssuesNumberOperateLogs
___x_cmd_gt_repo_issue_log(){
    param:scope     ___x_cmd_gt
    param:dsl       '
options:
    #1              "issue number(Case sensitive.Not with #)"       <>
    --repo|-r       "<owner_path>/<repo_path>"                      <>:RepoPath
    --sort          "sort(asc、desc)"                               <>="desc"
    --json|-j       "output origin json data"
'
    param:run
    [ -n "$1" ] || M='accepts 1 arg(issue number), received empty' arg:ret:64
    local number="${1}"
    ___x_cmd_gt_param_init_owner_repo
    if [ -n "$json" ] || [ -n "$ENFORCE_JSON" ]; then
        ___x_cmd_gt_curl get "/repos/${owner_repo##*/}/issues/${number}/operate_logs" repo sort
    else
        ___x_cmd_gt_curl get "/repos/${owner_repo##*/}/issues/${number}/operate_logs" repo sort | \
            x jo 2c             .created_at     .user.login     .action_type    .content | \
            x csv header --add   Time            User            Type            Content | \
            x csv static_tab
    fi
}

# EndSection

___x_cmd_gt_enterprise_issue(){
    param:scope         ___x_cmd_gt
    param:subcmd ___x_cmd_gt_enterprise_issue       \
        ls          "List enterprise issue"         \
        info        "Get  enterprise issue info"
    param:subcmd:try
    param:run

    ___x_cmd_gt_enterprise_issue _param_help_doc
    return 1
}

# Section: Enterprise Issue
# shellcheck disable=SC2154
# https://gitee.com/api/v5/swagger#/getV5EnterprisesEnterpriseIssues
___x_cmd_gt_enterprise_issue_ls(){
    param:scope     ___x_cmd_gt
    param:dsl       '
options:
    --enterprise|-e "enterprise path"                              <>

    --direction     "direction(asc、desc)"                         <>:Direction="desc"
    --sort          "sort(created,updated)"                        <>:Sort="created"
    --state         "state(all,open,progressing,closed,rejected)"  <>:IssueState="open"
    --labels        "labels"                                       <>=""
    --milestone     "milestone"                                    <>=""
    --assignee      "assignee"                                     <>=""
    --creator       "creator"                                      <>=""
    --program       "program"                                      <>=""
    --page          "page"                                         <>="1"
    --per_page      "per_page"                                     <>="20"
    --json|-j       "output origin json data"
'
    param:run
    if [ -n "$json" ] || [ -n "$ENFORCE_JSON" ]; then
        ___x_cmd_gt_get_multi "/enterprises/${enterprise##*/}/issues" state labels sort direction milestone assignee creator program
    else
        ___x_cmd_gt_get_multi "/enterprises/${enterprise##*/}/issues" state labels sort direction milestone assignee creator program | \
            x jo 2c             .number         .issue_state .assignee.name .assignee.remark  .title | \
            x csv header --add   Issue_Number    State        Assigner       AssignerMarkName  Title | \
            x csv static_tab
    fi
}

___x_cmd_gt_enterprise_issue_info(){
    param:scope     ___x_cmd_gt
    param:dsl       '
options:
    #1              "issue number(Case sensitive.Not with #)"                            <>
    --enterprise|-e "enterprise path"                                                    <>
    --json|-j       "output origin json data"
'
    param:run
    [ -n "$1" ] || M='accepts 1 arg(issue number), received empty' arg:ret:64
    local number="${1}"
    ___x_cmd_gt_curl get "/enterprises/${enterprise}/issues/${number}" | ___x_cmd_gt_issue_info_status_handler
}

# EndSection

# Section: User Issue List
# https://gitee.com/api/v5/swagger#/getV5UserIssues
___x_cmd_gt_user_issue(){
    param:scope     ___x_cmd_gt
    param:dsl       '
options:
    --filter        "filter(assigned,created,all)"                 <>:IssueFilter="assigned"
    --state         "state(open,progressing,closed,rejected)"      <>:IssueState="open"
    --direction     "direction(asc、desc)"                         <>:Direction="desc"
    --labels        "labels"                                       <>=""
    --since         "since"                                        <>=""
    --schedule      "schedule"                                     <>=""
    --deadline      "deadline"                                     <>=""
    --created_at    "create date"                                  <>=""
    --finished_at   "finish date"                                  <>=""
    --page          "page"                                         <>="1"
    --per_page      "per_page"                                     <>="20"
    --json|-j       "output origin json data"
'
    param:run
    if [ -n "$json" ] || [ -n "$ENFORCE_JSON" ]; then
        ___x_cmd_gt_get_multi "/user/issues" filter state direction labels since schedule deadline created_at finished_at
    else
        ___x_cmd_gt_get_multi "/user/issues" filter state direction labels since schedule deadline created_at finished_at | \
            x jo 2c             .number         .issue_state .assignee.name .repository.full_name .issue_type .title | \
            x csv header --add   Issue_Number    State        Assigner       Repo                 Type        Title | \
            x csv static_tab
    fi
}
# EndSection

# Section: Org Issue List

# shellcheck disable=SC2154
# https://gitee.com/api/v5/swagger#/getV5OrgsOrgIssues
___x_cmd_gt_org_issue(){
    param:scope     ___x_cmd_gt
    param:dsl       '
options:
    --org           "organization path"                            <>
    --direction     "direction(asc、desc)"                         <>:Direction="desc"
    --sort          "sort(created,updated)"                        <>:Sort="created"
    --state         "state(open,progressing,closed,rejected)"      <>:IssueState="open"
    --filter        "filter(assigned,created,all)"                 <>:IssueFilter="assigned"
    --labels        "labels"                                       <>=""
    --page          "page"                                         <>="1"
    --per_page      "per_page"                                     <>="20"
    --json|-j       "output origin json data"
'
    param:run
    if [ -n "$json" ] || [ -n "$ENFORCE_JSON" ]; then
        ___x_cmd_gt_get_multi "/orgs/${org##*/}/issues" filter state labels sort direction
    else
        ___x_cmd_gt_get_multi "/orgs/${org##*/}/issues" filter state labels sort direction | \
            x jo 2c             .number        .issue_state  .repository.full_name  .title | \
            x csv header --add   Issue_Number   State         Repo                   Title | \
            x csv static_tab
    fi
}

# EndSection

# Section: issue UI
___x_cmd_gt_issue____ui_handler(){
    if [ -n "$json" ] || [ -n "$ENFORCE_JSON" ]; then
        ___x_cmd_cmds_cat
        ___x_cmd_gt_http_error
        return
    fi
    (
        local _id=""
        case "$1" in
            Creating|Modify)
                x jo env .  gt_resp_err=.message gt_resp_err=.error \
                    _id=.number title=.title html_url=.html_url body=.body
                _inf_msg="$1 repo issue successfully"
                _err_msg="$1 repo issue failure"
                ;;
            comment)
                x jo env .  gt_resp_err=.message gt_resp_err=.error \
                    _id=.target.issue.number title=.target.issue.title body=.body
                _data="_id=.target.issue.number title=.target.issue.title body=.body"
                _inf_msg="Successfully"
                _err_msg="Update Comment failure"
                ;;
        esac
        if [ -n "$_id" ]; then
            ___x_cmd_ui_tf  true "${_inf_msg}:" ${title:+"Title: $title"} ${html_url:+"URL: $html_url"} ${body:+"Body: $body"}
        else
            ___x_cmd_ui_tf false "${_err_msg}:" >&2
            ___x_cmd_gt____handle_resp
            return 1
        fi
    )

}

# shellcheck disable=SC2154,SC2059
___x_cmd_gt_issue_info_status_handler(){
    if [ -n "$json" ] || [ -n "$ENFORCE_JSON" ]; then
        ___x_cmd_cmds_cat
        ___x_cmd_gt_http_error
        return
    fi
    (
        local id=""
        x jo env . id=.number title=.title state=.state assignee=.assignee.name html_url=.html_url body=.body gt_resp_err=.message
        if [ -n "$id" ]; then
            ___x_cmd_ui_tf true  "Success:" "ID: $id" "URL: $html_url" "State: $state" "Assignee: $assignee" "Title: $title" "Body: |"
            if ___x_cmd_gx_stdout_is_no_color; then
                x str ml wrap "$(printf "%s\n" "$body" | x bat --paging=never --plain -lmd)" '      '
            else
                x str ml wrap "$(printf "%s\n" "$body" | x bat --paging=never --plain -lmd --color=always)" '      '
            fi
        else
            ___x_cmd_ui_tf false "Getting issue info failure by $owner_repo $number:" >&2
            ___x_cmd_gt____handle_resp
            return 1
        fi
    )
}
# EndSection

# Section: Issue Comment

___x_cmd_gt_repo_issue_comment(){
    param:scope         ___x_cmd_gt
    param:subcmd ___x_cmd_gt_repo_issue_comment        \
        ls              "list all comment"             \
        create          "create comment"               \
        "edit|ed"       "Edit   comment"               \
        rm              "remove comment"
    param:subcmd:try
    param:run

    ___x_cmd_gt_repo_issue_comment _param_help_doc
    return 1
}

# https://gitee.com/api/v5/swagger#/getV5ReposOwnerRepoIssuesNumberComments
___x_cmd_gt_repo_issue_comment_ls(){
    param:scope     ___x_cmd_gt
    param:dsl       '
options:
    #1              "issue number(Case sensitive.Not with #)"                           <>
    --repo|-r       "<owner_path>/<repo_path>"                                          <>:RepoPath
    --since         "since"                                                             <>=""
    --page          "page"                                                              <>=""
    --per_page      "per_page"                                                          <>=""
    --order         "order(asc, desc)"                                                  <>="asc"
    --json|-j       "output origin json data"
'
    param:run
    local number="$1"
    ___x_cmd_gt_param_init_owner_repo

    if [ -n "$json" ] || [ -n "$ENFORCE_JSON" ]; then
        ___x_cmd_gt_get_multi "/repos/${owner_repo}/issues/$number/comments" since order
    else
        ___x_cmd_gt_get_multi "/repos/${owner_repo}/issues/$number/comments" since order | \
            x jo 2c             .id         .target.issue.number  .target.issue.title  .user.login | \
            x csv header --add   Commit_Id   Issue_Number          Title                User       | \
            x csv static_tab
    fi
}

# shellcheck disable=SC2086,SC2154
# https://gitee.com/api/v5/swagger#/postV5ReposOwnerRepoIssuesNumberComments
___x_cmd_gt_repo_issue_comment_create(){
    param:scope     ___x_cmd_gt
    param:dsl       '
options:
    #1              "issue number(Case sensitive.Not with #)"                           <>
    --repo|-r       "<owner_path>/<repo_path>"                                          <>:RepoPath
    --body          "The contents of the comment"                                       <>
    --json|-j       "output origin json data"
'
    param:run
    local number="$1"
    local gen_gt_json
    gen_gt_json="$(param:option2json -repo -number)"
    gt:debug "$gen_gt_json"

    ___x_cmd_gt_curl post "/repos/${owner##*/}/${repo##*/}/issues/$number/comments" "gen_gt_json" | ___x_cmd_gt_issue____ui_handler comment
}

# https://gitee.com/api/v5/swagger#/patchV5ReposOwnerRepoIssuesCommentsId
___x_cmd_gt_repo_issue_comment_edit(){
    param:scope     ___x_cmd_gt
    param:dsl       '
options:
    #1              "comments id"                           <>
    --repo|-r       "<owner_path>/<repo_path>"              <>:RepoPath
    --body          "The contents of the comment"           <>
    --json|-j       "output origin json data"
'
    param:run
    local _id="$1"
    local gen_gt_json
    gen_gt_json="$(param:option2json -repo)"
    gt:debug "$gen_gt_json"

    ___x_cmd_gt_curl patch "/repos/${owner##*/}/${repo##*/}/issues/comments/${_id}" "gen_gt_json" | ___x_cmd_gt_issue____ui_handler comment
}

# shellcheck disable=SC2181,SC2034
# https://gitee.com/api/v5/swagger#/deleteV5ReposOwnerRepoIssuesCommentsId
___x_cmd_gt_repo_issue_comment_rm(){
    param:scope     ___x_cmd_gt
    param:dsl       '
options:
    #1              "comments id"                       <>
    --repo|-r       "<owner_path>/<repo_path>"          <>:RepoPath
'
    param:run
    local id="$1"
    ___x_cmd_gt_param_init_owner_repo
    ___x_cmd_gt_curl del "/repos/${owner_repo}/issues/comments/${id}" |  (
            [ -z "$___X_CMD_GT_IN_TEST" ] || { ___x_cmd_cmds_cat; return; }
            x jo env . gt_resp_err=.message gt_resp_err=.error
            if ___x_cmd_gt_http_error; then
                ___x_cmd_ui_tf true  "[Success]: Deleted $id comment on $owner_repo"
            else
                ___x_cmd_ui_tf false "Deleted $id comment on $owner_repo failure:" >&2
                ___x_cmd_gt____handle_resp
                return 1
            fi
        )
}

# EndSection
