src/Import.ps1

# Import.ps1 - bring outside color schemes into the catalog.
#
# The moat is being the integration layer: rather than re-typing palettes, import
# the formats the community already publishes - iTerm2 .itermcolors, base16 yaml,
# and Windows Terminal scheme JSON - into a PoshPalette schemes/*.json entry.

$script:AnsiOrder = @('black','red','green','yellow','blue','purple','cyan','white',
    'brightBlack','brightRed','brightGreen','brightYellow','brightBlue','brightPurple','brightCyan','brightWhite')

function ConvertTo-PoshPaletteHex {
    param([double] $R, [double] $G, [double] $B)   # components 0..1
    '#{0:X2}{1:X2}{2:X2}' -f [int][Math]::Round($R * 255), [int][Math]::Round($G * 255), [int][Math]::Round($B * 255)
}

# iTerm2 .itermcolors is an XML plist of "Ansi N Color" + Background/Foreground/Cursor dicts.
function ConvertFrom-ITermColors {
    param([Parameter(Mandatory)][string] $Text)
    [xml] $xml = $Text
    $root = $xml.plist.dict
    $map = @{}
    $keys = $root.key
    $dicts = $root.dict
    for ($i = 0; $i -lt $keys.Count; $i++) {
        $d = $dicts[$i]
        $comp = @{}
        for ($j = 0; $j -lt $d.key.Count; $j++) { $comp[$d.key[$j]] = [double]$d.real[$j] }
        $map[$keys[$i]] = ConvertTo-PoshPaletteHex $comp['Red Component'] $comp['Green Component'] $comp['Blue Component']
    }
    $colors = [ordered]@{}
    for ($i = 0; $i -lt 16; $i++) { $colors[$script:AnsiOrder[$i]] = $map["Ansi $i Color"] }
    $colors['background']          = $map['Background Color']
    $colors['foreground']          = $map['Foreground Color']
    $colors['cursorColor']         = ($map['Cursor Color']    ?? $map['Foreground Color'])
    $colors['selectionBackground'] = ($map['Selection Color'] ?? $map['Background Color'])
    $colors
}

# base16 yaml: base00..base0F hex values, mapped to ANSI via the standard template.
function ConvertFrom-Base16 {
    param([Parameter(Mandatory)][string] $Text)
    $b = @{}
    foreach ($line in ($Text -split "`n")) {
        if ($line -match '^\s*(base0[0-9A-Fa-f])\s*:\s*"?#?([0-9A-Fa-f]{6})"?') {
            $b[$Matches[1].ToLower()] = '#' + $Matches[2].ToUpper()
        }
    }
    if ($b.Count -lt 16) { throw "Not a base16 scheme (found $($b.Count)/16 base colors)." }
    [ordered]@{
        black = $b['base00']; red = $b['base08']; green = $b['base0b']; yellow = $b['base0a']
        blue = $b['base0d']; purple = $b['base0e']; cyan = $b['base0c']; white = $b['base05']
        brightBlack = $b['base03']; brightRed = $b['base08']; brightGreen = $b['base0b']; brightYellow = $b['base0a']
        brightBlue = $b['base0d']; brightPurple = $b['base0e']; brightCyan = $b['base0c']; brightWhite = $b['base07']
        background = $b['base00']; foreground = $b['base05']
        cursorColor = $b['base05']; selectionBackground = $b['base02']
    }
}

# Windows Terminal scheme JSON is already close to our shape; normalize keys.
function ConvertFrom-WtScheme {
    param([Parameter(Mandatory)][string] $Text)
    $s = ConvertFrom-Jsonc $Text
    $colors = [ordered]@{}
    foreach ($k in $script:AnsiOrder) { if ($s.$k) { $colors[$k] = $s.$k } }
    foreach ($k in 'background','foreground','cursorColor','selectionBackground') { if ($s.$k) { $colors[$k] = $s.$k } }
    $colors
}

# Detect format, parse, and (optionally) save into schemes/<id>.json.
function Import-PoshPaletteScheme {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory, Position = 0)][string] $Path,
        [string] $Id,
        [string] $Name,
        [ValidateSet('auto','iterm','base16','wt')] [string] $Format = 'auto',
        [switch] $Save
    )
    if (-not (Test-Path $Path)) { throw "File not found: $Path" }
    $text = Get-Content $Path -Raw
    $ext  = [IO.Path]::GetExtension($Path).ToLower()

    if ($Format -eq 'auto') {
        $Format = if ($ext -eq '.itermcolors' -or $text -match '<plist') { 'iterm' }
                  elseif ($ext -in '.yaml','.yml' -or $text -match '(?m)^\s*base0[0-9A-Fa-f]\s*:') { 'base16' }
                  else { 'wt' }
    }
    $colors = switch ($Format) {
        'iterm'  { ConvertFrom-ITermColors $text }
        'base16' { ConvertFrom-Base16 $text }
        'wt'     { ConvertFrom-WtScheme $text }
    }

    if (-not $Id)   { $Id   = [IO.Path]::GetFileNameWithoutExtension($Path).ToLower() -replace '[^a-z0-9]+','-' -replace '(^-|-$)','' }
    if (-not $Name) { $Name = (Get-Culture).TextInfo.ToTitleCase(($Id -replace '-',' ')) }
    $scheme = [ordered]@{ id = $Id; name = $Name; colors = $colors }

    if ($Save) {
        $dir  = Join-Path (Get-PoshPaletteDataRoot) 'schemes'
        $dest = Join-Path $dir "$Id.json"
        Set-Content -Path $dest -Value ($scheme | ConvertTo-Json -Depth 32) -Encoding utf8
        Write-Host "Imported scheme '$Id' -> $dest" -ForegroundColor Green
    }
    [pscustomobject]$scheme
}