package ingest

import (
	"context"

	"github.com/gin-gonic/gin"

	apiutils "github.com/tidbcloud/aisupport/packages/sdk-go/infra/apiserver/utils"
	"github.com/tidbcloud/aisupport/services/jsm-syncer/internal/services/eventprocessing"
	syncstatesvc "github.com/tidbcloud/aisupport/services/jsm-syncer/internal/services/syncstate"
)

func (h *Handler) HandleAccountEvent(c *gin.Context) {
	body, ok := fetchBody(c)
	if !ok {
		return
	}
	h.handleEvent(
		c,
		eventprocessing.AccountMetadata(eventprocessing.SourceInternalIngest, body),
		func(ctx context.Context) (syncstatesvc.RealtimeChanges, error) {
			return h.syncState.HandleAccountEvent(ctx, body)
		},
	)
}

func (h *Handler) HandleBillingEvent(c *gin.Context) {
	body, ok := fetchBody(c)
	if !ok {
		return
	}
	eventType := c.Param("event_type")
	h.handleEvent(
		c,
		eventprocessing.BillingMetadata(eventprocessing.SourceInternalIngest, eventType, body),
		func(ctx context.Context) (syncstatesvc.RealtimeChanges, error) {
			return h.syncState.HandleBillingEvent(ctx, eventType, body)
		},
	)
}

func (h *Handler) HandleMSPMessage(c *gin.Context) {
	body, ok := fetchBody(c)
	if !ok {
		return
	}
	h.handleEvent(
		c,
		eventprocessing.MSPMetadata(eventprocessing.SourceInternalIngest, body),
		func(ctx context.Context) (syncstatesvc.RealtimeChanges, error) {
			return h.syncState.HandleMSPMessage(ctx, body)
		},
	)
}

func (h *Handler) HandleLakeEvent(c *gin.Context) {
	body, ok := fetchBody(c)
	if !ok {
		return
	}
	h.handleEvent(
		c,
		eventprocessing.LakeMetadata(eventprocessing.SourceInternalIngest, body),
		func(ctx context.Context) (syncstatesvc.RealtimeChanges, error) {
			return h.syncState.HandleLakeEvent(ctx, body)
		},
	)
}

func (h *Handler) handleEvent(
	c *gin.Context,
	meta eventprocessing.Metadata,
	handleState func(context.Context) (syncstatesvc.RealtimeChanges, error),
) {
	if err := eventprocessing.Handle(c, meta, handleState, h.atlassianSync.ApplyRealtimeChanges); err != nil {
		apiutils.Fail(c, err)
		return
	}
	success(c)
}
