package api

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

// Internationalization (i18n)
var Internationalization = map[string]map[string]string{}

func init() {
	Internationalization["pt-BR"] = map[string]string{
		"future": "em %s",
		"past":   "%s atrás",
		"s":      "alguns segundos",
		"ss":     "%d segundos",
		"m":      "um minuto",
		"mm":     "%d minutos",
		"h":      "uma hora",
		"hh":     "%d horas",
		"d":      "um dia",
		"dd":     "%d dias",
		"M":      "um mês",
		"MM":     "%d meses",
		"y":      "acerca de um ano",
		"yy":     "%d anos",
	}
}

func repeatCount(test bool) int {
	if test {
		return 1
	} else {
		return 2
	}
}

// FromDuration returns a friendly string representing an approximation of the
// given duration
func TimeAgoFromDuration(d time.Duration, locale ...string) string {
	var (
		loc                                 = localeparse(locale...)
		seconds                             = int(math.Floor(d.Seconds() + .50))
		templates                           = Internationalization[loc]
		minutes, hours, days, months, years int
		//
		format = func(prefix string, value int) string {
			id := strings.Repeat(prefix, repeatCount(value == 1))
			return fmt.Sprintf(
				templates[id],
				value,
			)
		}
	)

	switch {
	case seconds < 30:
		return templates["s"]
	case seconds < 60:
		return templates["ss"]
	}

	if minutes = div(seconds, 60); minutes < 60 {
		return format("m", minutes)
	}

	if hours = div(minutes, 60); hours < 24 {
		return format("h", hours)
	}

	if days = div(hours, 24); days < 31 {
		return format("d", days)
	}

	if months = div(days, 31); months < 12 {
		return format("M", months)
	}

	years = div(months, 12)

	return format("y", years)
}

func localeparse(locale ...string) (loc string) {
	if len(locale) > 0 {
		loc = locale[0]
	} else {
		loc = "pt-BR"
	}
	return
}

// FromTime returns a friendly string representing the approximate difference
// from the given time and time.Now()
func TimeAgoFromTime(t time.Time, locale ...string) string {

	var (
		loc       = localeparse(locale...)
		now       = time.Now()
		d         time.Duration
		id        string
		templates = Internationalization[loc]
	)

	if t.Before(now) {
		d = now.Sub(t)
		id = "past"
	} else {
		d = t.Sub(now)
		id = "future"
	}

	return fmt.Sprintf(templates[id], TimeAgoFromDuration(d, locale...))
}

func div(numerator int, denominator int) int {
	rem := numerator % denominator
	result := numerator / denominator

	if rem >= (denominator / 2) {
		result++
	}

	return result
}

// func round(f float64) int {
// 	return
// }

// func pluralize(i int, s string) string {
// 	var buf bytes.Buffer
// 	buf.WriteString(fmt.Sprintf("%d %s", i, s))
// 	if i != 1 {
// 		buf.WriteString("s")
// 	}
// 	return buf.String()
// }

// type TimeAgo struct {
// 	Locale    string
// 	templates map[string]string
// }

// func NewTimeAgo(locale ...string) *TimeAgo {

// 	return &TimeAgo{
// 		Locale:    L,
// 		templates: Internationalization[L],
// 	}
// }

// const (
// 	minute = 1
// 	hour   = minute * 60
// 	day    = hour * 24
// 	month  = day * 30
// 	year   = day * 365
// 	// quarter = year / 4
// )
