#!/usr/bin/env bash
# ─────────────────────────────────────────────────────────────────────
# Scenario 4: Multi-Repo Collaboration
# Flow: Cross-repo issue tracking → PR status dashboard → Coordinated release
#
# Commands chained:
#   1. repo +list      -- list all repos in org
#   2. issue +list     -- fetch open/closed issues from each repo
#   3. pr +list        -- fetch open/merged PRs from each repo
#   4. release +list   -- check latest release across repos
#   5. Generate HTML dashboard (summary cards + table + per-repo details)
#   6. release +create -- (optional) coordinated release across all repos
# ─────────────────────────────────────────────────────────────────────

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/lib/common.sh"

usage() {
    echo "Usage: $0 --org ORG [--repos REPO1,REPO2,...] [--release TAG] [--output FILE] [--dry-run]"
    echo ""
    echo "  --org ORG              Organization / user name (required)"
    echo "  --repos REPO1,REPO2    Comma-separated repo list (default: all repos in org)"
    echo "  --release TAG          Coordinated release tag to create across all repos"
    echo "  --output FILE          Output HTML dashboard file (default: dashboard.html)"
    echo "  --detail-limit N       Max open issues/PRs listed per repo in details (default: 10)"
    echo "  --dry-run              Preview actions without creating releases"
    exit 1
}

DRY_RUN=false
ORG=""
REPOS=""
RELEASE_TAG=""
OUTPUT_FILE="dashboard.html"
DETAIL_LIMIT=10

while [[ $# -gt 0 ]]; do
    case "$1" in
        --org)          ORG="$2"; shift 2 ;;
        --repos)        REPOS="$2"; shift 2 ;;
        --release)      RELEASE_TAG="$2"; shift 2 ;;
        --output)       OUTPUT_FILE="$2"; shift 2 ;;
        --detail-limit) DETAIL_LIMIT="$2"; shift 2 ;;
        --dry-run)      DRY_RUN="true"; shift ;;
        --help|-h)      usage ;;
        *)              log_err "Unknown arg: $1"; usage ;;
    esac
done

if [[ -z "$ORG" ]]; then
    log_err "Missing required parameter: --org"
    usage
fi

check_auth

# ── HTML escape helper ───────────────────────────────────────────────
html_escape() {
    local s="$1"
    s="${s//&/&amp;}"
    s="${s//</&lt;}"
    s="${s//>/&gt;}"
    s="${s//\"/&quot;}"
    echo "$s"
}

# ── Health score (0-100) — aligned with gitlink-health skill ─────────
# Model: start 100, deduct. Core 75 (issue efficiency / PR efficiency /
# activity, -25 each), auxiliary 25 (issue backlog -10, PR backlog -10,
# no recent release -5). Time-based core metrics are approximated by
# list-level ratios for a fast multi-repo scan.
#   release_age: days since latest release, -1 = no release.
compute_health() {
    local open_issues="$1" closed_issues="$2" open_prs="$3" merged_prs="$4" release_age="$5"
    awk -v oi="$open_issues" -v ci="$closed_issues" -v op="$open_prs" \
        -v mp="$merged_prs" -v age="$release_age" 'BEGIN {
        health = 100
        # ── 核心指标 (75) ──
        # Issue 处理效率 (proxy for 响应慢): 解决率 < 50% 扣 25
        ti = oi + ci
        res = (ti > 0) ? ci / ti : 1
        if (res < 0.5) health -= 25
        # PR 合并效率 (proxy for 合并慢): 合并率 < 50% 扣 25
        tp = op + mp
        mr = (tp > 0) ? mp / tp : 1
        if (mr < 0.5) health -= 25
        # 活跃度低: 无任何已完成工作 (合并 PR + 关闭 Issue == 0) 扣 25
        if ((mp + ci) == 0) health -= 25
        # ── 辅助指标 (25) ──
        if (oi > 20) health -= 10          # Issue 积压
        if (op > 10) health -= 10          # PR 积压
        if (age < 0 || age > 30) health -= 5   # 无近期发布 (>30天或无)
        if (health < 0) health = 0
        if (health > 100) health = 100
        printf "%d", health
    }'
}

# Map score → (grade, css class) — 5 bands per gitlink-health skill
health_grade() {
    local score="$1"
    if   [[ "$score" -ge 90 ]]; then echo "优秀|excellent"
    elif [[ "$score" -ge 70 ]]; then echo "良好|good"
    elif [[ "$score" -ge 50 ]]; then echo "一般|moderate"
    elif [[ "$score" -ge 30 ]]; then echo "需关注|attention"
    else                             echo "严重|critical"
    fi
}

