param(
  [string]$BaseUrl = "http://localhost/invitacion/public/index.php",
  [int]$TimeoutSec = 20
)

$ErrorActionPreference = "Stop"

$session = New-Object Microsoft.PowerShell.Commands.WebRequestSession
$results = @()

function Add-Result {
  param(
    [string]$Step,
    [bool]$Ok,
    [string]$Detail
  )
  $script:results += [pscustomobject]@{
    Step = $Step
    OK = $Ok
    Detail = $Detail
  }
}

function Test-Step {
  param(
    [string]$Name,
    [scriptblock]$Action
  )
  try {
    $detail = & $Action
    Add-Result -Step $Name -Ok $true -Detail ([string]$detail)
  } catch {
    Add-Result -Step $Name -Ok $false -Detail $_.Exception.Message
  }
}

function Get-CartQtyFromHtml {
  param([string]$Html)
  $m = [regex]::Match($Html, 'Cantidad:\s*<strong>(\d+)</strong>')
  if (-not $m.Success) { return $null }
  return [int]$m.Groups[1].Value
}

Test-Step "Home carga" {
  $r = Invoke-WebRequest -Uri $BaseUrl -WebSession $session -UseBasicParsing -TimeoutSec $TimeoutSec
  if ($r.StatusCode -ne 200) { throw "Status $($r.StatusCode)" }
  "200 OK"
}

$email = "qa_smoke_{0}@test.local" -f ([DateTime]::UtcNow.ToString("yyyyMMdd_HHmmss"))

Test-Step "Registro usuario" {
  $reg = Invoke-WebRequest -Uri ($BaseUrl + "?route=register") -Method Post -Body @{
    name = "QA Smoke"
    email = $email
    password = "12345678"
  } -WebSession $session -UseBasicParsing -MaximumRedirection 5 -TimeoutSec $TimeoutSec
  if ($reg.Content -notmatch "Dashboard del Cliente") { throw "No redirigio a dashboard" }
  $email
}

Test-Step "Seleccion invitacion" {
  $sel = Invoke-WebRequest -Uri ($BaseUrl + "?route=seleccionar-invitacion") -Method Post -Body @{
    id = "1"
  } -WebSession $session -UseBasicParsing -MaximumRedirection 5 -TimeoutSec $TimeoutSec
  if ($sel.Content -notmatch "Producto escogido") { throw "No se marco producto seleccionado" }
  "Producto 1"
}

$inviteUrl = $null
Test-Step "Preview invitacion personalizada" {
  $dash = Invoke-WebRequest -Uri ($BaseUrl + "?route=dashboard") -WebSession $session -UseBasicParsing -TimeoutSec $TimeoutSec
  $href = [regex]::Match($dash.Content, 'href=\"([^\"]*floral-sobre-tech/index\.html[^\"]*)\"').Groups[1].Value
  if ([string]::IsNullOrWhiteSpace($href)) { throw "No se encontro href de invitacion" }
  $href = $href -replace "&amp;", "&"
  if ($href.StartsWith("/")) {
    $inviteUrl = "http://localhost" + $href
  } elseif ($href.StartsWith("http")) {
    $inviteUrl = $href
  } else {
    $inviteUrl = "http://localhost/invitacion/public/" + $href
  }
  $inv = Invoke-WebRequest -Uri $inviteUrl -UseBasicParsing -TimeoutSec $TimeoutSec
  if ($inv.StatusCode -ne 200) { throw "Status invitacion $($inv.StatusCode)" }
  $inviteUrl
}

Test-Step "Guardar evento con requeridos" {
  $form = @{
    title = "Evento Smoke"
    event_date = "2026-12-20"
    venue = "Salon Smoke"
    notes = "Prueba de smoke test"
    "details[main_person_name]" = "Valeria"
    "details[secondary_person_name]" = "Emiliano"
    "details[event_date]" = "2026-12-20"
    "details[event_time]" = "18:00"
    "details[salon_name]" = "Salon Smoke"
    "details[event_address]" = "Direccion Smoke 123"
    "details[contact_whatsapp]" = "+525512345678"
  }
  $evt = Invoke-WebRequest -Uri ($BaseUrl + "?route=organizar-evento") -Method Post -Body $form -WebSession $session -UseBasicParsing -TimeoutSec $TimeoutSec
  if ($evt.Content -notmatch "Evento guardado correctamente") { throw "No guardo evento" }
  "Evento guardado"
}

Test-Step "Alta invitado manual" {
  $g = Invoke-WebRequest -Uri ($BaseUrl + "?route=invitados") -Method Post -Body @{
    mode = "manual"
    name = "Invitado Smoke"
    phone = "5551234567"
    email = "guest_smoke@test.local"
    adults = "2"
    kids = "0"
  } -WebSession $session -UseBasicParsing -TimeoutSec $TimeoutSec
  if ($g.Content -notmatch "Invitado agregado correctamente") { throw "No agrego invitado" }
  "Invitado agregado"
}

