# ----------------------------------------------------------------
# Scenario 1a: Webhook Setup — Register on GitLink Platform
# Role: 在 GitLink 平台上注册 webhook，连接"平台事件"到"本地接收器"
#
# 这是整个实时链路的最后一块拼图——把 GitLink 平台的 Issue 创建事件
# 和本地的 01a-webhook-listener.ps1 接收器连接起来。
#
# 完整链路:
#   GitLink Issue 创建
#       → Webhook POST 到 <WebhookUrl>
#       → 01a-webhook-listener.ps1 (接收 HTTP 请求)
#       → 01a-issue-triage.ps1 (AI 分类 + 打标签 + 分配)
#
# 前置条件:
#   方案A (本地开发): 先启动 ngrok → 再启动 01a-webhook-listener.ps1 → 再运行本脚本
#   方案B (公网服务器): 先启动 01a-webhook-listener.ps1 → 再运行本脚本（直接给公网URL）
# ----------------------------------------------------------------
#Requires -Version 5.1

param(
    [string]$WebhookUrl = "",

    [string]$Owner = "",
    [string]$Repo = "",
    [string]$Secret = "",
    [string]$Events = "issue",
    [string]$Description = "Community Ops — Issue Auto-Triage (created by gitlink-cli)",
    [switch]$DryRun,
    [switch]$ListExisting,
    [switch]$DeleteExisting,
    [switch]$Force,
    [switch]$Help
)

$ErrorActionPreference = "Stop"
Import-Module "$PSScriptRoot/lib/common.psm1" -Force -WarningAction SilentlyContinue

if ($Help) {
    Write-Host "Usage: powershell 01a-webhook-setup.ps1 -WebhookUrl URL [-Owner OWNER] [-Repo REPO] [-Secret SECRET] [-Events EVENTS] [-DryRun]"
    Write-Host ""
    Write-Host "  在 GitLink 平台上注册 webhook，将 Issue 创建事件连接到本地接收器。"
    Write-Host ""
    Write-Host "  -WebhookUrl URL    (必填) Webhook 回调地址，GitLink 会向此 URL POST 事件"
    Write-Host "                     - 本地开发: https://xxx.ngrok-free.app/webhook"
    Write-Host "                     - 公网服务器: https://your-server.com:8080/webhook"
    Write-Host "  -Owner OWNER       仓库所有者（在git仓库内可自动检测）"
    Write-Host "  -Repo  REPO        仓库名称（在git仓库内可自动检测）"
    Write-Host "  -Secret SECRET     HMAC 密钥（需与 01a-webhook-listener.ps1 的 -Secret 一致）"
    Write-Host "  -Events EVENTS     触发事件类型（默认: issue）"
    Write-Host "  -Description DESC  Webhook 描述"
    Write-Host "  -ListExisting      列出当前仓库已有的 webhook"
    Write-Host "  -DeleteExisting    删除当前仓库所有非 gitlink-cli 创建的 issue 类 webhook（需配合 -Force）"
    Write-Host "  -Force             配合 -DeleteExisting 使用"
    Write-Host "  -DryRun            预览模式"
    Write-Host ""
    Write-Host "  部署步骤:"
    Write-Host "    # 终端 1: 启动 ngrok（本地开发）"
    Write-Host "    ngrok http 8080"
    Write-Host ""
    Write-Host "    # 终端 2: 启动接收器"
    Write-Host "    powershell workflows/01a-webhook-listener.ps1 -Port 8080 -Secret 'your-secret'"
    Write-Host ""
    Write-Host "    # 终端 3: 注册 webhook（ngrok 提供的 URL）"
    Write-Host "    powershell workflows/01a-webhook-setup.ps1 -WebhookUrl 'https://xxx.ngrok-free.app/webhook' -Secret 'your-secret'"
    exit 0
}

if (-not $WebhookUrl) { Log-Err "WebhookUrl is required (use -Help for usage)"; exit 1 }

Check-Auth
$r = Resolve-OwnerRepo $Owner $Repo
$Owner = $r.Owner; $Repo = $r.Repo

# ================================================================
# Validation
# ================================================================
Log-Title "Webhook Setup: $Owner/$Repo"

# Validate URL format
if ($WebhookUrl -notmatch '^https?://') {
    Log-Err "Webhook URL must start with http:// or https://"
    Log-Info "For GitLink platform, HTTPS is required. Use ngrok for local dev: ngrok http 8080"
    exit 1
}

if ($WebhookUrl -notmatch '^https://') {
    Log-Warn "GitLink requires HTTPS URLs for webhooks. Your URL uses HTTP which may be rejected."
    Log-Info "Consider using ngrok to get an HTTPS URL: ngrok http <port>"
}