# ── Step 1: List Repositories ────────────────────────────────────────
log_title "多仓库协同看板 (Multi-Repo Collaboration Dashboard)"

log_step "获取组织 $ORG 下的仓库列表..."
REPOS_JSON=$(gl_check repo +list --user "$ORG" --limit 100)
REPOS_DATA_PATH='(.data.projects // .data | if type == "array" then . else [] end)'
ALL_REPO_COUNT=$(echo "$REPOS_JSON" | jq "$REPOS_DATA_PATH | length")
log_ok "组织下共有 $ALL_REPO_COUNT 个仓库"

# Filter repos if --repos specified
REPO_LIST=()
if [[ -n "$REPOS" ]]; then
    IFS=',' read -ra REPO_LIST <<< "$REPOS"
    log_info "仅处理指定仓库: ${REPO_LIST[*]}"
else
    for i in $(seq 0 $((ALL_REPO_COUNT - 1))); do
        RNAME=$(echo "$REPOS_JSON" | jq -r "$REPOS_DATA_PATH[$i].name // $REPOS_DATA_PATH[$i].identifier // empty")
        [[ -n "$RNAME" ]] && REPO_LIST+=("$RNAME")
    done
fi

if [[ "${#REPO_LIST[@]}" -eq 0 ]]; then
    log_err "没有可处理的仓库。请检查 --org 是否正确，或用 --repos 指定。"
    exit 1
fi
log_ok "将处理 ${#REPO_LIST[@]} 个仓库"

# ── Step 2-4: Collect data across repos ──────────────────────────────
log_title "跨仓库数据采集"

DASHBOARD_ROWS=""
REPO_DETAILS=""
TOTAL_ACTIVITY=0
TOTAL_OPEN_ISSUES=0
TOTAL_OPEN_PRS=0
TOTAL_MERGED_PRS=0
HEALTH_SUM=0

ISSUE_DATA_PATH='(.data.issues // .data | if type == "array" then . else [] end)'
PR_DATA_PATH='(.data.issues // .data.pulls // .data | if type == "array" then . else [] end)'

