<#
.SYNOPSIS
  Generates Fig1.svg and Fig2.svg for the machine-attributed retraction study.
.DESCRIPTION
  Vector output, greyscale-safe fills, Arial lettering, sized for a 174 mm single-column text area.
  Fig1: annual retraction counts (all vs machine-attributed) with the machine-attributed share.
  Fig2: box plots of time from publication to retraction for both cohorts.
.EXAMPLE
  .\New-Figures.ps1 -Csv ..\data\retractionwatch.csv -RunDir ..\runs\ai-retractions -OutDir ..\papers\ai-retractions\figures
#>
[CmdletBinding()]
param(
    [Parameter(Mandatory = $true)][string]$Csv,
    [Parameter(Mandatory = $true)][string]$RunDir,
    [Parameter(Mandatory = $true)][string]$OutDir,
    [string]$ReasonPattern = 'Computer-Aided Content|Computer-Generated Content',
    [int]$FirstYear = 2010,
    [int]$LastYear = 2025,
    [int]$MaxDaysDisplay = 3000
)
$ErrorActionPreference = 'Stop'
New-Item -ItemType Directory -Force -Path $OutDir | Out-Null

function Get-Quantile {
    param([double[]]$Sorted, [double]$P)
    if ($Sorted.Count -eq 0) { return 0 }
    $i = ($Sorted.Count - 1) * $P
    $lo = [int][Math]::Floor($i); $hi = [int][Math]::Ceiling($i)
    if ($lo -eq $hi) { return $Sorted[$lo] }
    return $Sorted[$lo] + ($i - $lo) * ($Sorted[$hi] - $Sorted[$lo])
}

# ---------- Fig 1 ----------
$rows = @(Import-Csv (Join-Path $RunDir 'tables\stats_by_year_ci.csv') |
    Where-Object { [int]$_.Year -ge $FirstYear -and [int]$_.Year -le $LastYear } | Sort-Object { [int]$_.Year })
$W = 660; $H = 400; $L = 62; $R = 52; $T = 24; $B = 58
$pw = $W - $L - $R; $ph = $H - $T - $B
$maxAll = ($rows | Measure-Object AllRetractions -Maximum).Maximum
$yMax = [Math]::Ceiling($maxAll / 2000.0) * 2000
$n = $rows.Count
$slot = $pw / $n
$bw = [Math]::Min(18, $slot * 0.36)

