package state

import (
	"fmt"
	"reflect"
	"sync"

	"github.com/google/uuid"
)

type State struct {
	id      string
	data    sync.Map
}

func New() *State {
	return &State{
		id: uuid.NewString(),
	}
}

func (s *State) Symbols() map[string]map[string]reflect.Value {
	return map[string]map[string]reflect.Value{
		"git.bazzel.dev/bmallen/helios/state/state": {
			"Get":    reflect.ValueOf(s.Get),
			"Set":    reflect.ValueOf(s.Set),
			"Delete": reflect.ValueOf(s.Delete),
			"Range":  reflect.ValueOf(s.Range),
			"Keys":   reflect.ValueOf(s.Keys),
			"ID":     reflect.ValueOf(s.ID),
		},
	}
}

func (s *State) Get(key string) any {
	value, _ := s.data.Load(key)

	return value
}

func (s *State) Set(key string, value any) {
	s.data.Store(key, value)
}

func (s *State) Delete(key string) {
	s.data.Delete(key)
}

func (s *State) Range(f func(key string, value any) bool) {
	wf := func(key any, value any) bool {
		return f(fmt.Sprintf("%v", key), value)
	}

	s.data.Range(wf)
}

func (s *State) Keys() []string {
	keys := []string{}

	s.data.Range(func(key, value any) bool {
		keys = append(keys, fmt.Sprintf("%v", key))

		return true
	})

	return keys
}

func (s *State) ID() string {
	return s.id
}