for repo in "${REPO_LIST[@]}"; do
    divider
    log_step "处理 $ORG/$repo..."

    ISSUES_JSON=$(gl_run issue +list --owner "$ORG" --repo "$repo" --state open --limit 50)
    OPEN_ISSUES=$(echo "$ISSUES_JSON" | jq "$ISSUE_DATA_PATH | length" 2>/dev/null || echo "0")
    [[ "$OPEN_ISSUES" =~ ^[0-9]+$ ]] || OPEN_ISSUES=0

    CLOSED_JSON=$(gl_run issue +list --owner "$ORG" --repo "$repo" --state closed --limit 50)
    CLOSED_ISSUES=$(echo "$CLOSED_JSON" | jq "$ISSUE_DATA_PATH | length" 2>/dev/null || echo "0")
    [[ "$CLOSED_ISSUES" =~ ^[0-9]+$ ]] || CLOSED_ISSUES=0

    PRS_JSON=$(gl_run pr +list --owner "$ORG" --repo "$repo" --state open --limit 50)
    OPEN_PRS=$(echo "$PRS_JSON" | jq "$PR_DATA_PATH | length" 2>/dev/null || echo "0")
    [[ "$OPEN_PRS" =~ ^[0-9]+$ ]] || OPEN_PRS=0

    MERGED_JSON=$(gl_run pr +list --owner "$ORG" --repo "$repo" --state merged --limit 50)
    MERGED_PRS=$(echo "$MERGED_JSON" | jq "$PR_DATA_PATH | length" 2>/dev/null || echo "0")
    [[ "$MERGED_PRS" =~ ^[0-9]+$ ]] || MERGED_PRS=0

    RELEASES_JSON=$(gl_run release +list --owner "$ORG" --repo "$repo" --limit 1)
    REL_ARR='(.data.releases // .data | if type == "array" then . else [] end)'
    LATEST_RELEASE=$(echo "$RELEASES_JSON" | jq -r "$REL_ARR[0].tag_name // $REL_ARR[0].name // \"none\"" 2>/dev/null)
    [[ -z "$LATEST_RELEASE" || "$LATEST_RELEASE" == "null" ]] && LATEST_RELEASE="none"

    # Release age in days (-1 if none / unparseable)
    RELEASE_AGE=-1
    if [[ "$LATEST_RELEASE" != "none" ]]; then
        REL_DATE=$(echo "$RELEASES_JSON" | jq -r "$REL_ARR[0].created_at // $REL_ARR[0].created_on // $REL_ARR[0].published_at // empty" 2>/dev/null)
        REL_DATE="${REL_DATE%% *}"; REL_DATE="${REL_DATE%%T*}"
        if [[ "$REL_DATE" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}$ ]]; then
            RELEASE_AGE=$(days_between "$REL_DATE" "$(date_today)")
        else
            RELEASE_AGE=0   # has release but no parseable date → treat as recent
        fi
    fi

    # Health score (aligned with gitlink-health skill)
    HEALTH=$(compute_health "$OPEN_ISSUES" "$CLOSED_ISSUES" "$OPEN_PRS" "$MERGED_PRS" "$RELEASE_AGE")
    IFS='|' read -r GRADE_LABEL GRADE_CLASS <<< "$(health_grade "$HEALTH")"

    log_ok "$repo: Issue(开:$OPEN_ISSUES 闭:$CLOSED_ISSUES) PR(开:$OPEN_PRS 合:$MERGED_PRS) Release:$LATEST_RELEASE 健康度:$HEALTH($GRADE_LABEL)"

    # ── Collect open issue details ──
    ISSUE_ROWS=""
    if [[ "$OPEN_ISSUES" -gt 0 ]]; then
        limit=$(( OPEN_ISSUES < DETAIL_LIMIT ? OPEN_ISSUES : DETAIL_LIMIT ))
        for ii in $(seq 0 $((limit - 1))); do
            I_ID=$(echo "$ISSUES_JSON" | jq -r "$ISSUE_DATA_PATH[$ii].id // $ISSUE_DATA_PATH[$ii].number // empty")
            I_TITLE=$(echo "$ISSUES_JSON" | jq -r "$ISSUE_DATA_PATH[$ii].name // $ISSUE_DATA_PATH[$ii].subject // $ISSUE_DATA_PATH[$ii].title // empty")
            I_AUTHOR=$(echo "$ISSUES_JSON" | jq -r "$ISSUE_DATA_PATH[$ii].author_name // $ISSUE_DATA_PATH[$ii].author_login // $ISSUE_DATA_PATH[$ii].author.login // \"unknown\"")
            ISSUE_ROWS+="<tr><td>#$(html_escape "$I_ID")</td><td>$(html_escape "$I_TITLE")</td><td>@$(html_escape "$I_AUTHOR")</td></tr>"
        done
    fi

    # ── Collect open PR details ──
    PR_ROWS=""
    if [[ "$OPEN_PRS" -gt 0 ]]; then
        limit=$(( OPEN_PRS < DETAIL_LIMIT ? OPEN_PRS : DETAIL_LIMIT ))
        for pi in $(seq 0 $((limit - 1))); do
            P_ID=$(echo "$PRS_JSON" | jq -r "$PR_DATA_PATH[$pi].pull_request_number // $PR_DATA_PATH[$pi].number // $PR_DATA_PATH[$pi].id // empty")
            P_TITLE=$(echo "$PRS_JSON" | jq -r "$PR_DATA_PATH[$pi].subject // $PR_DATA_PATH[$pi].title // $PR_DATA_PATH[$pi].name // empty")
            P_AUTHOR=$(echo "$PRS_JSON" | jq -r "$PR_DATA_PATH[$pi].author_name // $PR_DATA_PATH[$pi].author_login // $PR_DATA_PATH[$pi].author.login // \"unknown\"")
            PR_ROWS+="<tr><td>#$(html_escape "$P_ID")</td><td>$(html_escape "$P_TITLE")</td><td>@$(html_escape "$P_AUTHOR")</td></tr>"
        done
    fi

    # ── Per-repo collapsible detail section ──
    [[ -z "$ISSUE_ROWS" ]] && ISSUE_ROWS="<tr><td colspan=\"3\" class=\"empty\">无未关闭 Issue</td></tr>"
    [[ -z "$PR_ROWS" ]] && PR_ROWS="<tr><td colspan=\"3\" class=\"empty\">无未合并 PR</td></tr>"
    REPO_DETAILS+="<details><summary><span class=\"badge $GRADE_CLASS\">$HEALTH</span> $(html_escape "$repo") — Issue 开 $OPEN_ISSUES / PR 开 $OPEN_PRS</summary>
      <div class=\"detail-grid\">
        <div><h4>未关闭 Issue（最多 $DETAIL_LIMIT 条）</h4>
          <table class=\"detail-table\"><thead><tr><th>编号</th><th>标题</th><th>作者</th></tr></thead><tbody>$ISSUE_ROWS</tbody></table></div>
        <div><h4>未合并 PR（最多 $DETAIL_LIMIT 条）</h4>
          <table class=\"detail-table\"><thead><tr><th>编号</th><th>标题</th><th>作者</th></tr></thead><tbody>$PR_ROWS</tbody></table></div>
      </div>
    </details>"

    # Accumulate totals
    TOTAL_ACTIVITY=$((TOTAL_ACTIVITY + OPEN_ISSUES + CLOSED_ISSUES + OPEN_PRS + MERGED_PRS))
    TOTAL_OPEN_ISSUES=$((TOTAL_OPEN_ISSUES + OPEN_ISSUES))
    TOTAL_OPEN_PRS=$((TOTAL_OPEN_PRS + OPEN_PRS))
    TOTAL_MERGED_PRS=$((TOTAL_MERGED_PRS + MERGED_PRS))
    HEALTH_SUM=$((HEALTH_SUM + HEALTH))

    REL_DISPLAY="$LATEST_RELEASE"
    [[ "$REL_DISPLAY" == "none" ]] && REL_DISPLAY="—"

    DASHBOARD_ROWS+="<tr>
        <td><a href=\"https://gitlink.org.cn/$ORG/$repo\" target=\"_blank\">$(html_escape "$repo")</a></td>
        <td>$OPEN_ISSUES</td>
        <td>$CLOSED_ISSUES</td>
        <td>$OPEN_PRS</td>
        <td>$MERGED_PRS</td>
        <td>$(html_escape "$REL_DISPLAY")</td>
        <td><span class=\"badge $GRADE_CLASS\">$HEALTH</span> <span class=\"grade $GRADE_CLASS\">$GRADE_LABEL</span></td>
    </tr>"
