package tprint

import (
	"strings"
	"unicode"

	"github.com/mattn/go-runewidth"
)

func Search[T any](slice []T, cmp func(a, b T) T) T {
	best := *new(T)
	for _, v := range slice {
		best = cmp(v, best)
	}
	return best
}

func maxLengthStr(a, b string) string {
	if strLen(a) > strLen(b) {
		return a
	}
	return b
}

func maxLengthSlice[T any](a, b []T) []T {
	if len(a) > len(b) {
		return a
	}
	return b
}

func strLen(str string) int {
	l := 0

	runes := []rune(str)

	for i := 0; i < len(runes); i++ {
		rn := runes[i]

		// skip control sequences
		if unicode.IsControl(rn) {
			for j := i; j < len(runes)-1 && runes[j] != 'm'; j++ {
				i = j
			}
			i++
			continue
		}

		if rn <= 0xFF || rn >= '─' && rn <= '╿' {
			l++
		} else {
			l += runewidth.RuneWidth(rn)
		}
	}

	return l
}

func padStringRight(str string, pad rune, length int) string {
	padding := length - strLen(str)
	return str + strings.Repeat(string(pad), padding)
}

func padStringLeft(str string, pad rune, length int) string {
	padding := length - strLen(str)
	return strings.Repeat(string(pad), padding) + str
}

func padStringCenter(str string, pad rune, length int) string {
	l := strLen(str)
	return padStringLeft(padStringRight(str, pad, (length-l)/2+l), pad, length)
}