# Precise analysis: get actual backend mapping list from running server
# Use a smarter approach - test only the paths from the frontend API files
# and properly map them to backend endpoints

$companyUrl = "http://localhost:8006"

# Login
$loginBody = '{"tenantCode":"T202605253515","username":"admin","password":"admin123"}'
$loginResp = Invoke-WebRequest -Uri "$companyUrl/login" -Method POST -ContentType "application/json" -Body $loginBody -UseBasicParsing
$loginJson = $loginResp.Content | ConvertFrom-Json
$token = $loginJson.token
Write-Host "Token OK"
$headers = @{ Authorization = "Bearer $token" }

# Step 1: Get the ACTUAL registered mappings by testing key patterns
# First, let's extract frontend API URLs properly from saasadminui
$apiFiles = Get-ChildItem -Path "d:\ylrz\saasadminui\src\api" -Recurse -Filter "*.js"

# Parse each API file to extract url + method pairs
$frontendApis = @()
foreach ($file in $apiFiles) {
    $content = Get-Content $file.FullName -Raw -Encoding UTF8
    
    # Match each API function with its url and method
    $funcBlocks = [regex]::Matches($content, "(?:export\s+(?:const|function)\s+\w+\s*=?\s*\([^)]*\)\s*=>\s*\{?\s*return\s+request\(\s*\{[^}]*\}\s*\)|request\(\s*\{[^}]*\}\s*\))")
    
    foreach ($block in $funcBlocks) {
        $blockText = $block.Value
        
        $url = ""
        $method = "GET"
        
        if ($blockText -match "url:\s*['`"]([^'`"]+)['`"]") {
            $url = $Matches[1]
        }
        if ($blockText -match "method:\s*['`"]([^'`"]+)['`"]") {
            $method = $Matches[1].ToUpper()
        }
        
        if ($url -ne "") {
            # Replace path variables
            $cleanUrl = $url -replace '\$\{[^}]+\}', '1'
            $frontendApis += @{ url = $cleanUrl; method = $method; file = $file.Name }
        }
    }
}

Write-Host "Frontend API calls: $($frontendApis.Count)"

# Deduplicate by url+method
$uniqueApis = @{}
foreach ($api in $frontendApis) {
    $key = "$($api.method) $($api.url)"
    if (-not $uniqueApis.ContainsKey($key)) {
        $uniqueApis[$key] = $api
    }
}

Write-Host "Unique API calls: $($uniqueApis.Count)"

# Step 2: Test each API with the CORRECT HTTP method
Write-Host "`n=== Testing APIs with correct methods ==="
$ok = [System.Collections.ArrayList]::new()
$notFound = [System.Collections.ArrayList]::new()
$serverErr = [System.Collections.ArrayList]::new()
$forbidden = [System.Collections.ArrayList]::new()
$other = [System.Collections.ArrayList]::new()

$i = 0
$total = $uniqueApis.Count
foreach ($key in ($uniqueApis.Keys | Sort-Object)) {
    $i++
    $api = $uniqueApis[$key]
    $url = $api.url
    $method = $api.method
    $file = $api.file
    
    if ($i % 100 -eq 0) { Write-Host "  Progress: $i / $total" }
    
    try {
        if ($method -eq "GET") {
            $resp = Invoke-WebRequest -Uri "$companyUrl$url" -Method GET -Headers $headers -UseBasicParsing -TimeoutSec 8
        } elseif ($method -eq "POST") {
            $resp = Invoke-WebRequest -Uri "$companyUrl$url" -Method POST -Headers $headers -ContentType "application/json" -Body "{}" -UseBasicParsing -TimeoutSec 8
        } elseif ($method -eq "PUT") {
            $resp = Invoke-WebRequest -Uri "$companyUrl$url" -Method PUT -Headers $headers -ContentType "application/json" -Body "{}" -UseBasicParsing -TimeoutSec 8
        } elseif ($method -eq "DELETE") {
            $resp = Invoke-WebRequest -Uri "$companyUrl$url" -Method DELETE -Headers $headers -UseBasicParsing -TimeoutSec 8
        } else {
            $resp = Invoke-WebRequest -Uri "$companyUrl$url" -Method GET -Headers $headers -UseBasicParsing -TimeoutSec 8
        }
        
        $body = $resp.Content | ConvertFrom-Json
        if ($body.code -and $body.code -ne 200) {
            $code = "$($body.code)"
            if ($code -eq "404") { [void]$notFound.Add("$method $url | $file") }
            elseif ($code -eq "500") { [void]$serverErr.Add("$method $url | $file | msg=$($body.msg)") }
            elseif ($code -eq "403") { [void]$forbidden.Add("$method $url | $file") }
            else { [void]$other.Add("$method $url | $file | code=$code msg=$($body.msg)") }
        } else {
            [void]$ok.Add("$method $url | $file")
        }
    } catch {
        $err = "$($_.Exception.Message)"
        if ($err -match "404") { [void]$notFound.Add("$method $url | $file") }
        elseif ($err -match "500") { [void]$serverErr.Add("$method $url | $file") }
        elseif ($err -match "403") { [void]$forbidden.Add("$method $url | $file") }
        else { [void]$other.Add("$method $url | $file | $err") }
    }
}

