Write-Text.psm1

function Write-Text {
    param(
        [Parameter(Mandatory=$true, ValueFromPipeline=$true)]
        [object]$Object,

        [string]$ForegroundColor,
        [string]$BackgroundColor,
        [switch]$NoNewline
    )

    process {
        $outputText = $Object.ToString()

        $ansiCodes = @()

        if ($ForegroundColor) {
            $ansiCodes += ConvertTo-AnsiColor -HexColor $ForegroundColor -IsBackground:$false
        }

        if ($BackgroundColor) {
            $ansiCodes += ConvertTo-AnsiColor -HexColor $BackgroundColor -IsBackground:$true
        }

        $ansiSequence = if ($ansiCodes.Count -gt 0) {
            "`e[$($ansiCodes -join ';')m"
        } else {
            ""
        }

        $resetSequence = "`e[0m"

        if ($NoNewline) {
            [Console]::Write("${ansiSequence}${outputText}${resetSequence}")
        } else {
            [Console]::WriteLine("${ansiSequence}${outputText}${resetSequence}")
        }
    }
}

function ConvertTo-AnsiColor {
    param(
        [string]$HexColor,
        [switch]$IsBackground
    )
    
    $hex = $HexColor.TrimStart('#')
    if ($hex.Length -ne 6) { return "" }
    
    $r = [Convert]::ToInt32($hex.Substring(0,2), 16)
    $g = [Convert]::ToInt32($hex.Substring(2,2), 16)
    $b = [Convert]::ToInt32($hex.Substring(4,2), 16)
    
    # ANSI 真彩色序列:38;2;R;G;B(前景)或 48;2;R;G;B(背景)
    $colorType = if ($IsBackground) { 48 } else { 38 }
    return "$colorType;2;$r;$g;$b"
}