package port

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

type PlayerWatermillConsumer struct {
	svc                    *app.PlayerService
	subscriber             message.Subscriber
	logger                 watermill.LoggerAdapter
	marshaler              watermillmsg.Marshaler
	eventServerSyncedTopic string
}

func NewPlayerWatermillConsumer(
	svc *app.PlayerService,
	subscriber message.Subscriber,
	logger watermill.LoggerAdapter,
	marshaler watermillmsg.Marshaler,
	eventServerSyncedTopic string,
) *PlayerWatermillConsumer {
	return &PlayerWatermillConsumer{
		svc:                    svc,
		subscriber:             subscriber,
		logger:                 logger,
		marshaler:              marshaler,
		eventServerSyncedTopic: eventServerSyncedTopic,
	}
}

func (c *PlayerWatermillConsumer) Register(router *message.Router) {
	router.AddNoPublisherHandler(
		"PlayerConsumer.sync",
		c.eventServerSyncedTopic,
		c.subscriber,
		c.sync,
	)
}

func (c *PlayerWatermillConsumer) sync(msg *message.Message) error {
	var rawPayload watermillmsg.ServerSyncedEventPayload

	if err := c.marshaler.Unmarshal(msg, &rawPayload); err != nil {
		c.logger.Error("couldn't unmarshal payload", err, watermill.LogFields{
			"handler": message.HandlerNameFromCtx(msg.Context()),
		})
		return nil
	}

	payload, err := domain.NewServerSyncedEventPayload(rawPayload.Key, rawPayload.URL, rawPayload.VersionCode)
	if err != nil {
		c.logger.Error("couldn't construct domain.ServerSyncedEventPayload", err, watermill.LogFields{
			"handler": message.HandlerNameFromCtx(msg.Context()),
		})
		return nil
	}

	return c.svc.Sync(msg.Context(), payload)
}
