Functions/New-Issue.ps1

function New-Issue {
    <#
    .SYNOPSIS
        Crea una nueva issue en GitHub desde un archivo markdown con formato frontmatter.
     
    .DESCRIPTION
        Lee un archivo markdown con formato frontmatter YAML que contiene el título,
        labels y cuerpo de una issue, y la crea en el repositorio de GitHub actual.
         
        El archivo debe tener el siguiente formato:
        ---
        title: Título de la issue
        labels: bug,enhancement
        ---
         
        Cuerpo de la issue en markdown...
     
    .PARAMETER Path
        Ruta al archivo markdown que contiene la definición de la issue.
        El archivo debe tener formato frontmatter YAML válido.
     
    .PARAMETER Repository
        Repositorio de GitHub donde crear la issue.
        Formato: owner/repo
        Si no se especifica, usa el repositorio del directorio actual.
     
    .PARAMETER Template
        Crea un archivo template de issue en .dev/issues/issue-template.md
        Útil para empezar a crear nuevas issues con el formato correcto.
     
    .PARAMETER WhatIf
        Muestra qué se haría sin crear realmente la issue.
     
    .EXAMPLE
        New-Issue -Path .\issues\bug-login.md
 
        Crea una issue en el repositorio actual usando el archivo especificado.
     
    .EXAMPLE
        New-Issue -Template
 
        Crea un archivo template en .dev/issues/issue-template.md para empezar a escribir nuevas issues.
 
    .EXAMPLE
        New-Issue -Path .\issues\feature-dark-mode.md -Repository "usuario/proyecto"
 
        Crea una issue en un repositorio específico.
 
    .EXAMPLE
        New-Issue -Path .\issues\bug-performance.md -WhatIf
        Muestra un preview de la issue sin crearla realmente.
     
    .NOTES
        Requiere:
        - GitHub CLI (gh) instalado y autenticado
        - Estar en un repositorio Git (si no se especifica -Repository)
         
        Author: @ccisnedev
        Version: 1.0.0
    #>

    [CmdletBinding(
        SupportsShouldProcess,
        DefaultParameterSetName = 'CreateIssue'
    )]
    param(
        [Parameter(
            Mandatory,
            Position = 0,
            ValueFromPipeline,
            ValueFromPipelineByPropertyName,
            ParameterSetName = 'CreateIssue',
            HelpMessage = "Ruta al archivo de issue con formato frontmatter YAML"
        )]
        [ValidateScript({
            if (-not (Test-Path $_ -PathType Leaf)) {
                throw "El archivo '$_' no existe"
            }
            if ($_ -notmatch '\.(md|markdown)$') {
                throw "El archivo debe ser un archivo markdown (.md o .markdown)"
            }
            $true
        })]
        [string]$Path,

        [Parameter(
            ParameterSetName = 'CreateIssue',
            HelpMessage = "Repositorio GitHub (formato: owner/repo)"
        )]
        [ValidatePattern('^[\w-]+/[\w-]+$')]
        [string]$Repository,

        [Parameter(
            Mandatory,
            ParameterSetName = 'CreateTemplate',
            HelpMessage = "Crea un archivo template en .dev/issues/issue-template.md"
        )]
        [switch]$Template
    )

    begin {
        $ErrorActionPreference = 'Stop'
        Write-Verbose "Iniciando New-Issue"
    }

    process {
        try {
            # ParameterSet: CreateTemplate - Crear archivo template
            if ($PSCmdlet.ParameterSetName -eq 'CreateTemplate') {
                Write-Host ""
                Write-Host "╔════════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
                Write-Host "║ 📝 CREAR TEMPLATE DE ISSUE ║" -ForegroundColor Cyan
                Write-Host "╚════════════════════════════════════════════════════════════╝" -ForegroundColor Cyan
                Write-Host ""

                $targetDir = ".dev\issues"
                $targetFile = Join-Path $targetDir "issue-template.md"
                $sourceTemplate = Join-Path $PSScriptRoot "..\Resources\New-Issue\templates\issue-template.md"

                # Verificar si ya existe
                if (Test-Path $targetFile) {
                    Write-Host "⚠️ El archivo ya existe: $targetFile" -ForegroundColor Yellow
                    Write-Host ""
                    $overwrite = Read-Host "¿Deseas sobrescribirlo? (s/N)"
                    if ($overwrite -notmatch '^s|si|y|yes$') {
                        Write-Host ""
                        Write-Host "❌ Operación cancelada" -ForegroundColor Red
                        return
                    }
                }

                # Crear directorio si no existe
                if (-not (Test-Path $targetDir)) {
                    Write-Host "📁 Creando directorio: $targetDir" -ForegroundColor Yellow
                    New-Item -Path $targetDir -ItemType Directory -Force | Out-Null
                    Write-Host " ✅ Directorio creado" -ForegroundColor Green
                }

                # Copiar template
                Write-Host "📄 Creando template..." -ForegroundColor Yellow
                Copy-Item -Path $sourceTemplate -Destination $targetFile -Force
                Write-Host " ✅ Template creado" -ForegroundColor Green
                Write-Host ""

                Write-Host "╔════════════════════════════════════════════════════════════╗" -ForegroundColor Green
                Write-Host "║ ✅ TEMPLATE CREADO EXITOSAMENTE ║" -ForegroundColor Green
                Write-Host "╚════════════════════════════════════════════════════════════╝" -ForegroundColor Green
                Write-Host ""
                Write-Host "📍 Ubicación: " -NoNewline -ForegroundColor Yellow
                Write-Host $targetFile -ForegroundColor Cyan
                Write-Host ""
                Write-Host "💡 Edita el archivo y luego crea la issue con:" -ForegroundColor Yellow
                Write-Host " New-Issue -Path $targetFile" -ForegroundColor Cyan
                Write-Host ""

                return [PSCustomObject]@{
                    Success = $true
                    TemplatePath = $targetFile
                    Action = "Template Created"
                }
            }

            # ParameterSet: CreateIssue - Crear issue en GitHub
            # Banner
            Write-Host ""
            Write-Host "╔════════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
            Write-Host "║ 🎫 CREAR NUEVA ISSUE EN GITHUB ║" -ForegroundColor Cyan
            Write-Host "╚════════════════════════════════════════════════════════════╝" -ForegroundColor Cyan
            Write-Host ""

            # Validación 1: GitHub CLI
            Write-Host "🔍 Verificando GitHub CLI..." -ForegroundColor Yellow
            if (-not (Test-GitHubCLI)) {
                throw "GitHub CLI no está disponible"
            }
            Write-Host " ✅ GitHub CLI disponible y autenticado" -ForegroundColor Green
            Write-Host ""

            # Validación 2: Repositorio Git (solo si no se especifica -Repository)
            if (-not $Repository) {
                Write-Host "🔍 Verificando repositorio Git..." -ForegroundColor Yellow
                if (-not (Test-GitRepository)) {
                    throw "No estás en un repositorio Git y no especificaste -Repository"
                }
                Write-Host " ✅ Repositorio Git válido" -ForegroundColor Green
                Write-Host ""
            }

            # Validación 3: Leer y parsear archivo
            Write-Host "📄 Leyendo archivo de issue..." -ForegroundColor Yellow
            Write-Host " Archivo: $Path" -ForegroundColor Gray
            
            $resolvedPath = Resolve-Path $Path
            $issueData = Read-IssueFile -Path $resolvedPath
            
            Write-Host " ✅ Archivo parseado correctamente" -ForegroundColor Green
            Write-Host ""

            # Mostrar información de la issue
            Write-Host "📋 INFORMACIÓN DE LA ISSUE" -ForegroundColor Cyan
            Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor DarkGray
            Write-Host " Título: " -NoNewline -ForegroundColor Yellow
            Write-Host $issueData.Title -ForegroundColor White
            
            if ($issueData.Labels) {
                $formattedLabels = Format-Labels -Labels $issueData.Labels
                Write-Host " Labels: " -NoNewline -ForegroundColor Yellow
                Write-Host $formattedLabels -ForegroundColor Magenta
            } else {
                Write-Host " Labels: " -NoNewline -ForegroundColor Yellow
                Write-Host "(ninguno)" -ForegroundColor DarkGray
            }
            
            Write-Host " Cuerpo: " -NoNewline -ForegroundColor Yellow
            Write-Host "$($issueData.Body.Length) caracteres" -ForegroundColor Gray
            Write-Host ""

            # WhatIf: Mostrar preview y salir
            if ($PSCmdlet.ShouldProcess($issueData.Title, "Crear issue en GitHub")) {
                
                # Crear archivo temporal para el cuerpo
                $tempFile = [System.IO.Path]::GetTempFileName()
                try {
                    Set-Content -Path $tempFile -Value $issueData.Body -Encoding UTF8 -NoNewline

                    # Construir comando gh issue create
                    $ghArgs = @('issue', 'create', '--title', $issueData.Title, '--body-file', $tempFile)
                    
                    if ($issueData.Labels) {
                        $formattedLabels = Format-Labels -Labels $issueData.Labels
                        $ghArgs += @('--label', $formattedLabels)
                    }
                    
                    if ($Repository) {
                        $ghArgs += @('--repo', $Repository)
                    }

                    Write-Host "🚀 Creando issue en GitHub..." -ForegroundColor Yellow
                    Write-Verbose "Ejecutando: gh $($ghArgs -join ' ')"
                    
                    # Ejecutar gh issue create
                    $output = & gh @ghArgs 2>&1
                    
                    if ($LASTEXITCODE -eq 0) {
                        Write-Host ""
                        Write-Host "╔════════════════════════════════════════════════════════════╗" -ForegroundColor Green
                        Write-Host "║ ✅ ISSUE CREADA EXITOSAMENTE ║" -ForegroundColor Green
                        Write-Host "╚════════════════════════════════════════════════════════════╝" -ForegroundColor Green
                        Write-Host ""
                        Write-Host "🔗 URL: $output" -ForegroundColor Cyan
                        Write-Host ""
                        
                        # Mostrar últimas issues
                        Write-Host "📋 Últimas issues del repositorio:" -ForegroundColor Yellow
                        Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor DarkGray
                        
                        $listArgs = @('issue', 'list', '--limit', '5')
                        if ($Repository) {
                            $listArgs += @('--repo', $Repository)
                        }
                        & gh @listArgs
                        Write-Host ""
                        
                        # Retornar URL de la issue
                        return [PSCustomObject]@{
                            Success = $true
                            IssueUrl = $output.ToString().Trim()
                            Title = $issueData.Title
                            Labels = $issueData.Labels
                        }
                    }
                    else {
                        throw "Error al crear issue: $output"
                    }
                }
                finally {
                    # Limpiar archivo temporal
                    if (Test-Path $tempFile) {
                        Remove-Item $tempFile -Force -ErrorAction SilentlyContinue
                    }
                }
            }
            else {
                Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor DarkGray
                Write-Host ""
                Write-Host "ℹ️ Modo WhatIf: No se creó ninguna issue" -ForegroundColor Cyan
                Write-Host ""
                Write-Host "PREVIEW DEL CUERPO:" -ForegroundColor Yellow
                Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor DarkGray
                Write-Host $issueData.Body -ForegroundColor Gray
                Write-Host "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" -ForegroundColor DarkGray
                Write-Host ""
                
                return [PSCustomObject]@{
                    Success = $false
                    WhatIf = $true
                    Title = $issueData.Title
                    Labels = $issueData.Labels
                }
            }
        }
        catch {
            Write-Host ""
            Write-Host "╔════════════════════════════════════════════════════════════╗" -ForegroundColor Red
            Write-Host "║ ❌ ERROR ║" -ForegroundColor Red
            Write-Host "╚════════════════════════════════════════════════════════════╝" -ForegroundColor Red
            Write-Host ""
            Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red
            Write-Host ""
            
            if ($_.Exception.Message -notmatch "formato|frontmatter|title") {
                Write-Host "💡 Para ver el formato esperado del archivo, revisa:" -ForegroundColor Yellow
                $templatePath = Join-Path $PSScriptRoot "..\Resources\New-Issue\templates\issue-template.md"
                Write-Host " $templatePath" -ForegroundColor Cyan
                Write-Host ""
            }
            
            throw
        }
    }

    end {
        Write-Verbose "New-Issue completado"
    }
}