Test-Step "Marcar envio invitaciones" {
  $send = Invoke-WebRequest -Uri ($BaseUrl + "?route=enviar-invitaciones") -Method Post -Body @{} -WebSession $session -UseBasicParsing -TimeoutSec $TimeoutSec
  if ($send.Content -notmatch "Invitaciones marcadas como enviadas") { throw "No marco envio" }
  "Envio marcado"
}

Test-Step "Carrito cantidad y remove" {
  $cartBefore = Invoke-WebRequest -Uri ($BaseUrl + "?route=cart") -WebSession $session -UseBasicParsing -TimeoutSec $TimeoutSec
  $qtyBefore = Get-CartQtyFromHtml -Html $cartBefore.Content
  if ($null -eq $qtyBefore) { $qtyBefore = 0 }

  Invoke-WebRequest -Uri ($BaseUrl + "?route=add-to-cart") -Method Post -Body @{ id = "1"; qty = "2" } -WebSession $session -UseBasicParsing -MaximumRedirection 5 -TimeoutSec $TimeoutSec | Out-Null
  $cartAfterAdd = Invoke-WebRequest -Uri ($BaseUrl + "?route=cart") -WebSession $session -UseBasicParsing -TimeoutSec $TimeoutSec
  $qtyAfterAdd = Get-CartQtyFromHtml -Html $cartAfterAdd.Content
  if ($null -eq $qtyAfterAdd) { throw "No se pudo leer cantidad tras agregar" }
  if ($qtyAfterAdd -lt ($qtyBefore + 2)) { throw "Cantidad no incremento correctamente: before=$qtyBefore after_add=$qtyAfterAdd" }

  Invoke-WebRequest -Uri ($BaseUrl + "?route=remove-from-cart") -Method Post -Body @{ id = "1"; qty = "1" } -WebSession $session -UseBasicParsing -MaximumRedirection 5 -TimeoutSec $TimeoutSec | Out-Null
  $cartAfterRemove = Invoke-WebRequest -Uri ($BaseUrl + "?route=cart") -WebSession $session -UseBasicParsing -TimeoutSec $TimeoutSec
  $qtyAfterRemove = Get-CartQtyFromHtml -Html $cartAfterRemove.Content
  if ($null -eq $qtyAfterRemove) { $qtyAfterRemove = 0 }
  if ($qtyAfterRemove -ne ($qtyAfterAdd - 1)) {
    throw "Remove por cantidad incorrecto: after_add=$qtyAfterAdd after_remove=$qtyAfterRemove"
  }
  "Carrito OK (before=$qtyBefore, add=$qtyAfterAdd, remove=$qtyAfterRemove)"
}

Test-Step "Webhook pago" {
  $sid = "cs_smoke_" + [DateTime]::UtcNow.ToString("yyyyMMddHHmmss")
  $createCmd = "require 'vendor/autoload.php'; require 'src/db.php'; \App\Order::create('$sid',12345,'pending',null); echo 'CREATED';"
  php -r $createCmd | Out-Null
  $payload = "{`"type`":`"checkout.session.completed`",`"data`":{`"object`":{`"id`":`"$sid`"}}}"
  try {
    $resp = Invoke-WebRequest -Uri "http://localhost/invitacion/public/webhook.php" -Method Post -Body $payload -ContentType "application/json" -UseBasicParsing -TimeoutSec $TimeoutSec
  } catch {
    if ($_.Exception.Response -and $_.Exception.Response.StatusCode) {
      throw "Webhook status $([int]$_.Exception.Response.StatusCode)"
    }
    throw
  }
  if ($resp.StatusCode -ne 200) { throw "Webhook status $($resp.StatusCode)" }
  $checkCmd = "require 'vendor/autoload.php'; require 'src/db.php'; `$o=\App\Order::findBySession('$sid'); echo (`$o['status'] ?? 'null');"
  $st = php -r $checkCmd
  if ($st -notmatch "paid") { throw "Estado orden no actualizado: $st" }
  "Webhook OK"
}

Write-Host ""
Write-Host "=== Smoke Test Report ==="
$results | ForEach-Object {
  $icon = if ($_.OK) { "[PASS]" } else { "[FAIL]" }
  Write-Host "$icon $($_.Step) - $($_.Detail)"
}

$failCount = ($results | Where-Object { -not $_.OK }).Count
Write-Host ""
Write-Host ("Total: {0}, Passed: {1}, Failed: {2}" -f $results.Count, ($results.Count - $failCount), $failCount)

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