package adapter

import (
	"context"
	"fmt"

	"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
	"gitea.dwysokinski.me/twhelp/corev3/internal/watermill/watermillmsg"
	"github.com/ThreeDotsLabs/watermill/message"
)

type VillageWatermillPublisher struct {
	marshaler        watermillmsg.Marshaler
	publisher        message.Publisher
	eventSyncedTopic string
}

func NewVillageWatermillPublisher(
	publisher message.Publisher,
	marshaler watermillmsg.Marshaler,
	eventSyncedTopic string,
) *VillageWatermillPublisher {
	return &VillageWatermillPublisher{
		publisher:        publisher,
		marshaler:        marshaler,
		eventSyncedTopic: eventSyncedTopic,
	}
}

func (pub *VillageWatermillPublisher) EventSynced(
	ctx context.Context,
	payloads ...domain.VillagesSyncedEventPayload,
) error {
	msgs := make([]*message.Message, 0, len(payloads))

	for _, p := range payloads {
		msg, err := pub.marshaler.Marshal(ctx, watermillmsg.VillagesSyncedEventPayload{
			ServerKey:            p.ServerKey(),
			ServerURL:            p.ServerURL(),
			VersionCode:          p.VersionCode(),
			NumVillages:          p.NumVillages(),
			NumPlayerVillages:    p.NumPlayerVillages(),
			NumBarbarianVillages: p.NumBarbarianVillages(),
			NumBonusVillages:     p.NumBonusVillages(),
		})
		if err != nil {
			return fmt.Errorf("%s: couldn't marshal VillagesSyncedEventPayload: %w", p.ServerKey(), err)
		}

		msgs = append(msgs, msg)
	}

	if err := pub.publisher.Publish(pub.eventSyncedTopic, msgs...); err != nil {
		return fmt.Errorf("couldn't publish message to topic '%s': %w", pub.eventSyncedTopic, err)
	}

	return nil
}
