param(
    [string]$TemplatePath = "C:\Users\niuniu\Desktop\Report.pptx",
    [string]$OutputPath = "C:\workspace\cursor\output\vip-report\shape-inventory.json"
)

$ErrorActionPreference = "Stop"

# 关键行注释：这里是关键处理节点。
# 函数说明：封装Get-ShapeNode方法的核心处理流程。
function Get-ShapeNode {
    param(
        [Parameter(Mandatory = $true)]$Shape,
        [Parameter(Mandatory = $true)][int]$SlideIndex
    )

    $text = $null
    # 关键行注释：进入核心执行区，并在 finally 中释放 PowerPoint 资源。
    try {
        if ($Shape.HasTextFrame -eq -1 -and $Shape.TextFrame.HasText -eq -1) {
            $text = $Shape.TextFrame.TextRange.Text -replace "`r`n", " "
        }
    } catch {
        $text = $null
    }

    $children = @()
    $chartCount = 0
    $imageCount = 0

    # 关键行注释：进入核心执行区，并在 finally 中释放 PowerPoint 资源。
    try {
        if ($Shape.HasChart -eq -1) {
            $chartCount = 1
        }
    } catch {
    }

    if ($Shape.Type -in 11, 13) {
        $imageCount = 1
    }

    # 关键行注释：进入核心执行区，并在 finally 中释放 PowerPoint 资源。
    try {
        $groupCount = $Shape.GroupItems.Count
        if ($groupCount -gt 0) {
            for ($i = 1; $i -le $groupCount; $i++) {
                $child = Get-ShapeNode -Shape $Shape.GroupItems.Item($i) -SlideIndex $SlideIndex
                $children += $child
                $chartCount += $child.ChartCount
                $imageCount += $child.ImageCount
            }
        }
    } catch {
    }

    $hasTable = $false
    # 关键行注释：进入核心执行区，并在 finally 中释放 PowerPoint 资源。
    try {
        $hasTable = ($Shape.HasTable -eq -1)
    } catch {
        $hasTable = $false
    }

    return [pscustomobject]@{
        Slide = $SlideIndex
        Name = $Shape.Name
        Id = $Shape.Id
        Type = $Shape.Type
        HasChart = [bool]$chartCount
        HasTable = $hasTable
        Text = $text
        Left = [math]::Round($Shape.Left, 2)
        Top = [math]::Round($Shape.Top, 2)
        Width = [math]::Round($Shape.Width, 2)
        Height = [math]::Round($Shape.Height, 2)
        ChildCount = $children.Count
        ChartCount = $chartCount
        ImageCount = $imageCount
        Children = $children
    }
}

$ppt = $null
$pres = $null

# 关键行注释：进入核心执行区，并在 finally 中释放 PowerPoint 资源。
try {
    $ppt = New-Object -ComObject PowerPoint.Application
    $pres = $ppt.Presentations.Open($TemplatePath, -1, 0, 0)

    $slides = @()
    foreach ($slide in $pres.Slides) {
        $shapeNodes = @()
        $chartCount = 0
        $imageCount = 0
        foreach ($shape in $slide.Shapes) {
            $node = Get-ShapeNode -Shape $shape -SlideIndex $slide.SlideIndex
            $shapeNodes += $node
            $chartCount += $node.ChartCount
            $imageCount += $node.ImageCount
        }

        $title = $null
        # 关键行注释：进入核心执行区，并在 finally 中释放 PowerPoint 资源。
        try {
            if ($slide.Shapes.HasTitle -eq -1) {
                $title = $slide.Shapes.Title.TextFrame.TextRange.Text -replace "`r`n", " "
            }
        } catch {
            $title = $null
        }

        $slides += [pscustomobject]@{
            Slide = $slide.SlideIndex
            Title = $title
            ShapeCount = $slide.Shapes.Count
            ChartCount = $chartCount
            ImageCount = $imageCount
            Shapes = $shapeNodes
        }
    }

    $payload = [pscustomobject]@{
        TemplatePath = $TemplatePath
        SlideCount = $pres.Slides.Count
        Slides = $slides
    } | ConvertTo-Json -Depth 8

    $parent = Split-Path -Parent $OutputPath
    if ($parent -and -not (Test-Path $parent)) {
        New-Item -ItemType Directory -Path $parent -Force | Out-Null
    }
    Set-Content -LiteralPath $OutputPath -Value $payload -Encoding UTF8
    Write-Output $OutputPath
} finally {
    if ($pres -ne $null) {
        try { $pres.Close() | Out-Null } catch {}
    }
    if ($ppt -ne $null) {
        try { $ppt.Quit() | Out-Null } catch {}
    }
}
