package text

import (
	"fmt"
	"math"
	"time"
)

// Pluralize returns "1 issue" or "2 issues" depending on count.
// It applies a simple "s" suffix rule.
func Pluralize(count int, singular string) string {
	if count == 1 {
		return fmt.Sprintf("%d %s", count, singular)
	}
	return fmt.Sprintf("%d %ss", count, singular)
}

// FuzzyAgo returns a human-friendly relative time string like "just now",
// "2 minutes ago", "3 hours ago", etc.
func FuzzyAgo(t time.Time) string {
	d := time.Since(t)

	if d < time.Minute {
		return "just now"
	}

	minutes := int(math.Floor(d.Minutes()))
	if minutes < 60 {
		return fmt.Sprintf("%s ago", Pluralize(minutes, "minute"))
	}

	hours := int(math.Floor(d.Hours()))
	if hours < 24 {
		return fmt.Sprintf("%s ago", Pluralize(hours, "hour"))
	}

	days := hours / 24
	if days < 30 {
		return fmt.Sprintf("%s ago", Pluralize(days, "day"))
	}

	months := days / 30
	if months < 12 {
		return fmt.Sprintf("%s ago", Pluralize(months, "month"))
	}

	years := months / 12
	return fmt.Sprintf("%s ago", Pluralize(years, "year"))
}

// Truncate shortens text to maxWidth, replacing the end with "..." if it exceeds
// the limit. If maxWidth is less than or equal to 3, the result is just "...".
func Truncate(text string, maxWidth int) string {
	if len(text) <= maxWidth {
		return text
	}
	if maxWidth <= 3 {
		return "..."[:maxWidth]
	}
	return text[:maxWidth-3] + "..."
}

// FormatDate returns a human-friendly relative time for TTY output, or an
// RFC3339 timestamp for piped output.
func FormatDate(t time.Time, isTTY bool) string {
	if isTTY {
		return FuzzyAgo(t)
	}
	return t.Format(time.RFC3339)
}
