package maestro

// |@@| C

import (
	"context"
	"gardening/src/lib/contexter"
	erro "gardening/src/lib/error"
	formLib "gardening/src/lib/form"
	"gardening/src/lib/message"
	"gardening/src/lib/out_extra"
	"gardening/src/lib/presenter"
	"gardening/src/mdl"
	"strconv"
	"time"
)

type Maestro struct {
	Contexter *contexter.Contexter
}

type MaeIn interface{}

type MaeOut interface{}

type MaeAct func(context.Context, MaeIn) (MaeOut, error)

func (this *Maestro) AddSuccessMessage(extra *out_extra.OutExtra, title string) {
	msg := &message.Message{
		Title: title,
		Body:  "",
		Kind:  message.MessageSuccess,
	}
	extra.Messages = append(extra.Messages, msg)
}

func (this *Maestro) AddFailureMessage(extra *out_extra.OutExtra, title string) {
	msg := &message.Message{
		Title: title,
		Body:  "",
		Kind:  message.MessageFailure,
	}
	extra.Messages = append(extra.Messages, msg)
}

func (this *Maestro) EmptyFormBag() *formLib.FormBag {
	return &formLib.FormBag{}
}

func (this *Maestro) NewEvent(ctx context.Context) *mdl.Event {
	return &mdl.Event{
		Who:  this.Contexter.MayGetIdentityUid(ctx),
		When: time.Now(),
	}
}

func (this *Maestro) CastInt(number int) string {
	return strconv.Itoa(number)
}

func (this *Maestro) UpdateColumnsVisibility(columns []*presenter.Column, columns2 []presenter.Column) []*presenter.Column {
	m := make(map[string]*presenter.Column)
	for _, column := range columns {
		m[column.Key] = column
	}
	for _, column2 := range columns2 {
		column, has := m[column2.Key]
		if has {
			column.Hidden = column2.Hidden
		}
	}
	return columns
}

func Continue() (bool, error) {
	return true, nil
}

func (this *Maestro) Stop() (bool, error) {
	return false, nil
}

func Unauthorized() (bool, error) {
	err := erro.N("Not authorized")
	return false, err
}

func ActOnActs[T any, U any](ctx context.Context, in T, out U, acts []func(ctx context.Context, in T, out U) (bool, error)) (U, error) {
	for _, act := range acts {
		goon, err := act(ctx, in, out)
		if err != nil {
			return out, err
		}
		if !goon {
			break
		}
	}
	return out, nil
}