Write-Host "  Owner:       $Owner"
Write-Host "  Repo:        $Repo"
Write-Host "  Webhook URL: $WebhookUrl"
Write-Host "  Events:      $Events"
Write-Host "  Secret:      $(if ($Secret) { '***configured***' } else { '(not set)' })"
Write-Host "  Description: $Description"
Divider

# ================================================================
# List existing webhooks
# ================================================================
if ($ListExisting -or $DeleteExisting) {
    Log-Title "Existing Webhooks"

    $listResult = Invoke-GL webhook,+list,--owner,$Owner,--repo,$Repo
    if (-not $listResult) {
        Log-Warn "Could not list webhooks (API may not be available or no webhooks)"
    } else {
        try {
            $listData = $listResult | ConvertFrom-Json
            if ($listData.ok -and $listData.data) {
                $webhooks = @()
                if ($listData.data.webhooks) { $webhooks = @($listData.data.webhooks) }
                elseif ($listData.data -is [array]) { $webhooks = $listData.data }

                if ($webhooks.Count -eq 0) {
                    Log-Info "No webhooks configured for this repo"
                } else {
                    Write-Host ""
                    foreach ($wh in $webhooks) {
                        $whId = if ($wh.id) { $wh.id } else { "?" }
                        $whUrl = if ($wh.hook_url) { $wh.hook_url } elseif ($wh.url) { $wh.url } else { "?" }
                        $whActive = if ($wh.is_active -ne $null) { $wh.is_active } elseif ($wh.active -ne $null) { $wh.active } else { "?" }
                        $whEvents = if ($wh.events) { ($wh.events -join ',') } else { "?" }
                        $whDesc = if ($wh.description) { $wh.description } else { "(no description)" }
                        Write-Host "  [#$whId] $whUrl" -ForegroundColor Cyan
                        Write-Host "    Active: $whActive | Events: $whEvents"
                        Write-Host "    $whDesc"
                        Write-Host ""
                    }
                }
            }
        } catch {
            Log-Warn "Could not parse webhook list: $_"
            Log-Info "Raw output: $listResult"
        }
    }
}

# ================================================================
# Delete existing issue-related webhooks (cleanup before create)
# ================================================================
if ($DeleteExisting) {
    if (-not $Force) {
        Log-Warn "-DeleteExisting requires -Force flag for safety. Add -Force to confirm deletion."
    } else {
        Log-Warn "Removing existing webhooks that match issue events..."

        $listResult = Invoke-GL webhook,+list,--owner,$Owner,--repo,$Repo
        if ($listResult) {
            try {
                $listData = $listResult | ConvertFrom-Json
                $webhooks = @()
                if ($listData.data.webhooks) { $webhooks = @($listData.data.webhooks) }
                elseif ($listData.data -is [array]) { $webhooks = $listData.data }

                foreach ($wh in $webhooks) {
                    $whId = if ($wh.id) { $wh.id } else { $null }
                    $whEvents = if ($wh.events) { $wh.events } else { @() }
                    $whUrl = if ($wh.hook_url) { $wh.hook_url } else { "" }

                    # Only delete issue-related ones that point to gitlink-cli created URLs
                    $isIssueWebhook = ($whEvents -contains "issue") -or ($whEvents -is [string] -and $whEvents -match "issue")
                    if ($isIssueWebhook) {
                        if ($DryRun) {
                            Log-Warn "[DRY RUN] Would delete webhook #$whId ($whUrl)"
                        } else {
                            Log-Step "Deleting webhook #$whId..."
                            $delResult = Invoke-GL webhook,+delete,--owner,$Owner,--repo,$Repo,--id,$whId
                            if ($delResult) {
                                Log-Ok "Deleted webhook #$whId"
                            } else {
                                Log-Warn "Failed to delete webhook #$whId"
                            }
                        }
                    }
                }
            } catch { }
        }
    }

    if (-not $ListExisting) {
        Log-Info "Cleanup complete. Proceeding to create new webhook..."
    } else {
        # User just wanted to list, exit
        exit 0
    }
}

if ($ListExisting) { exit 0 }

# ================================================================
# Check for existing webhook with same URL
# ================================================================
Log-Step "Checking for existing webhooks with same URL..."
$listResult = Invoke-GL webhook,+list,--owner,$Owner,--repo,$Repo
$existingId = $null
if ($listResult) {
    try {
        $listData = $listResult | ConvertFrom-Json
        $webhooks = @()
        if ($listData.data.webhooks) { $webhooks = @($listData.data.webhooks) }
        elseif ($listData.data -is [array]) { $webhooks = $listData.data }

        foreach ($wh in $webhooks) {
            if ($wh.hook_url -eq $WebhookUrl -or $wh.url -eq $WebhookUrl) {
                $existingId = $wh.id
                break
            }
        }
    } catch { }
}

