param(
  [string]$Root = (Split-Path -Parent $PSScriptRoot)
)

$ErrorActionPreference = "Stop"
Add-Type -AssemblyName System.Drawing

$sourceDir = Join-Path $Root "screenshots"
$outputDir = Join-Path $Root "store-assets\ready-to-upload"
New-Item -ItemType Directory -Force -Path $outputDir | Out-Null

$purpleDark = [System.Drawing.ColorTranslator]::FromHtml("#281052")
$purple = [System.Drawing.ColorTranslator]::FromHtml("#6D35D8")
$purpleBright = [System.Drawing.ColorTranslator]::FromHtml("#8250E8")
$white = [System.Drawing.Color]::White
$ink = [System.Drawing.ColorTranslator]::FromHtml("#171429")

function New-Canvas([int]$Width, [int]$Height) {
  $bitmap = New-Object System.Drawing.Bitmap($Width, $Height, [System.Drawing.Imaging.PixelFormat]::Format32bppArgb)
  $bitmap.SetResolution(96, 96)
  return $bitmap
}

function Save-Png($Bitmap, [string]$Name) {
  $path = Join-Path $outputDir $Name
  $Bitmap.Save($path, [System.Drawing.Imaging.ImageFormat]::Png)
  return $path
}

function Set-Quality($Graphics) {
  $Graphics.SmoothingMode = [System.Drawing.Drawing2D.SmoothingMode]::HighQuality
  $Graphics.InterpolationMode = [System.Drawing.Drawing2D.InterpolationMode]::HighQualityBicubic
  $Graphics.PixelOffsetMode = [System.Drawing.Drawing2D.PixelOffsetMode]::HighQuality
  $Graphics.TextRenderingHint = [System.Drawing.Text.TextRenderingHint]::ClearTypeGridFit
}

function Draw-Cover($Graphics, $Image, [System.Drawing.Rectangle]$Destination, [System.Drawing.Rectangle]$Source) {
  $sourceRatio = $Source.Width / $Source.Height
  $destinationRatio = $Destination.Width / $Destination.Height
  if ($sourceRatio -gt $destinationRatio) {
    $cropWidth = [int]($Source.Height * $destinationRatio)
    $Source.X += [int](($Source.Width - $cropWidth) / 2)
    $Source.Width = $cropWidth
  } else {
    $cropHeight = [int]($Source.Width / $destinationRatio)
    $Source.Y += [int](($Source.Height - $cropHeight) / 2)
    $Source.Height = $cropHeight
  }
  $Graphics.DrawImage($Image, $Destination, $Source, [System.Drawing.GraphicsUnit]::Pixel)
}

function Draw-Header($Graphics, [string]$Title, [string]$Subtitle) {
  $brush = New-Object System.Drawing.Drawing2D.LinearGradientBrush(
    (New-Object System.Drawing.Rectangle(0, 0, 1280, 112)),
    $purpleBright,
    $purpleDark,
    0
  )
  $titleFont = New-Object System.Drawing.Font("Segoe UI", 27, [System.Drawing.FontStyle]::Bold)
  $subtitleFont = New-Object System.Drawing.Font("Segoe UI", 15, [System.Drawing.FontStyle]::Regular)
  try {
    $Graphics.FillRectangle($brush, 0, 0, 1280, 112)
    $Graphics.DrawString($Title, $titleFont, [System.Drawing.Brushes]::White, 38, 20)
    $Graphics.DrawString($Subtitle, $subtitleFont, [System.Drawing.Brushes]::White, 40, 67)
  } finally {
    $brush.Dispose(); $titleFont.Dispose(); $subtitleFont.Dispose()
  }
}

function Redact-SandboxName($Graphics) {
  $cover = New-Object System.Drawing.SolidBrush([System.Drawing.Color]::White)
  try { $Graphics.FillRectangle($cover, 128, 124, 150, 34) } finally { $cover.Dispose() }
}

function Build-Screenshot([string]$Name, [string]$SourceName, [string]$Title, [string]$Subtitle, [System.Drawing.Rectangle]$Crop, [bool]$Redact) {
  $source = [System.Drawing.Image]::FromFile((Join-Path $sourceDir $SourceName))
  $canvas = New-Canvas 1280 800
  $graphics = [System.Drawing.Graphics]::FromImage($canvas)
  try {
    Set-Quality $graphics
    Draw-Header $graphics $Title $Subtitle
    Draw-Cover $graphics $source (New-Object System.Drawing.Rectangle(0, 112, 1280, 688)) $Crop
    if ($Redact) { Redact-SandboxName $graphics }
    Save-Png $canvas $Name | Out-Null
  } finally {
    $graphics.Dispose(); $canvas.Dispose(); $source.Dispose()
  }
}

