param(
    [Parameter(Position = 0)]
    [string]$Target = "all",

    [switch]$DryRun
)

$ErrorActionPreference = "Stop"

$projectRoot = $PSScriptRoot
$uploadScript = Join-Path $projectRoot "oss-html.ps1"

if (-not (Test-Path $uploadScript)) {
    throw ("Upload script not found: {0}" -f $uploadScript)
}

$publishTargets = @{
    "classic-sequential" = @{
        LocalPath = "event/classic-sequential.json"
        RemotePath = "gotomars/event/classic-sequential.json"
        PublicUrl = "https://oss-mbh5.colormaprun.com/gotomars/event/classic-sequential.json"
    }
    "score-o" = @{
        LocalPath = "event/score-o.json"
        RemotePath = "gotomars/event/score-o.json"
        PublicUrl = "https://oss-mbh5.colormaprun.com/gotomars/event/score-o.json"
    }
}

function Assert-JsonConfig {
    param(
        [string]$ConfigPath,
        [string]$ConfigName
    )

    if (-not (Test-Path $ConfigPath)) {
        throw ("Config file not found: {0}" -f $ConfigPath)
    }

    $raw = Get-Content -LiteralPath $ConfigPath -Raw -Encoding UTF8
    try {
        $parsed = $raw | ConvertFrom-Json
    } catch {
        throw ("JSON parse failed: {0}`n{1}" -f $ConfigPath, $_.Exception.Message)
    }

    if (-not $parsed.schemaVersion) {
        throw ("Missing schemaVersion: {0}" -f $ConfigPath)
    }

    if (-not $parsed.game) {
        throw ("Missing game block: {0}" -f $ConfigPath)
    }

    if (-not $parsed.game.mode) {
        throw ("Missing game.mode: {0}" -f $ConfigPath)
    }

    Write-Host ("[OK] {0} schemaVersion={1} game.mode={2}" -f $ConfigName, $parsed.schemaVersion, $parsed.game.mode)
}

function Publish-ConfigTarget {
    param(
        [string]$ConfigName,
        [hashtable]$Config
    )

    $localPath = Join-Path $projectRoot $Config.LocalPath
    $remotePath = $Config.RemotePath
    $publicUrl = $Config.PublicUrl

    Assert-JsonConfig -ConfigPath $localPath -ConfigName $ConfigName

    if ($DryRun) {
        Write-Host ("[DRY-RUN] Skip upload: {0} -> {1}" -f $localPath, $remotePath)
        Write-Host ("[DRY-RUN] Public URL: {0}" -f $publicUrl)
        return
    }

    Write-Host ("[UPLOAD] {0} -> {1}" -f $localPath, $remotePath)
    & $uploadScript cp-up $localPath $remotePath
    if ($LASTEXITCODE -ne 0) {
        throw ("Upload failed: {0}" -f $ConfigName)
    }

    Write-Host ("[DONE] {0} published" -f $ConfigName)
    Write-Host ("[URL] {0}" -f $publicUrl)
}

$selectedTargets = if ($Target -eq "all") {
    $publishTargets.Keys | Sort-Object
} else {
    @($Target)
}

foreach ($selectedTarget in $selectedTargets) {
    if (-not $publishTargets.ContainsKey($selectedTarget)) {
        $supported = ($publishTargets.Keys + "all" | Sort-Object) -join ", "
        throw ("Unsupported publish target: {0}. Allowed: {1}" -f $selectedTarget, $supported)
    }

    Publish-ConfigTarget -ConfigName $selectedTarget -Config $publishTargets[$selectedTarget]
}
