UltimateCompleter.psm1

# Define the path to the JSON data file
$DataPath = Join-Path -Path $PSScriptRoot -ChildPath "completions.json"

# Load the JSON data into memory (Using -AsHashTable to prevent case collisions like -d vs -D)
if (Test-Path $DataPath) {
    # This requires PowerShell 6+ / 7
    $Global:UltimateCompletions = Get-Content -Raw -Path $DataPath | ConvertFrom-Json -AsHashTable
} else {
    Write-Warning "UltimateCompleter: completions.json not found!"
    return
}

# Find the root commands in the JSON and register a completer for each
foreach ($RootCommand in $Global:UltimateCompletions.Keys) {

    Register-ArgumentCompleter -CommandName $RootCommand, "$RootCommand.exe" -ScriptBlock {
        param($wordToComplete, $commandAst, $cursorPosition)

        $Elements = $commandAst.CommandElements
        $RawRoot = $Elements[0].Value
        $Root = ($RawRoot -replace '(?i)\.exe$', '').ToLower()

        if (-not $Global:UltimateCompletions.Contains($Root)) { return }
        $CurrentNode = $Global:UltimateCompletions[$Root]

        $Results = @()
        $IsTyping = ![string]::IsNullOrWhiteSpace($wordToComplete)
        $IgnoredItems = @('--color', '--version', '-v', '--help', '-h')

        # 1. SCAN FOR SUBCOMMAND: Scan the entire command line for a known subcommand
        $FoundSubCommand = $null
        $SubCommandIndex = -1

        for ($i = 1; $i -lt $Elements.Count; $i++) {
            $Value = $Elements[$i].Value.ToString().ToLower()
            # Do not treat the word currently being typed as a finalized subcommand
            if ($IsTyping -and $i -eq ($Elements.Count - 1)) { continue }

            if ($CurrentNode.Contains('subcommands') -and $CurrentNode['subcommands'].Contains($Value)) {
                $FoundSubCommand = $Value
                $SubCommandIndex = $i
                break
            }
        }

        # 2. DETERMINE ALREADY TYPED ARGUMENTS
        $AlreadyTyped = @()
        $StartIndex = if ($FoundSubCommand) { $SubCommandIndex + 1 } else { 1 }
        $EndIndex = if ($IsTyping) { $Elements.Count - 2 } else { $Elements.Count - 1 }

        if ($EndIndex -ge $StartIndex) {
            $AlreadyTyped = $Elements[$StartIndex..$EndIndex] | Select-Object -ExpandProperty Value
        }

        # 3. SMART DEPTH & STACKING LIMITER (The Magic Heuristic)
        # If any of the already typed arguments does NOT start with '-', we assume it's a
        # positional argument (like a filename, partition 'boot', or package name).
        # Once a positional argument is typed, we STOP suggesting flags and let PowerShell suggest files.
        $StopSuggesting = $false
        foreach ($Arg in $AlreadyTyped) {
            if (-not $Arg.StartsWith('-')) {
                $StopSuggesting = $true
                break
            }
        }

        if ($StopSuggesting) {
            return # Exit completer, enabling default file/path autocomplete
        }

        # 4. POPULATE RESULTS BASED ON CONTEXT
        if ($FoundSubCommand) {
            # Subcommand Context (e.g., fastboot flash)
            $SubNode = $CurrentNode['subcommands'][$FoundSubCommand]
            if ($SubNode.Contains('flags')) {
                $Results += ($SubNode['flags'] -is [System.Collections.Hashtable]) ? $SubNode['flags'].Keys : $SubNode['flags']
            }
        } else {
            # Root Context (e.g., fastboot)
            if ($CurrentNode.Contains('subcommands')) { $Results += $CurrentNode['subcommands'].Keys }
            if ($CurrentNode.Contains('flags')) {
                $Results += ($CurrentNode['flags'] -is [System.Collections.Hashtable]) ? $CurrentNode['flags'].Keys : $CurrentNode['flags']
            }
        }

        # 5. FILTER: Remove ignored items and already typed items (to prevent duplicates like vendor vendor)
        if ($AlreadyTyped.Count -gt 0) {
            $Results = $Results | Where-Object { $_ -notin $AlreadyTyped }
        }
        $Results = $Results | Where-Object { $_ -notin $IgnoredItems }

        if ($IsTyping) {
            $Results = $Results | Where-Object { $_ -like "$wordToComplete*" }
        }

        # 6. FORMAT: Convert to PowerShell's CompletionResult with Tooltips
        $Results | Select-Object -Unique | ForEach-Object {
            $ItemName = $_
            $Tooltip = $ItemName

            if ($CurrentNode.Contains('subcommands') -and $CurrentNode['subcommands'].Contains($ItemName)) {
                if ($CurrentNode['subcommands'][$ItemName].Contains('description')) {
                    $Tooltip = $CurrentNode['subcommands'][$ItemName]['description']
                }
            } elseif ($CurrentNode.Contains('flags') -and $CurrentNode['flags'] -is [System.Collections.Hashtable] -and $CurrentNode['flags'].Contains($ItemName)) {
                $Tooltip = $CurrentNode['flags'][$ItemName]
            } elseif ($FoundSubCommand) {
                $SubNode = $CurrentNode['subcommands'][$FoundSubCommand]
                if ($SubNode.Contains('flags') -and $SubNode['flags'] -is [System.Collections.Hashtable] -and $SubNode['flags'].Contains($ItemName)) {
                    $Tooltip = $SubNode['flags'][$ItemName]
                }
            }

            [System.Management.Automation.CompletionResult]::new($ItemName, $ItemName, 'ParameterValue', $Tooltip)
        }
    }
}