$viewportCrop = New-Object System.Drawing.Rectangle(0, 100, 1920, 1040)
Build-Screenshot "01-original-canvas-page.png" "original.png" "A normal Canvas lesson page" "Global and course navigation surround the lesson." $viewportCrop $true
Build-Screenshot "02-lildra-focused-reading.png" "lildra.png" "A calmer reading view" "Lildra hides surrounding navigation and centres the lesson." $viewportCrop $false
Build-Screenshot "03-sticky-dynamic-title.png" "lildra.png" "The lesson title stays visible" "A compact title bar follows the current Canvas page title." (New-Object System.Drawing.Rectangle(170, 100, 1580, 850)) $false
Build-Screenshot "04-original-content-preserved.png" "lildra.png" "Original lesson content remains" "Headings, text and images remain in the original page." (New-Object System.Drawing.Rectangle(270, 240, 1500, 850)) $false

$before = [System.Drawing.Image]::FromFile((Join-Path $sourceDir "original.png"))
$after = [System.Drawing.Image]::FromFile((Join-Path $sourceDir "lildra.png"))
$comparison = New-Canvas 1280 800
$graphics = [System.Drawing.Graphics]::FromImage($comparison)
try {
  Set-Quality $graphics
  Draw-Header $graphics "Before and after" "The same lesson, with surrounding Canvas navigation hidden."
  Draw-Cover $graphics $before (New-Object System.Drawing.Rectangle(0, 112, 632, 688)) (New-Object System.Drawing.Rectangle(0, 100, 1050, 1040))
  Draw-Cover $graphics $after (New-Object System.Drawing.Rectangle(648, 112, 632, 688)) (New-Object System.Drawing.Rectangle(250, 100, 1050, 1040))
  $divider = New-Object System.Drawing.SolidBrush($purple)
  $labelFont = New-Object System.Drawing.Font("Segoe UI", 15, [System.Drawing.FontStyle]::Bold)
  try {
    $graphics.FillRectangle($divider, 632, 112, 16, 688)
    $graphics.FillRectangle([System.Drawing.Brushes]::White, 18, 130, 92, 34)
    $graphics.FillRectangle([System.Drawing.Brushes]::White, 666, 130, 92, 34)
    $graphics.DrawString("Before", $labelFont, (New-Object System.Drawing.SolidBrush($ink)), 28, 134)
    $graphics.DrawString("Lildra", $labelFont, (New-Object System.Drawing.SolidBrush($purple)), 676, 134)
    # Remove the private sandbox course name from the before panel.
    $graphics.FillRectangle([System.Drawing.Brushes]::White, 102, 124, 145, 36)
  } finally { $divider.Dispose(); $labelFont.Dispose() }
  Save-Png $comparison "05-before-and-after.png" | Out-Null
} finally {
  $graphics.Dispose(); $comparison.Dispose(); $before.Dispose(); $after.Dispose()
}

