param(
    [string]$Output = "extractions_pdf_indexed_global",
    [switch]$Fresh,
    [switch]$IncludeRootPdfs,
    [int]$Limit = 0,
    [string]$PdfToText = "$env:LOCALAPPDATA\Microsoft\WinGet\Packages\oschwartz10612.Poppler_Microsoft.Winget.Source_8wekyb3d8bbwe\poppler-25.07.0\Library\bin\pdftotext.exe",
    [string]$PdfInfo = "$env:LOCALAPPDATA\Microsoft\WinGet\Packages\oschwartz10612.Poppler_Microsoft.Winget.Source_8wekyb3d8bbwe\poppler-25.07.0\Library\bin\pdfinfo.exe"
)

$ErrorActionPreference = "Stop"

$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$programmeDir = Resolve-Path (Join-Path $scriptDir "..")
$outputDir = Join-Path $programmeDir $Output

if ($Fresh -and (Test-Path $outputDir)) {
    $resolvedOutput = Resolve-Path $outputDir
    if (-not ($resolvedOutput.Path.StartsWith($programmeDir.Path))) {
        throw "Refus de supprimer hors Programme: $resolvedOutput"
    }
    Remove-Item -LiteralPath $resolvedOutput.Path -Recurse -Force
}

New-Item -ItemType Directory -Force -Path $outputDir | Out-Null

$pdfs = @()
$pdfs += Get-ChildItem -LiteralPath (Join-Path $programmeDir "Cycle 3") -Recurse -Filter "*.pdf" -File -ErrorAction SilentlyContinue
$pdfs += Get-ChildItem -LiteralPath (Join-Path $programmeDir "Cycle 4") -Recurse -Filter "*.pdf" -File -ErrorAction SilentlyContinue
if ($IncludeRootPdfs) {
    $pdfs += Get-ChildItem -LiteralPath $programmeDir -Filter "*.pdf" -File -ErrorAction SilentlyContinue
}

$pdfs = $pdfs | Sort-Object FullName
if ($Limit -gt 0) {
    $pdfs = $pdfs | Select-Object -First $Limit
}

$count = @($pdfs).Count
$width = [Math]::Max(3, "$count".Length)
$rows = New-Object System.Collections.Generic.List[object]

function Invoke-ExternalToFile {
    param(
        [string]$Exe,
        [string[]]$Arguments,
        [string]$OutputFile
    )

    $quotedExe = '"' + $Exe + '"'
    $quotedArgs = ($Arguments | ForEach-Object { '"' + ($_ -replace '"', '\"') + '"' }) -join " "
    $quotedOutput = '"' + $OutputFile + '"'
    $command = "$quotedExe $quotedArgs > $quotedOutput 2>&1"
    & cmd.exe /d /c $command
    return $LASTEXITCODE
}

for ($i = 0; $i -lt $count; $i++) {
    $pdf = $pdfs[$i]
    $id = ($i + 1).ToString().PadLeft($width, "0")
    $relativePath = $pdf.FullName.Substring($programmeDir.Path.Length + 1)
    $textFile = "$id.txt"
    $infoFile = "$id.pdfinfo.txt"
    $textPath = Join-Path $outputDir $textFile
    $infoPath = Join-Path $outputDir $infoFile

    Write-Host "[$id/$count] $relativePath"

    $status = "ok"
    $notes = New-Object System.Collections.Generic.List[string]

    try {
        $exitCode = Invoke-ExternalToFile -Exe $PdfInfo -Arguments @($pdf.FullName) -OutputFile $infoPath
        if ($exitCode -ne 0) {
            $status = "error"
            $notes.Add("pdfinfo exit code $exitCode")
        }
    } catch {
        $status = "error"
        $notes.Add("pdfinfo: $($_.Exception.Message)")
    }

    try {
        $exitCode = Invoke-ExternalToFile -Exe $PdfToText -Arguments @("-layout", $pdf.FullName, "-") -OutputFile $textPath
        if ($exitCode -ne 0) {
            $status = "error"
            $notes.Add("pdftotext exit code $exitCode")
        }
    } catch {
        $status = "error"
        $notes.Add("pdftotext: $($_.Exception.Message)")
    }

    $rows.Add([pscustomobject]@{
        Id = $id
        RelativePath = $relativePath
        TextFile = $textFile
        InfoFile = $infoFile
        SHA256 = (Get-FileHash -Algorithm SHA256 -LiteralPath $pdf.FullName).Hash
        SizeBytes = $pdf.Length
        Status = $status
        Notes = ($notes -join " | ")
    })
}

$manifestPath = Join-Path $outputDir "manifest.csv"
$rows | Export-Csv -Path $manifestPath -NoTypeInformation -Encoding UTF8

$errors = @($rows | Where-Object { $_.Status -ne "ok" }).Count
Write-Host "PDF indexés: $count"
Write-Host "Erreurs: $errors"
Write-Host "Dossier: $outputDir"

if ($errors -gt 0) {
    exit 1
}
