package utils

import (
	"database/sql/driver"
	"fmt"
	"time"
)

type JsonTime struct {
	time.Time
}

func NewJsonTime(timeObj time.Time) JsonTime {
	return JsonTime{timeObj}
}

func Now() JsonTime {
	return JsonTime{Time: time.Now()}
}

const (
	timeFormat    = "2006-01-02 15:04:05"
	newTimeFormat = time.RFC3339
)

func (t JsonTime) FormatToStr() string {
	return t.Time.Format(newTimeFormat)
}

func (t JsonTime) MarshalJSON() ([]byte, error) {
	var stamp = fmt.Sprintf("\"%s\"", t.FormatToStr())
	return []byte(stamp), nil
}

func (ct *JsonTime) UnmarshalJSON(b []byte) (err error) {
	s := string(b)
	if s == "null" || s == "" {
		return
	}
	if b[0] == '"' && b[len(s)-1] == '"' && len(b) > 1 {
		s = string(b[1 : len(b)-1])
	}
	if s[10] == 'T' {
		ct.Time, err = time.Parse(newTimeFormat, s)
	} else {
		ct.Time, err = time.Parse(timeFormat, s)
	}
	return
}

// Value insert timestamp into mysql need this function.
func (t JsonTime) Value() (driver.Value, error) {
	var zeroTime time.Time
	if t.Time.UnixNano() == zeroTime.UnixNano() {
		return nil, nil
	}
	return t.Time, nil
}

func (t JsonTime) Before(u JsonTime) bool {
	return t.Time.Before(u.Time)
}

// Scan valueof time.Time
func (t *JsonTime) Scan(v interface{}) error {
	value, ok := v.(time.Time)
	if ok {
		*t = JsonTime{Time: value}
		return nil
	}
	return fmt.Errorf("can not convert %v to timestamp", v)
}
