param(
    [string]$WorkbookPath = ""
)

$ErrorActionPreference = "Stop"

if (-not $WorkbookPath) {
    $root = Split-Path $PSScriptRoot -Parent
    $item = Get-ChildItem -Path $root -File -Filter "*.xlsx" |
        Where-Object { $_.Name -like "*Sheet*.xlsx" } |
        Sort-Object LastWriteTime -Descending |
        Select-Object -First 1
    if ($item) {
        $WorkbookPath = $item.FullName
    }
}

if (-not (Test-Path -LiteralPath $WorkbookPath)) {
    throw "Workbook not found: $WorkbookPath"
}

$excel = New-Object -ComObject Excel.Application
$excel.Visible = $false
$excel.DisplayAlerts = $false

$openParen = [string][char]0xFF08
$closeParen = [string][char]0xFF09
$idPattern = "(?<![A-Z0-9-])([A-Z]+-[A-Z0-9]+-\d+[A-Z]?)(?![A-Z0-9-])"
$regex = New-Object System.Text.RegularExpressions.Regex($idPattern)

try {
    $wb = $excel.Workbooks.Open((Resolve-Path -LiteralPath $WorkbookPath).Path)

    $titles = @{}
    for ($sheetIndex = 1; $sheetIndex -le $wb.Worksheets.Count; $sheetIndex++) {
        $ws = $wb.Worksheets.Item($sheetIndex)
        $rowCount = $ws.UsedRange.Rows.Count
        for ($row = 2; $row -le $rowCount; $row++) {
            $caseId = [string]$ws.Cells.Item($row, 1).Text
            $title = [string]$ws.Cells.Item($row, 5).Text
            $caseId = $caseId.Trim()
            $title = $title.Trim()
            if ($caseId -and $title -and -not $titles.ContainsKey($caseId)) {
                $titles[$caseId] = $title
            }
        }
    }

    $changed = 0
    for ($sheetIndex = 1; $sheetIndex -le $wb.Worksheets.Count; $sheetIndex++) {
        $ws = $wb.Worksheets.Item($sheetIndex)
        $rowCount = $ws.UsedRange.Rows.Count
        for ($row = 2; $row -le $rowCount; $row++) {
            $text = [string]$ws.Cells.Item($row, 9).Value2
            if (-not $text) {
                continue
            }

            $newText = $regex.Replace($text, {
                param($match)
                $id = $match.Groups.Item(1).Value
                if (-not $titles.ContainsKey($id)) {
                    return $match.Value
                }

                $afterIndex = $match.Index + $match.Length
                if ($afterIndex -lt $text.Length -and $text.Substring($afterIndex, 1) -eq $openParen) {
                    return $match.Value
                }

                return $id + $openParen + $titles[$id] + $closeParen
            })

            if ($newText -ne $text) {
                $ws.Cells.Item($row, 9).Value2 = $newText
                $changed += 1
            }
        }
    }

    $wb.Save()
    Write-Output "Annotated step references in $changed rows."
}
finally {
    if ($wb) {
        $wb.Close($true)
    }
    $excel.Quit()
    [System.Runtime.InteropServices.Marshal]::ReleaseComObject($excel) | Out-Null
    [GC]::Collect()
    [GC]::WaitForPendingFinalizers()
}
