package helpers

import (
	"fmt"
	"math"
	"pool-stats/models"
	"sort"
	"strconv"
	"strings"
	"time"
)

func HumanDiff(diff float64) string {
	units := []string{"", "K", "M", "G", "T"}
	i := 0
	for diff >= 1000 && i < len(units)-1 {
		diff /= 1000
		i++
	}
	return fmt.Sprintf("%.2f%s", diff, units[i])
}

func ParseCreateDate(createdate string) time.Time {
	parts := strings.Split(createdate, ",")
	if len(parts) == 2 {
		sec, _ := strconv.ParseInt(parts[0], 10, 64)
		nsec, _ := strconv.ParseInt(parts[1], 10, 64)
		return time.Unix(sec, nsec)
	}
	return time.Time{}
}

func FormatCreateDate(createdate string) string {
	parts := strings.Split(createdate, ",")
	if len(parts) == 2 {
		sec, _ := strconv.ParseInt(parts[0], 10, 64)
		nsec, _ := strconv.ParseInt(parts[1], 10, 64)
		t := time.Unix(sec, nsec)
		return t.Format(time.DateTime)
	}
	return "-"
}

func CalculateAverageHashrate(shares []models.ShareLog) float64 {
	if len(shares) == 0 {
		return 0.0
	}

	sort.Slice(shares, func(i, j int) bool {
		return shares[i].CreateDate < shares[j].CreateDate
	})

	first := ParseCreateDate(shares[0].CreateDate)
	last := ParseCreateDate(shares[len(shares)-1].CreateDate)
	timeSpan := last.Sub(first).Seconds()
	if timeSpan <= 0 {
		return 0.0
	}

	var totalAssignedDiff float64
	for _, s := range shares {
		totalAssignedDiff += s.Diff
	}

	avgAssignedDiff := totalAssignedDiff / float64(len(shares))

	// Hashrate = avg diff * 2^32 / avg time per share
	hashrate := (avgAssignedDiff * math.Pow(2, 32)) / (timeSpan / float64(len(shares)))
	return hashrate
}

func FormatHashrate(hps float64) string {
	units := []string{"H/s", "kH/s", "MH/s", "GH/s", "TH/s", "PH/s", "EH/s"}
	i := 0
	for hps >= 1000 && i < len(units)-1 {
		hps /= 1000
		i++
	}
	return fmt.Sprintf("%.2f %s", hps, units[i])
}