package piwigotools

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

type TimeResult time.Time

func (c *TimeResult) UnmarshalJSON(b []byte) error {
	value := strings.Trim(string(b), `"`) //get rid of "
	if value == "" || value == "null" {
		return nil
	}

	t, err := time.Parse("2006-01-02 15:04:05", value) //parse time
	if err != nil {
		return err
	}
	*c = TimeResult(t) //set result using the pointer
	return nil
}

func (c TimeResult) MarshalJSON() ([]byte, error) {
	switch s := c.String(); s {
	case "":
		return []byte("null"), nil
	default:
		return []byte(`"` + s + `"`), nil
	}
}

func (c TimeResult) String() string {
	t := c.toTime()
	if t.IsZero() {
		return ""
	} else {
		return t.Format("2006-01-02 15:04:05")
	}
}

func (c TimeResult) toTime() time.Time {
	return time.Time(c)
}

func (c TimeResult) AgeAt(createdAt *TimeResult) string {
	var year, month, day, hour, min, sec int
	a := c.toTime()
	if a.IsZero() {
		return ""
	}
	b := createdAt.toTime()
	if b.IsZero() {
		return ""
	}

	if a.Location() != b.Location() {
		b = b.In(a.Location())
	}
	if a.After(b) {
		a, b = b, a
	}
	y1, M1, d1 := a.Date()
	y2, M2, d2 := b.Date()

	h1, m1, s1 := a.Clock()
	h2, m2, s2 := b.Clock()

	year = int(y2 - y1)
	month = int(M2 - M1)
	day = int(d2 - d1)
	hour = int(h2 - h1)
	min = int(m2 - m1)
	sec = int(s2 - s1)

	// Normalize negative values
	if sec < 0 {
		sec += 60
		min--
	}
	if min < 0 {
		min += 60
		hour--
	}
	if hour < 0 {
		hour += 24
		day--
	}
	if day < 0 {
		// days in month:
		t := time.Date(y1, M1, 32, 0, 0, 0, 0, time.UTC)
		day += 32 - t.Day()
		month--
	}
	if month < 0 {
		month += 12
		year--
	}

	switch {
	case year == 1:
		return fmt.Sprintf("%d months old", 12+month)
	case year > 1:
		return fmt.Sprintf("%d years old", year)
	case month == 1:
		return fmt.Sprintf("%d month old", month)
	case month > 1:
		return fmt.Sprintf("%d months old", month)
	case day > 1:
		return fmt.Sprintf("%d days old", day)
	default:
		return fmt.Sprintf("%d day, %d hour", day, hour)
	}
}