@echo off
setlocal EnableExtensions
chcp 65001 >nul
title EBuyAI WorkBuddy 配置助手

set "EBUYAI_SELF=%~f0"
set "EBUYAI_PS1="
set "EBUYAI_GUID="
set "EBUYAI_POWERSHELL=powershell.exe"
where powershell.exe >nul 2>&1
if errorlevel 1 goto POWERSHELL_MISSING

for /f "delims=" %%I in ('powershell.exe -NoLogo -NoProfile -Command "[guid]::NewGuid().ToString([char]78)"') do set "EBUYAI_GUID=%%I"
if not defined EBUYAI_GUID goto EXTRACTION_FAILED
set "EBUYAI_PS1=%TEMP%\ebuyai-workbuddy-%EBUYAI_GUID%.ps1"

"%EBUYAI_POWERSHELL%" -NoLogo -NoProfile -ExecutionPolicy Bypass -Command "$source=$env:EBUYAI_SELF; $target=$env:EBUYAI_PS1; $lines=Get-Content -LiteralPath $source -Encoding UTF8; $marker=[Array]::LastIndexOf($lines,':: __EBUYAI_POWERSHELL__'); if($marker -lt 0){exit 2}; $lines[($marker+1)..($lines.Count-1)] | Set-Content -LiteralPath $target -Encoding UTF8"
if errorlevel 1 goto EXTRACTION_FAILED

"%EBUYAI_POWERSHELL%" -NoLogo -NoProfile -ExecutionPolicy Bypass -File "%EBUYAI_PS1%"
set "EBUYAI_EXIT=%ERRORLEVEL%"
del /f /q "%EBUYAI_PS1%" >nul 2>&1
goto FINISH

:POWERSHELL_MISSING
echo.
echo [E01] 系统未找到 Windows PowerShell，配置未完成。
set "EBUYAI_EXIT=1"
goto FINISH

:EXTRACTION_FAILED
del /f /q "%EBUYAI_PS1%" >nul 2>&1
echo.
echo [E02] 无法读取配置助手，请重新下载后再试。
set "EBUYAI_EXIT=1"

:FINISH
if not "%EBUYAI_NONINTERACTIVE%"=="1" (
  echo.
  echo 按任意键关闭窗口……
  pause >nul
)
endlocal & exit /b %EBUYAI_EXIT%

:: __EBUYAI_POWERSHELL__
$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

$installerVersion = "1.0.4"
$script:configChanged = $false
$script:backupPath = $null
$script:temporaryConfigPath = $null

function Stop-EBuyAIInstall {
    param([Parameter(Mandatory = $true)][string]$Message)

    Write-Host ""
    Write-Host "配置未完成：$Message" -ForegroundColor Red
    if (-not $script:configChanged) {
        Write-Host "原有 WorkBuddy 配置未被修改。" -ForegroundColor Yellow
    }
    elseif ($script:backupPath) {
        Write-Host "原配置备份：$($script:backupPath)" -ForegroundColor Yellow
    }
    exit 1
}

function Throw-EBuyAIInstallError {
    param(
        [Parameter(Mandatory = $true)][string]$Code,
        [Parameter(Mandatory = $true)][string]$Message
    )

    throw "[$Code] $Message"
}