$s = New-Object System.Text.StringBuilder
[void]$s.AppendLine('<?xml version="1.0" encoding="UTF-8"?>')
[void]$s.AppendLine("<svg xmlns=`"http://www.w3.org/2000/svg`" width=`"$W`" height=`"$H`" viewBox=`"0 0 $W $H`" font-family=`"Arial, Helvetica, sans-serif`">")
[void]$s.AppendLine('<title>Annual retractions and machine-attributed retractions</title>')
[void]$s.AppendLine('<desc>Grouped bars show the annual number of all retractions and of retractions attributed to computer-generated content. The line shows the machine-attributed share of all retractions in each year.</desc>')
[void]$s.AppendLine('<defs><pattern id="hatch" width="4" height="4" patternTransform="rotate(45)" patternUnits="userSpaceOnUse"><line x1="0" y1="0" x2="0" y2="4" stroke="#000000" stroke-width="2"/></pattern></defs>')
[void]$s.AppendLine("<rect x=`"0`" y=`"0`" width=`"$W`" height=`"$H`" fill=`"#ffffff`"/>")
# y axis left
for ($v = 0; $v -le $yMax; $v += 2000) {
    $y = $T + $ph - ($v / [double]$yMax) * $ph
    [void]$s.AppendLine("<line x1=`"$L`" y1=`"$y`" x2=`"$($L+$pw)`" y2=`"$y`" stroke=`"#cccccc`" stroke-width=`"0.5`"/>")
    [void]$s.AppendLine("<text x=`"$($L-8)`" y=`"$($y+4)`" font-size=`"10`" text-anchor=`"end`">$v</text>")
}
# y axis right (share %)
for ($v = 0; $v -le 50; $v += 10) {
    $y = $T + $ph - ($v / 50.0) * $ph
    [void]$s.AppendLine("<text x=`"$($L+$pw+8)`" y=`"$($y+4)`" font-size=`"10`" text-anchor=`"start`">$v</text>")
}
$pts = New-Object System.Collections.ArrayList
$i = 0
foreach ($r in $rows) {
    $cx = $L + $slot * $i + $slot / 2.0
    $hAll = ([double]$r.AllRetractions / $yMax) * $ph
    $hMac = ([double]$r.MachineAttributed / $yMax) * $ph
    [void]$s.AppendLine("<rect x=`"$([Math]::Round($cx-$bw-1,1))`" y=`"$([Math]::Round($T+$ph-$hAll,1))`" width=`"$([Math]::Round($bw,1))`" height=`"$([Math]::Round($hAll,1))`" fill=`"#b8b8b8`" stroke=`"#555555`" stroke-width=`"0.4`"/>")
    [void]$s.AppendLine("<rect x=`"$([Math]::Round($cx+1,1))`" y=`"$([Math]::Round($T+$ph-$hMac,1))`" width=`"$([Math]::Round($bw,1))`" height=`"$([Math]::Round($hMac,1))`" fill=`"url(#hatch)`" stroke=`"#000000`" stroke-width=`"0.4`"/>")
    [void]$s.AppendLine("<text x=`"$([Math]::Round($cx,1))`" y=`"$($T+$ph+15)`" font-size=`"9`" text-anchor=`"middle`" transform=`"rotate(-45 $([Math]::Round($cx,1)) $($T+$ph+15))`">$($r.Year)</text>")
    $sy = $T + $ph - ([double]$r.SharePct / 50.0) * $ph
    [void]$pts.Add(("{0},{1}" -f [Math]::Round($cx, 1), [Math]::Round($sy, 1)))
    $i++
}
[void]$s.AppendLine("<polyline points=`"$($pts -join ' ')`" fill=`"none`" stroke=`"#000000`" stroke-width=`"1.6`" stroke-dasharray=`"5,3`"/>")
foreach ($p in $pts) { $xy = $p -split ','; [void]$s.AppendLine("<circle cx=`"$($xy[0])`" cy=`"$($xy[1])`" r=`"2.6`" fill=`"#000000`"/>") }
[void]$s.AppendLine("<line x1=`"$L`" y1=`"$($T+$ph)`" x2=`"$($L+$pw)`" y2=`"$($T+$ph)`" stroke=`"#000000`" stroke-width=`"1`"/>")
[void]$s.AppendLine("<line x1=`"$L`" y1=`"$T`" x2=`"$L`" y2=`"$($T+$ph)`" stroke=`"#000000`" stroke-width=`"1`"/>")
[void]$s.AppendLine("<line x1=`"$($L+$pw)`" y1=`"$T`" x2=`"$($L+$pw)`" y2=`"$($T+$ph)`" stroke=`"#000000`" stroke-width=`"1`"/>")
[void]$s.AppendLine("<text x=`"14`" y=`"$($T+$ph/2)`" font-size=`"11`" text-anchor=`"middle`" transform=`"rotate(-90 14 $($T+$ph/2))`">Retractions per year</text>")
[void]$s.AppendLine("<text x=`"$($W-12)`" y=`"$($T+$ph/2)`" font-size=`"11`" text-anchor=`"middle`" transform=`"rotate(90 $($W-12) $($T+$ph/2))`">Machine-attributed share (%)</text>")
[void]$s.AppendLine("<text x=`"$($L+$pw/2)`" y=`"$($H-6)`" font-size=`"11`" text-anchor=`"middle`">Retraction year</text>")
$lx = $L + 14; $ly = $T + 10
[void]$s.AppendLine("<rect x=`"$lx`" y=`"$ly`" width=`"12`" height=`"9`" fill=`"#b8b8b8`" stroke=`"#555555`" stroke-width=`"0.4`"/><text x=`"$($lx+17)`" y=`"$($ly+8)`" font-size=`"10`">All retractions</text>")
[void]$s.AppendLine("<rect x=`"$lx`" y=`"$($ly+15)`" width=`"12`" height=`"9`" fill=`"url(#hatch)`" stroke=`"#000000`" stroke-width=`"0.4`"/><text x=`"$($lx+17)`" y=`"$($ly+23)`" font-size=`"10`">Machine-attributed</text>")
[void]$s.AppendLine("<line x1=`"$lx`" y1=`"$($ly+34)`" x2=`"$($lx+12)`" y2=`"$($ly+34)`" stroke=`"#000000`" stroke-width=`"1.6`" stroke-dasharray=`"5,3`"/><text x=`"$($lx+17)`" y=`"$($ly+38)`" font-size=`"10`">Share of all retractions</text>")
[void]$s.AppendLine('</svg>')
Set-Content -Path (Join-Path $OutDir 'Fig1.svg') -Value $s.ToString() -Encoding UTF8
Write-Host "Wrote Fig1.svg" -ForegroundColor Green

# ---------- Fig 2 ----------
Write-Host "Computing lag distributions for Fig2..." -ForegroundColor Cyan
$inv = [Globalization.CultureInfo]::InvariantCulture
$lagA = New-Object System.Collections.Generic.List[double]
$lagB = New-Object System.Collections.Generic.List[double]
foreach ($r in (Import-Csv $Csv)) {
    $od = $null; $rd = $null
    try { $od = [datetime]::Parse($r.OriginalPaperDate, $inv) } catch { }
    try { $rd = [datetime]::Parse($r.RetractionDate, $inv) } catch { }
    if ($null -eq $od -or $null -eq $rd -or $rd -lt $od) { continue }
    $d = ($rd - $od).TotalDays
    if ($r.Reason -match $ReasonPattern) { $lagA.Add($d) } else { $lagB.Add($d) }
}
$A = [double[]]@($lagA.ToArray() | Sort-Object)
$B = [double[]]@($lagB.ToArray() | Sort-Object)
$stats = @()
foreach ($set in @(@{ N = 'Machine-attributed'; V = $A }, @{ N = 'All other reasons'; V = $B })) {
    $v = $set.V
    $stats += [pscustomobject]@{
        Name = $set.N; N = $v.Count
        P5 = Get-Quantile $v 0.05; Q1 = Get-Quantile $v 0.25; Med = Get-Quantile $v 0.5
        Q3 = Get-Quantile $v 0.75; P95 = Get-Quantile $v 0.95
    }
}
$stats | Export-Csv (Join-Path $RunDir 'tables\fig2_boxstats.csv') -NoTypeInformation -Encoding UTF8

$W2 = 660; $H2 = 300; $L2 = 132; $R2 = 24; $T2 = 26; $B2 = 52
$pw2 = $W2 - $L2 - $R2; $ph2 = $H2 - $T2 - $B2
$f = New-Object System.Text.StringBuilder
[void]$f.AppendLine('<?xml version="1.0" encoding="UTF-8"?>')
[void]$f.AppendLine("<svg xmlns=`"http://www.w3.org/2000/svg`" width=`"$W2`" height=`"$H2`" viewBox=`"0 0 $W2 $H2`" font-family=`"Arial, Helvetica, sans-serif`">")
[void]$f.AppendLine('<title>Time from publication to retraction by cohort</title>')
[void]$f.AppendLine('<desc>Box plots comparing time from publication to retraction. Boxes span the interquartile range, the interior line marks the median, whiskers span the 5th to 95th percentiles. The machine-attributed cohort has a much narrower spread.</desc>')
[void]$f.AppendLine("<rect x=`"0`" y=`"0`" width=`"$W2`" height=`"$H2`" fill=`"#ffffff`"/>")
for ($v = 0; $v -le $MaxDaysDisplay; $v += 500) {
    $x = $L2 + ($v / [double]$MaxDaysDisplay) * $pw2
    [void]$f.AppendLine("<line x1=`"$x`" y1=`"$T2`" x2=`"$x`" y2=`"$($T2+$ph2)`" stroke=`"#dddddd`" stroke-width=`"0.5`"/>")
    [void]$f.AppendLine("<text x=`"$x`" y=`"$($T2+$ph2+16)`" font-size=`"10`" text-anchor=`"middle`">$v</text>")
}
$row = 0
foreach ($st in $stats) {
    $cy = $T2 + $ph2 * (0.3 + 0.42 * $row)
    $bh = 34
    $fx = { param($val) $L2 + ([Math]::Min($val, $MaxDaysDisplay) / [double]$MaxDaysDisplay) * $pw2 }
    $x1 = & $fx $st.Q1; $x3 = & $fx $st.Q3; $xm = & $fx $st.Med
    $xl = & $fx $st.P5; $xh = & $fx $st.P95
    $fill = '#e8e8e8'; if ($row -eq 0) { $fill = 'url(#hatch2)' }
    if ($row -eq 0) { [void]$f.AppendLine('<defs><pattern id="hatch2" width="4" height="4" patternTransform="rotate(45)" patternUnits="userSpaceOnUse"><line x1="0" y1="0" x2="0" y2="4" stroke="#000000" stroke-width="1.4"/></pattern></defs>') }
    [void]$f.AppendLine("<line x1=`"$([Math]::Round($xl,1))`" y1=`"$([Math]::Round($cy,1))`" x2=`"$([Math]::Round($xh,1))`" y2=`"$([Math]::Round($cy,1))`" stroke=`"#000000`" stroke-width=`"1`"/>")
    foreach ($xw in @($xl, $xh)) { [void]$f.AppendLine("<line x1=`"$([Math]::Round($xw,1))`" y1=`"$([Math]::Round($cy-8,1))`" x2=`"$([Math]::Round($xw,1))`" y2=`"$([Math]::Round($cy+8,1))`" stroke=`"#000000`" stroke-width=`"1`"/>") }
    [void]$f.AppendLine("<rect x=`"$([Math]::Round($x1,1))`" y=`"$([Math]::Round($cy-$bh/2,1))`" width=`"$([Math]::Round($x3-$x1,1))`" height=`"$bh`" fill=`"$fill`" stroke=`"#000000`" stroke-width=`"1`"/>")
    [void]$f.AppendLine("<line x1=`"$([Math]::Round($xm,1))`" y1=`"$([Math]::Round($cy-$bh/2,1))`" x2=`"$([Math]::Round($xm,1))`" y2=`"$([Math]::Round($cy+$bh/2,1))`" stroke=`"#000000`" stroke-width=`"2.4`"/>")
    [void]$f.AppendLine("<text x=`"$($L2-10)`" y=`"$([Math]::Round($cy-2,1))`" font-size=`"11`" text-anchor=`"end`">$($st.Name)</text>")
    [void]$f.AppendLine("<text x=`"$($L2-10)`" y=`"$([Math]::Round($cy+12,1))`" font-size=`"9`" text-anchor=`"end`">n = $($st.N)</text>")
    $row++
}
[void]$f.AppendLine("<line x1=`"$L2`" y1=`"$($T2+$ph2)`" x2=`"$($L2+$pw2)`" y2=`"$($T2+$ph2)`" stroke=`"#000000`" stroke-width=`"1`"/>")
[void]$f.AppendLine("<text x=`"$($L2+$pw2/2)`" y=`"$($H2-8)`" font-size=`"11`" text-anchor=`"middle`">Time from publication to retraction (days), truncated at $MaxDaysDisplay</text>")
[void]$f.AppendLine('</svg>')
Set-Content -Path (Join-Path $OutDir 'Fig2.svg') -Value $f.ToString() -Encoding UTF8
Write-Host "Wrote Fig2.svg" -ForegroundColor Green
$stats | Format-Table -AutoSize