if ($existingId) {
    Log-Warn "A webhook with URL '$WebhookUrl' already exists (ID: #$existingId)"
    Log-Info "To replace it, delete the existing one first with:"
    Log-Info "  gitlink-cli webhook +delete --owner $Owner --repo $Repo --id $existingId"
    Log-Info "Or run this script with -DeleteExisting -Force to clean up"
    exit 1
}
Log-Ok "No duplicate webhook found"

# ================================================================
# Register Webhook on GitLink
# ================================================================
Log-Title "Registering Webhook"

# Build command arguments
$createArgs = @(
    "webhook", "+create",
    "--owner", $Owner,
    "--repo", $Repo,
    "--url", $WebhookUrl,
    "--events", $Events,
    "--description", $Description
)

if ($Secret) {
    $createArgs += @("--secret", $Secret)
}

Log-Step "Creating webhook on GitLink platform..."
Log-Info "Command: gitlink-cli $($createArgs -join ' ')"

if ($DryRun) {
    Log-Warn "[DRY RUN] Would create webhook with above parameters"
    exit 0
}

$createResult = Invoke-GLCheck @createArgs
if (-not $createResult) {
    Log-Err "Webhook creation failed"
    Log-Info "Common issues:"
    Log-Info "  1. URL must be HTTPS (GitLink requirement)"
    Log-Info "  2. URL must be publicly accessible from GitLink's servers"
    Log-Info "  3. You may need admin permissions on the repo"
    Log-Info "  4. Max 20 webhooks per repo — use -ListExisting to check"
    exit 1
}

$webhookId = ""
if ($createResult.data.id) { $webhookId = $createResult.data.id }
elseif ($createResult.data.webhook.id) { $webhookId = $createResult.data.webhook.id }
Log-Ok "Webhook created! ID: #$webhookId"

# ================================================================
# Test Webhook
# ================================================================
Log-Step "Testing webhook connectivity..."
$testResult = Invoke-GL webhook,+test,--owner,$Owner,--repo,$Repo,--id,$webhookId,--event,issue
if ($testResult) {
    try {
        $testOk = (($testResult | ConvertFrom-Json).ok -eq $true)
    } catch { $testOk = $false }

    if ($testOk) {
        Log-Ok "Webhook test ping sent successfully"
        Log-Info "Check the listener console for the test event"
    } else {
        Log-Warn "Webhook test may have failed — check that your listener is running and accessible"
        Log-Info "Verify: curl -X POST $WebhookUrl -H 'Content-Type: application/json' -d '{}'"
    }
} else {
    Log-Warn "Could not test webhook — check that your listener is running"
}

# ================================================================
# Complete
# ================================================================
Log-Title "Webhook Setup Complete"
Write-Host ""

$checkmark = [char]0x2714
Write-Host "  ${checkmark} GitLink Platform: Webhook registered" -ForegroundColor Green
Write-Host "    → When a new Issue is created in $Owner/$Repo" -ForegroundColor Gray
Write-Host "    → GitLink POSTs to: $WebhookUrl" -ForegroundColor Gray
Write-Host "    → Webhook ID: #$webhookId" -ForegroundColor Gray
Write-Host ""
Write-Host "  ${checkmark} Local Listener: 01a-webhook-listener.ps1" -ForegroundColor Green
Write-Host "    → Receives HTTP POST from GitLink" -ForegroundColor Gray
Write-Host "    → Validates HMAC signature" -ForegroundColor Gray
Write-Host "    → Calls 01a-issue-triage.ps1" -ForegroundColor Gray
Write-Host ""
Write-Host "  ${checkmark} Triage Script: 01a-issue-triage.ps1" -ForegroundColor Green
Write-Host "    → AI analyzes issue content" -ForegroundColor Gray
Write-Host "    → Selects matching label from repo's existing labels" -ForegroundColor Gray
Write-Host "    → Assigns to issue creator" -ForegroundColor Gray
Write-Host ""

Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Cyan
Write-Host "  验证方式:" -ForegroundColor Cyan
Write-Host "  1. 在 GitLink 网页端 $Owner/$Repo 创建一个新 Issue" -ForegroundColor White
Write-Host "  2. 观察 01a-webhook-listener.ps1 的控制台输出" -ForegroundColor White
Write-Host "  3. 检查 Issue 是否自动被打上标签并分配了负责人" -ForegroundColor White
Write-Host ""
Write-Host "  手动测试（不走 webhook，直接触发分类）:" -ForegroundColor Cyan
Write-Host "  powershell workflows/01a-issue-triage.ps1 -IssueNumber <N>" -ForegroundColor White
Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor Cyan
Write-Host ""
Write-Host "  Webhook 管理:" -ForegroundColor Cyan
Write-Host "  - 查看: gitlink-cli webhook +list"
Write-Host "  - 详情: gitlink-cli webhook +info --id $webhookId"
Write-Host "  - 删除: gitlink-cli webhook +delete --id $webhookId"