# Create a store icon candidate from the established logo. Only edge-connected
# near-white canvas pixels are removed; the white L inside the purple mark remains.
$originalIcon = [System.Drawing.Image]::FromFile((Join-Path $Root "icons\LildraLogoHiRes.png"))
$sourceIcon = New-Canvas $originalIcon.Width $originalIcon.Height
$sourceGraphics = [System.Drawing.Graphics]::FromImage($sourceIcon)
try {
  $sourceGraphics.DrawImageUnscaled($originalIcon, 0, 0)
} finally {
  $sourceGraphics.Dispose(); $originalIcon.Dispose()
}
$visited = New-Object 'bool[,]' $sourceIcon.Width, $sourceIcon.Height
$queue = New-Object 'System.Collections.Generic.Queue[System.Drawing.Point]'
for ($x = 0; $x -lt $sourceIcon.Width; $x++) {
  $queue.Enqueue([System.Drawing.Point]::new($x, 0))
  $queue.Enqueue([System.Drawing.Point]::new($x, ($sourceIcon.Height - 1)))
}
for ($y = 0; $y -lt $sourceIcon.Height; $y++) {
  $queue.Enqueue([System.Drawing.Point]::new(0, $y))
  $queue.Enqueue([System.Drawing.Point]::new(($sourceIcon.Width - 1), $y))
}
while ($queue.Count -gt 0) {
  $point = $queue.Dequeue()
  if ($point.X -lt 0 -or $point.Y -lt 0 -or $point.X -ge $sourceIcon.Width -or $point.Y -ge $sourceIcon.Height -or $visited[$point.X, $point.Y]) { continue }
  $visited[$point.X, $point.Y] = $true
  $pixel = $sourceIcon.GetPixel($point.X, $point.Y)
  if ($pixel.R -lt 215 -or $pixel.G -lt 215 -or $pixel.B -lt 215) { continue }
  $sourceIcon.SetPixel($point.X, $point.Y, [System.Drawing.Color]::Transparent)
  $queue.Enqueue([System.Drawing.Point]::new(($point.X + 1), $point.Y))
  $queue.Enqueue([System.Drawing.Point]::new(($point.X - 1), $point.Y))
  $queue.Enqueue([System.Drawing.Point]::new($point.X, ($point.Y + 1)))
  $queue.Enqueue([System.Drawing.Point]::new($point.X, ($point.Y - 1)))
}
$storeIcon = New-Canvas 128 128
$graphics = [System.Drawing.Graphics]::FromImage($storeIcon)
try {
  Set-Quality $graphics
  $graphics.Clear([System.Drawing.Color]::Transparent)
  $graphics.DrawImage($sourceIcon, (New-Object System.Drawing.Rectangle(16, 16, 96, 96)))
  Save-Png $storeIcon "store-icon-128.png" | Out-Null
} finally { $graphics.Dispose(); $storeIcon.Dispose(); $sourceIcon.Dispose() }

$icon = [System.Drawing.Image]::FromFile((Join-Path $outputDir "store-icon-128.png"))
$focused = [System.Drawing.Image]::FromFile((Join-Path $sourceDir "lildra.png"))
foreach ($promo in @(
  @{Name="small-promo-440x280.png"; Width=440; Height=280; Icon=112; Screenshot=$false},
  @{Name="marquee-promo-1400x560.png"; Width=1400; Height=560; Icon=170; Screenshot=$true}
)) {
  $canvas = New-Canvas $promo.Width $promo.Height
  $graphics = [System.Drawing.Graphics]::FromImage($canvas)
  $gradient = New-Object System.Drawing.Drawing2D.LinearGradientBrush(
    (New-Object System.Drawing.Rectangle(0, 0, $promo.Width, $promo.Height)),
    $purpleBright,
    $purpleDark,
    12
  )
  $nameFont = New-Object System.Drawing.Font("Segoe UI", $(if($promo.Width -gt 500){58}else{34}), [System.Drawing.FontStyle]::Bold)
  $tagFont = New-Object System.Drawing.Font("Segoe UI", $(if($promo.Width -gt 500){24}else{15}), [System.Drawing.FontStyle]::Regular)
  try {
    Set-Quality $graphics
    $graphics.FillRectangle($gradient, 0, 0, $promo.Width, $promo.Height)
    $iconX = $(if($promo.Width -gt 500){80}else{34})
    $iconY = [int](($promo.Height - $promo.Icon) / 2)
    $graphics.DrawImage($icon, $iconX, $iconY, $promo.Icon, $promo.Icon)
    $textX = $iconX + $promo.Icon + $(if($promo.Width -gt 500){42}else{22})
    $graphics.DrawString("Lildra", $nameFont, [System.Drawing.Brushes]::White, $textX, $(if($promo.Width -gt 500){170}else{105}))
    if ($promo.Width -gt 500) {
      $graphics.DrawString("Distraction-free lesson reading", $tagFont, [System.Drawing.Brushes]::White, $textX + 2, 250)
    }
    if ($promo.Screenshot) {
      $panel = New-Object System.Drawing.Rectangle(785, 55, 570, 450)
      Draw-Cover $graphics $focused $panel $viewportCrop
    }
    Save-Png $canvas $promo.Name | Out-Null
  } finally {
    $gradient.Dispose(); $nameFont.Dispose(); $tagFont.Dispose(); $graphics.Dispose(); $canvas.Dispose()
  }
}
$icon.Dispose(); $focused.Dispose()

Get-ChildItem -LiteralPath $outputDir -File | Sort-Object Name | Select-Object Name, Length