function Get-EBuyAIKey {
    param([Parameter(Mandatory = $true)][bool]$NonInteractive)

    if ($NonInteractive) {
        if ([string]::IsNullOrWhiteSpace($env:EBUYAI_API_KEY)) {
            Throw-EBuyAIInstallError -Code "E10" -Message "非交互模式没有提供测试 Key。"
        }
        return $env:EBUYAI_API_KEY.Trim()
    }

    Write-Host "请粘贴订单中收到的 EBuyAI Key，然后按 Enter。" -ForegroundColor Cyan
    Write-Host "输入内容不会显示，这是正常现象。" -ForegroundColor DarkGray
    $secureKey = Read-Host -AsSecureString
    $pointer = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($secureKey)
    try {
        return [Runtime.InteropServices.Marshal]::PtrToStringBSTR($pointer).Trim()
    }
    finally {
        [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($pointer)
    }
}

function Get-ModelProperty {
    param(
        [AllowNull()]$Model,
        [Parameter(Mandatory = $true)][string]$Name
    )

    if ($null -eq $Model) {
        return $null
    }
    $property = $Model.PSObject.Properties[$Name]
    if ($null -eq $property) {
        return $null
    }
    return $property.Value
}

function Test-EBuyAIManagedModel {
    param(
        [AllowNull()]$Model,
        [Parameter(Mandatory = $true)][string[]]$CurrentIds
    )

    $id = [string](Get-ModelProperty -Model $Model -Name "id")
    if ($id -in $CurrentIds) {
        return $true
    }

    $vendor = [string](Get-ModelProperty -Model $Model -Name "vendor")
    if ($vendor -eq "EBuyAI") {
        return $true
    }

    $url = [string](Get-ModelProperty -Model $Model -Name "url")
    if (-not [string]::IsNullOrWhiteSpace($url)) {
        try {
            if (([Uri]$url).Host -eq "api.ebuyai.com") {
                return $true
            }
        }
        catch {
            return $false
        }
    }

    return $false
}

try {
    $nonInteractive = $env:EBUYAI_NONINTERACTIVE -eq "1"
    $baseUrl = "https://api.ebuyai.com/v1"
    $configPath = Join-Path $env:USERPROFILE ".workbuddy\models.json"

    if ($nonInteractive -and -not [string]::IsNullOrWhiteSpace($env:EBUYAI_BASE_URL)) {
        $baseUrl = $env:EBUYAI_BASE_URL.Trim().TrimEnd("/")
    }
    if ($nonInteractive -and -not [string]::IsNullOrWhiteSpace($env:EBUYAI_CONFIG_PATH)) {
        $configPath = [IO.Path]::GetFullPath($env:EBUYAI_CONFIG_PATH)
    }

    try {
        $baseUri = [Uri]$baseUrl
    }
    catch {
        Throw-EBuyAIInstallError -Code "E11" -Message "API 地址无效。"
    }
    $isLoopback = $baseUri.IsLoopback -or $baseUri.Host -eq "localhost"
    if ($baseUri.Scheme -ne "https" -and -not ($nonInteractive -and $isLoopback)) {
        Throw-EBuyAIInstallError -Code "E11" -Message "API 地址必须使用 HTTPS。"
    }

    $definitions = @(
        [ordered]@{ id = "e-deepseek-v4-flash"; name = "DS V4 Flash"; badge = "快问"; badgeColor = "#16A34A"; supportsToolCall = $false },
        [ordered]@{ id = "e-glm-5.3"; name = "GLM-5.3"; badge = "通用"; badgeColor = "#2563EB"; supportsToolCall = $true },
        [ordered]@{ id = "e-deepseek-v4-pro"; name = "DS V4 Pro"; badge = "复杂"; badgeColor = "#7C3AED"; supportsToolCall = $true },
        [ordered]@{ id = "e-minimax-m3"; name = "MiniMax M3"; badge = "均衡"; badgeColor = "#D97706"; supportsToolCall = $true },
        [ordered]@{ id = "e-kimi-k2.7-code"; name = "Kimi K2.7 Code"; badge = "代码"; badgeColor = "#475569"; supportsToolCall = $true }
    )
    $currentIds = @($definitions | ForEach-Object { [string]$_.id })

    Write-Host ""
    Write-Host "========================================" -ForegroundColor Cyan
    Write-Host "  EBuyAI WorkBuddy 配置助手 v$installerVersion" -ForegroundColor Cyan
    Write-Host "========================================" -ForegroundColor Cyan
    Write-Host "将安全加入 5 个 EBuyAI 模型，并保留其他现有模型。" -ForegroundColor DarkGray
    Write-Host ""

    $apiKey = Get-EBuyAIKey -NonInteractive $nonInteractive
    if ([string]::IsNullOrWhiteSpace($apiKey)) {
        Throw-EBuyAIInstallError -Code "E10" -Message "EBuyAI Key 不能为空。"
    }
    if (-not $apiKey.StartsWith("sk-", [StringComparison]::Ordinal)) {
        Throw-EBuyAIInstallError -Code "E10" -Message "Key 格式不正确，应以 sk- 开头。"
    }

    $maskedCharacterCount = [Math]::Min([Math]::Max($apiKey.Length - 3, 1), 24)
    $maskedKey = "sk-" + ("*" * $maskedCharacterCount)
    if ($apiKey.Length - 3 -gt $maskedCharacterCount) {
        $maskedKey += "…"
    }
    Write-Host "已读取 Key：$maskedKey（共 $($apiKey.Length) 个字符）" -ForegroundColor DarkGray

    Write-Host "正在验证 EBuyAI Key 和模型权限……" -ForegroundColor Cyan
    try {
        $response = Invoke-RestMethod -Method Get -Uri "$baseUrl/models" -Headers @{ Authorization = "Bearer $apiKey" } -TimeoutSec 20
    }
    catch {
        $statusCode = $null
        if ($null -ne $_.Exception.Response -and $null -ne $_.Exception.Response.StatusCode) {
            $statusCode = [int]$_.Exception.Response.StatusCode
        }
        if ($statusCode -in @(401, 403)) {
            Throw-EBuyAIInstallError -Code "E12" -Message "Key 无效、已停用或无权访问。"
        }
        Throw-EBuyAIInstallError -Code "E13" -Message "无法连接 EBuyAI API，请检查网络后重试。"
    }

    if ($null -eq $response -or $null -eq $response.data) {
        Throw-EBuyAIInstallError -Code "E14" -Message "API 返回的模型列表无效。"
    }
    $availableIds = @(
        $response.data |
            ForEach-Object { [string]$_.id } |
            Where-Object { -not [string]::IsNullOrWhiteSpace($_) } |
            Select-Object -Unique
    )
    $missingIds = @($currentIds | Where-Object { $_ -notin $availableIds })
    if ($missingIds.Count -gt 0) {
        Throw-EBuyAIInstallError -Code "E15" -Message "当前 Key 缺少模型权限：$($missingIds -join ', ')。"
    }

    $configExists = Test-Path -LiteralPath $configPath -PathType Leaf
    if (Test-Path -LiteralPath $configPath -PathType Container) {
        Throw-EBuyAIInstallError -Code "E20" -Message "models.json 路径被文件夹占用。"
    }

    $rootType = "object"
    $root = [ordered]@{}
    $existingModels = @()
    if ($configExists) {
        $rawConfig = [IO.File]::ReadAllText($configPath, [Text.Encoding]::UTF8)
        if ([string]::IsNullOrWhiteSpace($rawConfig)) {
            Throw-EBuyAIInstallError -Code "E21" -Message "现有 models.json 是空文件，请先人工检查。"
        }

        try {
            $parsed = $rawConfig | ConvertFrom-Json
        }
        catch {
            Throw-EBuyAIInstallError -Code "E21" -Message "现有 models.json 不是有效 JSON，请先人工检查。"
        }

        $trimmedConfig = $rawConfig.TrimStart()
        if ($trimmedConfig.StartsWith("[")) {
            $rootType = "array"
            $existingModels = @($parsed)
        }
        elseif ($trimmedConfig.StartsWith("{")) {
            foreach ($property in $parsed.PSObject.Properties) {
                $root[$property.Name] = $property.Value
            }
            if ($root.Contains("models") -and $null -ne $root.models) {
                if ($root.models -isnot [System.Array]) {
                    Throw-EBuyAIInstallError -Code "E22" -Message "现有 models 字段不是数组，请先人工检查。"
                }
                $existingModels = @($root.models)
            }
        }
        else {
            Throw-EBuyAIInstallError -Code "E22" -Message "现有 models.json 根结构不受支持。"
        }
    }

    $preservedModels = New-Object System.Collections.ArrayList
    $removedManagedIds = New-Object System.Collections.Generic.HashSet[string] ([StringComparer]::Ordinal)
    foreach ($model in $existingModels) {
        if (Test-EBuyAIManagedModel -Model $model -CurrentIds $currentIds) {
            $managedId = [string](Get-ModelProperty -Model $model -Name "id")
            if (-not [string]::IsNullOrWhiteSpace($managedId)) {
                [void]$removedManagedIds.Add($managedId)
            }
            continue
        }
        [void]$preservedModels.Add($model)
    }

    $chatUrl = "$baseUrl/chat/completions"
    $mergedModels = New-Object System.Collections.ArrayList
    foreach ($definition in $definitions) {
        [void]$mergedModels.Add([PSCustomObject][ordered]@{
            id = $definition.id
            name = $definition.name
            vendor = "EBuyAI"
            apiKey = $apiKey
            maxInputTokens = 128000
            maxOutputTokens = 32768
            url = $chatUrl
            supportsToolCall = [bool]$definition.supportsToolCall
            supportsImages = $false
            tags = @("badge:$($definition.badge):$($definition.badgeColor)")
        })
    }
    foreach ($model in $preservedModels) {
        [void]$mergedModels.Add($model)
    }

    if ($rootType -eq "object") {
        $root["models"] = @($mergedModels)
        if ($root.Contains("availableModels") -and $null -ne $root.availableModels) {
            if ($root.availableModels -isnot [System.Array]) {
                Throw-EBuyAIInstallError -Code "E23" -Message "现有 availableModels 字段不是数组，请先人工检查。"
            }

            $originalVisible = @($root.availableModels)
            if ($originalVisible.Count -gt 0) {
                $preservedIds = @(
                    $preservedModels |
                        ForEach-Object { [string](Get-ModelProperty -Model $_ -Name "id") } |
                        Where-Object { -not [string]::IsNullOrWhiteSpace($_) }
                )
                $visible = New-Object System.Collections.ArrayList
                foreach ($id in $currentIds) {
                    if ($id -notin $visible) {
                        [void]$visible.Add($id)
                    }
                }
                foreach ($idValue in $originalVisible) {
                    $id = [string]$idValue
                    if ($removedManagedIds.Contains($id) -and $id -notin $preservedIds) {
                        continue
                    }
                    if ($id -in $currentIds) {
                        continue
                    }
                    if ($id -notin $visible) {
                        [void]$visible.Add($idValue)
                    }
                }
                $root["availableModels"] = @($visible)
            }
        }
        $output = $root
    }
    else {
        $output = @($mergedModels)
    }

    $directory = Split-Path -Parent $configPath
    if (Test-Path -LiteralPath $directory -PathType Leaf) {
        Throw-EBuyAIInstallError -Code "E20" -Message "WorkBuddy 配置目录路径被文件占用。"
    }
    if (-not (Test-Path -LiteralPath $directory -PathType Container)) {
        [void](New-Item -ItemType Directory -Path $directory -Force)
    }

    $json = ConvertTo-Json -InputObject $output -Depth 32
    $script:temporaryConfigPath = Join-Path $directory (".models.ebuyai-{0}.tmp" -f [Guid]::NewGuid().ToString("N"))
    $utf8NoBom = New-Object Text.UTF8Encoding($false)
    [IO.File]::WriteAllText($script:temporaryConfigPath, $json + [Environment]::NewLine, $utf8NoBom)

    try {
        $null = [IO.File]::ReadAllText($script:temporaryConfigPath, [Text.Encoding]::UTF8) | ConvertFrom-Json
    }
    catch {
        Throw-EBuyAIInstallError -Code "E30" -Message "生成的配置未通过 JSON 校验。"
    }

    try {
        if ($configExists) {
            $stamp = Get-Date -Format "yyyyMMdd-HHmmss"
            $script:backupPath = Join-Path $directory ("models.json.ebuyai-backup-{0}-{1}" -f $stamp, [Guid]::NewGuid().ToString("N").Substring(0, 8))
            [IO.File]::Replace($script:temporaryConfigPath, $configPath, $script:backupPath, $true)
        }
        else {
            [IO.File]::Move($script:temporaryConfigPath, $configPath)
        }
        $script:configChanged = $true
        $script:temporaryConfigPath = $null
    }
    catch {
        Throw-EBuyAIInstallError -Code "E31" -Message "无法安全写入 models.json，请检查文件权限后重试。"
    }

    Write-Host ""
    Write-Host "配置成功。" -ForegroundColor Green
    Write-Host "已新增或更新：5 个 EBuyAI 模型"
    Write-Host "已保留其他模型：$($preservedModels.Count) 个"
    Write-Host "配置文件：$configPath" -ForegroundColor DarkGray
    if ($script:backupPath) {
        Write-Host "原配置备份：$($script:backupPath)" -ForegroundColor DarkGray
    }
    Write-Host "WorkBuddy 会自动加载新配置，通常约 1 秒，无需重启。" -ForegroundColor Cyan
    Write-Host "请重新打开模型列表查看；若仍未显示，再重启 WorkBuddy。" -ForegroundColor Cyan
    exit 0
}
catch {
    $message = [string]$_.Exception.Message
    if ($message -notmatch '^\[E\d{2}\] ') {
        $message = "[E99] 配置过程中发生异常，请重新下载后重试。"
    }
    Stop-EBuyAIInstall -Message $message
}
finally {
    if ($script:temporaryConfigPath -and (Test-Path -LiteralPath $script:temporaryConfigPath)) {
        Remove-Item -LiteralPath $script:temporaryConfigPath -Force -ErrorAction SilentlyContinue
    }
}
