package ledger

import (
	"slices"
)

type Deltas []Delta

func (deltas Deltas) Group(group ...Group) Deltas {
	result := make(Deltas, 0, len(deltas))
	for i := range deltas {
		result = append(result, Groups(group).Each(deltas[i]))
	}
	return result
}

func (deltas Deltas) Like(like ...Like) Deltas {
	result := make(Deltas, 0, len(deltas))
	for i := range deltas {
		if Likes(like).All(deltas[i]) {
			result = append(result, deltas[i])
		}
	}
	return result
}

func (deltas Deltas) Register() Register {
	dateToBalances := make(Register)
	for _, delta := range deltas {
		if _, ok := dateToBalances[delta.Date]; !ok {
			dateToBalances[delta.Date] = make(Balances)
		}
		dateToBalances[delta.Date].Push(delta)
	}
	dates := make([]string, 0, len(dateToBalances)+1)
	for k := range dateToBalances {
		dates = append(dates, k)
	}
	slices.Sort(dates)
	for i := range dates {
		if i == 0 {
			continue
		}
		dateToBalances[dates[i]].PushAll(dateToBalances[dates[i-1]])
	}
	return dateToBalances
}

func (deltas Deltas) Balances() Balances {
	result := make(Balances)
	for _, delta := range deltas {
		if _, ok := result[delta.Name]; !ok {
			result[delta.Name] = make(Balance)
		}
		if _, ok := result[delta.Name][delta.Currency]; !ok {
			result[delta.Name][delta.Currency] = 0
		}
		result[delta.Name][delta.Currency] += delta.Value
		if result[delta.Name][delta.Currency] < 0.000000001 && result[delta.Name][delta.Currency] > -0.000000001 {
			result[delta.Name][delta.Currency] = 0
		}
	}
	return result
}