# Step 3: Summary
Write-Host "`n========================================"
Write-Host "=== API Test Results (Correct Methods) ==="
Write-Host "========================================"
Write-Host "200 OK: $($ok.Count)"
Write-Host "404 Not Found: $($notFound.Count)"
Write-Host "500 Server Error: $($serverErr.Count)"
Write-Host "403 Forbidden: $($forbidden.Count)"
Write-Host "OTHER: $($other.Count)"

# Categorize 404 by module
Write-Host "`n--- 404 by Module ---"
$nfByMod = @{}
foreach ($line in $notFound) {
    if ($line -match "\s+/([^/]+)/") {
        $mod = $Matches[1]
        if (-not $nfByMod.ContainsKey($mod)) { $nfByMod[$mod] = 0 }
        $nfByMod[$mod]++
    }
}
$nfByMod.GetEnumerator() | Sort-Object Value -Descending | ForEach-Object { Write-Host "  $($_.Key): $($_.Value)" }

# Categorize 500 by type
Write-Host "`n--- 500 Error Types ---"
$errByType = @{}
foreach ($line in $serverErr) {
    if ($line -match "msg=(.+)") {
        $msg = $Matches[1].Substring(0, [Math]::Min(80, $Matches[1].Length))
        if (-not $errByType.ContainsKey($msg)) { $errByType[$msg] = 0 }
        $errByType[$msg]++
    }
}
$errByType.GetEnumerator() | Sort-Object Value -Descending | Select-Object -First 15 | ForEach-Object { Write-Host "  [$($_.Value)] $($_.Key)" }

# Show sample 404
Write-Host "`n--- Sample 404 ---"
$notFound | Sort-Object | Select-Object -First 30 | ForEach-Object { Write-Host "  $_" }

# Show sample 500
Write-Host "`n--- Sample 500 ---"
$serverErr | Sort-Object | Select-Object -First 30 | ForEach-Object { Write-Host "  $_" }

# Save
$out = [System.Collections.ArrayList]::new()
[void]$out.Add("API Test Results (Correct Methods) - $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')")
[void]$out.Add("200 OK: $($ok.Count)")
[void]$out.Add("404: $($notFound.Count)")
[void]$out.Add("500: $($serverErr.Count)")
[void]$out.Add("403: $($forbidden.Count)")
[void]$out.Add("OTHER: $($other.Count)")
[void]$out.Add("")
[void]$out.Add("=== 404 ===")
$notFound | Sort-Object | ForEach-Object { [void]$out.Add($_) }
[void]$out.Add("")
[void]$out.Add("=== 500 ===")
$serverErr | Sort-Object | ForEach-Object { [void]$out.Add($_) }
[void]$out.Add("")
[void]$out.Add("=== 403 ===")
$forbidden | Sort-Object | ForEach-Object { [void]$out.Add($_) }
[void]$out.Add("")
[void]$out.Add("=== OTHER ===")
$other | Sort-Object | ForEach-Object { [void]$out.Add($_) }

[System.IO.File]::WriteAllLines("d:\ylrz\saasadminui\api_test_v2_results.txt", $out, (New-Object System.Text.UTF8Encoding($false)))
Write-Host "`nResults saved to api_test_v2_results.txt"