done

# Average health
AVG_HEALTH=0
[[ "${#REPO_LIST[@]}" -gt 0 ]] && AVG_HEALTH=$((HEALTH_SUM / ${#REPO_LIST[@]}))

# ── Step 5: Generate HTML Dashboard ──────────────────────────────────
log_title "生成 HTML 看板"
log_step "写入 $OUTPUT_FILE..."

TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

cat > "$OUTPUT_FILE" << HTMLEOF
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>多仓库协同看板 - $ORG</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Microsoft YaHei', sans-serif; background: #f0f2f5; padding: 24px; color: #1f2329; }
.container { max-width: 1280px; margin: 0 auto; }
h1 { color: #1f2329; margin-bottom: 6px; font-size: 26px; }
.timestamp { color: #8a919f; font-size: 13px; margin-bottom: 24px; }
.summary { display: grid; grid-template-columns: repeat(5, 1fr); gap: 16px; margin-bottom: 28px; }
.card { background: #fff; border-radius: 10px; padding: 18px 20px; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
.card h3 { color: #8a919f; font-size: 13px; margin-bottom: 8px; font-weight: 500; }
.card .value { font-size: 30px; font-weight: 700; }
.card.blue .value { color: #2f80ed; }
.card.orange .value { color: #f2994a; }
.card.purple .value { color: #9b51e0; }
.card.green .value { color: #27ae60; }
.card.teal .value { color: #17a2b8; }
h2 { font-size: 18px; margin: 24px 0 14px; color: #1f2329; }
table { width: 100%; border-collapse: collapse; background: #fff; border-radius: 10px; overflow: hidden; box-shadow: 0 1px 3px rgba(0,0,0,0.08); }
th { background: #2f80ed; color: #fff; padding: 12px 16px; text-align: left; font-weight: 500; font-size: 14px; }
td { padding: 11px 16px; border-bottom: 1px solid #eef0f3; font-size: 14px; }
tr:last-child td { border-bottom: none; }
tr:hover td { background: #f7f9fc; }
a { color: #2f80ed; text-decoration: none; font-weight: 500; }
a:hover { text-decoration: underline; }
.badge { display: inline-block; min-width: 34px; text-align: center; padding: 2px 8px; border-radius: 12px; color: #fff; font-weight: 700; font-size: 13px; }
.grade { font-size: 13px; margin-left: 4px; }
.excellent, .badge.excellent { background: #27ae60; } .grade.excellent { color: #27ae60; background: none; }
.good, .badge.good { background: #2f80ed; } .grade.good { color: #2f80ed; background: none; }
.moderate, .badge.moderate { background: #f2c94c; } .grade.moderate { color: #d9a400; background: none; }
.attention, .badge.attention { background: #f2994a; } .grade.attention { color: #f2994a; background: none; }
.critical, .badge.critical { background: #eb5757; } .grade.critical { color: #eb5757; background: none; }
details { background: #fff; border-radius: 10px; margin-bottom: 12px; box-shadow: 0 1px 3px rgba(0,0,0,0.08); overflow: hidden; }
summary { padding: 14px 18px; cursor: pointer; font-weight: 600; font-size: 15px; user-select: none; }
summary:hover { background: #f7f9fc; }
.detail-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 18px; padding: 0 18px 18px; }
.detail-table th { background: #eef2f8; color: #4a5568; padding: 8px 12px; font-size: 13px; }
.detail-table td { padding: 8px 12px; font-size: 13px; }
.detail-table h4, .detail-grid h4 { font-size: 14px; margin-bottom: 8px; color: #4a5568; }
.empty { color: #b0b7c3; text-align: center; font-style: italic; }
@media (max-width: 900px) { .summary { grid-template-columns: repeat(2, 1fr); } .detail-grid { grid-template-columns: 1fr; } }
</style>
</head>
<body>
<div class="container">
<h1>多仓库协同看板</h1>
<p class="timestamp">生成时间：$TIMESTAMP ｜ 组织：$ORG</p>
<div class="summary">
    <div class="card blue"><h3>仓库总数</h3><div class="value">${#REPO_LIST[@]}</div></div>
    <div class="card orange"><h3>未关闭 Issue</h3><div class="value">$TOTAL_OPEN_ISSUES</div></div>
    <div class="card purple"><h3>未合并 PR</h3><div class="value">$TOTAL_OPEN_PRS</div></div>
    <div class="card green"><h3>已合并 PR</h3><div class="value">$TOTAL_MERGED_PRS</div></div>
    <div class="card teal"><h3>平均健康度</h3><div class="value">$AVG_HEALTH</div></div>
</div>

<h2>仓库概览</h2>
<table>
<thead><tr><th>仓库</th><th>未关闭 Issue</th><th>已关闭 Issue</th><th>未合并 PR</th><th>已合并 PR</th><th>最新 Release</th><th>健康度</th></tr></thead>
<tbody>$DASHBOARD_ROWS</tbody>
</table>

<h2>仓库详情</h2>
$REPO_DETAILS
</div>
</body>
</html>
HTMLEOF

log_ok "看板已保存: $OUTPUT_FILE"

# ── Step 6: Coordinated Release ──────────────────────────────────────
if [[ -n "$RELEASE_TAG" ]]; then
    log_title "协调发版: $RELEASE_TAG"

    if [[ "$DRY_RUN" == "true" ]]; then
        log_warn "[DRY RUN] 将为以下 ${#REPO_LIST[@]} 个仓库创建 Release $RELEASE_TAG:"
        for repo in "${REPO_LIST[@]}"; do
            log_warn "  [DRY RUN] $ORG/$repo → $RELEASE_TAG"
        done
    else
        RELEASE_OK=0
        RELEASE_FAIL=0
        for repo in "${REPO_LIST[@]}"; do
            log_step "为 $ORG/$repo 创建 Release..."
            RELEASE_RESULT=$(gl_run release +create --owner "$ORG" --repo "$repo" \
                --tag "$RELEASE_TAG" --name "Release $RELEASE_TAG" \
                --body "Coordinated release $RELEASE_TAG for $ORG/$repo" 2>&1) || true

            if [[ "$(json_ok "$RELEASE_RESULT")" == "true" ]]; then
                log_ok "Release $RELEASE_TAG 已在 $repo 创建"
                RELEASE_OK=$((RELEASE_OK + 1))
            else
                log_warn "Release 创建失败: $repo (tag 可能已存在)"
                RELEASE_FAIL=$((RELEASE_FAIL + 1))
            fi
        done
        log_info "协调发版结果: 成功 $RELEASE_OK / 失败 $RELEASE_FAIL"
    fi
fi

# ─────────────────────────────────────────────────────────────────────
log_title "多仓库看板完成"
# ─────────────────────────────────────────────────────────────────────

echo -e "${GREEN}汇总:${NC}"
echo "  处理仓库:     ${#REPO_LIST[@]}"
echo "  未关闭 Issue: $TOTAL_OPEN_ISSUES"
echo "  未合并 PR:    $TOTAL_OPEN_PRS"
echo "  已合并 PR:    $TOTAL_MERGED_PRS"
echo "  平均健康度:   $AVG_HEALTH / 100"
echo "  看板文件:     $OUTPUT_FILE"
[[ -n "$RELEASE_TAG" ]] && echo "  协调发版:     $RELEASE_TAG$([[ "$DRY_RUN" == "true" ]] && echo " (dry-run)")"
echo ""
echo -e "${CYAN}打开看板:${NC}"
echo "  start $OUTPUT_FILE     # Windows"
echo "  xdg-open $OUTPUT_FILE  # Linux"
echo "  open $OUTPUT_FILE      # macOS"
echo ""
