package integration

import (
	"context"
	"strconv"

	roomeventsv1 "hyapp.local/api/proto/events/room/v1"
	"hyapp/pkg/rocketmqx"
	"hyapp/pkg/roommq"
)

// RocketMQOutboxPublisher publishes durable room_outbox facts to a RocketMQ topic.
type RocketMQOutboxPublisher struct {
	producer *rocketmqx.Producer
	topic    string
}

// NewRocketMQOutboxPublisher creates a room_outbox fanout publisher.
func NewRocketMQOutboxPublisher(producer *rocketmqx.Producer, topic string) *RocketMQOutboxPublisher {
	return &RocketMQOutboxPublisher{producer: producer, topic: topic}
}

// PublishOutboxEvent implements OutboxPublisher.
func (p *RocketMQOutboxPublisher) PublishOutboxEvent(ctx context.Context, envelope *roomeventsv1.EventEnvelope) error {
	body, err := roommq.EncodeRoomOutboxMessage(envelope)
	if err != nil {
		return err
	}
	return p.producer.SendSync(ctx, rocketmqx.Message{
		Topic: p.topic,
		Tag:   roommq.TagRoomOutboxEvent,
		Keys:  []string{envelope.GetEventId(), envelope.GetRoomId()},
		Body:  body,
		Properties: map[string]string{
			"message_type":     roommq.MessageTypeRoomOutboxEvent,
			"app_code":         envelope.GetAppCode(),
			"room_id":          envelope.GetRoomId(),
			"event_id":         envelope.GetEventId(),
			"event_type":       envelope.GetEventType(),
			"room_version":     strconv.FormatInt(envelope.GetRoomVersion(), 10),
			"occurred_at_ms":   strconv.FormatInt(envelope.GetOccurredAtMs(), 10),
			"source_database":  "hyapp_room",
			"source_table":     "room_outbox",
			"delivery_version": "1",
		},
	})
}

// RocketMQRocketLaunchScheduler publishes exact-time rocket wakeup messages.
type RocketMQRocketLaunchScheduler struct {
	producer *rocketmqx.Producer
	topic    string
}

// NewRocketMQRocketLaunchScheduler creates the delayed launch scheduler.
func NewRocketMQRocketLaunchScheduler(producer *rocketmqx.Producer, topic string) *RocketMQRocketLaunchScheduler {
	return &RocketMQRocketLaunchScheduler{producer: producer, topic: topic}
}

// ScheduleRoomRocketLaunch implements RoomRocketLaunchScheduler.
func (s *RocketMQRocketLaunchScheduler) ScheduleRoomRocketLaunch(ctx context.Context, schedule RoomRocketLaunchSchedule) error {
	body, err := roommq.EncodeRoomRocketLaunchDueMessage(roommq.RoomRocketLaunchDueMessage{
		AppCode:    schedule.AppCode,
		RoomID:     schedule.RoomID,
		RocketID:   schedule.RocketID,
		Level:      schedule.Level,
		LaunchAtMS: schedule.LaunchAtMS,
		ResetAtMS:  schedule.ResetAtMS,
		CommandID:  schedule.CommandID,
	})
	if err != nil {
		return err
	}
	return s.producer.SendSync(ctx, rocketmqx.Message{
		Topic:        s.topic,
		Tag:          roommq.TagRoomRocketLaunchDue,
		Keys:         []string{schedule.RocketID, schedule.RoomID},
		Body:         body,
		DeliveryAtMS: schedule.LaunchAtMS,
		Properties: map[string]string{
			"message_type": roommq.MessageTypeRoomRocketLaunchDue,
			"app_code":     schedule.AppCode,
			"room_id":      schedule.RoomID,
			"rocket_id":    schedule.RocketID,
			"level":        strconv.FormatInt(int64(schedule.Level), 10),
			"launch_at_ms": strconv.FormatInt(schedule.LaunchAtMS, 10),
			"reset_at_ms":  strconv.FormatInt(schedule.ResetAtMS, 10),
		},
	})
}
