package utils

import (
	"fmt"
	"math"
	"time"

	"github.com/pingcap-inc/clinic/clinic_data_service/pkg/dto"
)

const (
	DateLayout = "20060102"
)

func GetYesterdayStr(day string) (string, error) {
	d, err := time.Parse(DateLayout, day)
	if err != nil {
		return "", err
	}
	return d.AddDate(0, 0, -1).Format("20060102"), nil
}

func TimestampToTime(timestamp float64) time.Time {
	seconds := int64(timestamp)
	// nanoseconds := int64((timestamp - float64(seconds)) * 1e9)
	// return time.Unix(seconds, nanoseconds)
	return time.Unix(seconds, 0)
}
func GetRangeTime(dayStr string) (dto.TimeRange, error) {
	startTime, err := time.ParseInLocation("20060102", dayStr, time.UTC)
	if err != nil {
		return dto.TimeRange{}, fmt.Errorf("failed to parse day string: %w", err)
	}
	endTime := startTime.Add(time.Duration(24) * time.Hour)
	return dto.TimeRange{
		Start: startTime,
		End:   endTime,
	}, nil
}

func GetDateByStr(day string) (time.Time, error) {
	d, err := time.Parse(DateLayout, day)
	return d, err
}

func CalculateDiff(current, previous float64) *float64 {
	if previous == 0 {

		return nil
	}
	// if previous == 0 {
	// 	defaultValue := 100.0

	// 	return &defaultValue
	// }
	// if current == 0 {
	// 	defaultValue := -100.0
	// 	return &defaultValue
	// }

	diff := (current - previous) / previous * 100
	roundedDiff := math.Round(diff*100) / 100
	return &roundedDiff
}

func CalculatePercent(current, total float64) *float64 {
	if current == 0 {
		return nil
	}
	val := current / total * 100
	roundedDiff := math.Round(val*100) / 100
	return &roundedDiff
}

// RoundFloat rounds a float64 to the specified number of decimal places.
// If precision is not provided, it defaults to 2.
func RoundFloat(val float64, precision ...int) float64 {
	if math.IsNaN(val) || math.IsInf(val, 0) {
		return val
	}

	prec := 2 // default precision
	if len(precision) > 0 {
		prec = precision[0]
	}

	if prec < 0 {
		prec = 0
	}

	ratio := math.Pow(10, float64(prec))
	return math.Round(val*ratio) / ratio
}

func GetUtf8Location() *time.Location {
	loc, _ := time.LoadLocation("Asia/Shanghai")
	return loc
}
