package web

import (
	"fmt"
	"io"
	"net/http"
	"strings"
)

func renderStatus(code int) http.HandlerFunc {
	return func(w http.ResponseWriter, _ *http.Request) {
		w.WriteHeader(code)
		io.WriteString(w, fmt.Sprintf("%d %s", code, http.StatusText(code))) //nolint: errcheck
	}
}

// ParseTrailers extracts Git commit message trailers from the given message.
// Trailers are key-value pairs at the end of the commit message in the format
// "Key: value". This function returns a map where keys are normalized to lowercase
// and values are arrays to support multiple trailers with the same key.
func ParseTrailers(message string) map[string][]string {
	trailers := make(map[string][]string)

	lines := strings.Split(message, "\n")

	// Trim trailing blank lines so we don't select an empty "block" past the end
	for len(lines) > 0 && strings.TrimSpace(lines[len(lines)-1]) == "" {
		lines = lines[:len(lines)-1]
	}
	if len(lines) == 0 {
		return trailers
	}

	// Find the start of the last paragraph (after the last blank line)
	start := 0
	for i := len(lines) - 1; i >= 0; i-- {
		if strings.TrimSpace(lines[i]) == "" {
			start = i + 1
			break
		}
	}

	// Parse trailers from the trailer block, skipping non-trailer lines
	for i := start; i < len(lines); i++ {
		line := strings.TrimSpace(lines[i])
		if line == "" {
			continue
		}
		if key, value, ok := parseTrailerLine(line); ok {
			key = strings.ToLower(key)
			trailers[key] = append(trailers[key], value)
		}
	}

	return trailers
}

// parseTrailerLine extracts the key and value from a trailer line.
func parseTrailerLine(line string) (key, value string, ok bool) {
	// Split on first : or #
	sepIdx := -1
	for i, ch := range line {
		if ch == ':' || ch == '#' {
			sepIdx = i
			break
		}
	}

	if sepIdx == -1 {
		return "", "", false
	}

	key = strings.TrimSpace(line[:sepIdx])
	value = strings.TrimSpace(line[sepIdx+1:])

	if key == "" || value == "" {
		return "", "", false
	}

	return key, value, true
}

// GetCoAuthors extracts co-author names from commit message trailers.
// It looks for "Co-authored-by" or "Co-Authored-By" trailers and extracts
// the name portion (without email address).
func GetCoAuthors(message string) []string {
	trailers := ParseTrailers(message)
	coAuthors := []string{}

	// Look for co-authored-by trailer (case-insensitive)
	if authors, ok := trailers["co-authored-by"]; ok {
		for _, author := range authors {
			// Extract name from "Name <email>" format
			name := extractName(author)
			if name != "" {
				coAuthors = append(coAuthors, name)
			}
		}
	}

	return coAuthors
}

// extractName extracts the name portion from "Name <email>" format.
// If no email is present, returns the entire string trimmed.
func extractName(author string) string {
	// Look for "Name <email>" pattern
	if idx := strings.Index(author, "<"); idx != -1 {
		return strings.TrimSpace(author[:idx])
	}
	return strings.TrimSpace(author)
}
