package event_svc

import (
	"context"
	"strconv"
	"time"

	core_event "github.com/tidbcloud/core-svc/event"
	"github.com/tidbcloud/pkgv2/bizerr"
	"github.com/tidbcloud/pkgv2/db"
	"github.com/tidbcloud/serverless-service/internal/domain/entity"
	"github.com/tidbcloud/serverless-service/internal/domain/repo"
)

// VirtualizedBackupEventService maintains only data owned by the virtualized
// backup path. It never creates, updates, or deletes legacy schedules.
type VirtualizedBackupEventService struct {
	schedules repo.BackupScheduleRepo
	histories repo.BackupScheduleHistoryRepo
	db        db.TransProvider
}

func NewVirtualizedBackupEventService(
	schedules repo.BackupScheduleRepo,
	histories repo.BackupScheduleHistoryRepo,
	db db.TransProvider,
) *VirtualizedBackupEventService {
	return &VirtualizedBackupEventService{schedules: schedules, histories: histories, db: db}
}

func (s *VirtualizedBackupEventService) HandleClusterEvent(ctx context.Context, event *core_event.ClusterEvent) error {
	if event.EventType != core_event.ClusterEventTypeDeleted {
		return nil
	}
	clusterID := strconv.FormatUint(event.ClusterID, 10)
	deletedAt := time.Now().UTC()
	if event.EventCreatedAtMs > 0 {
		deletedAt = time.UnixMilli(event.EventCreatedAtMs).UTC()
	}
	return s.db.Transaction(ctx, func(ctx context.Context) error {
		// A failed virtualized pass may be retried after the legacy handler has
		// soft-deleted the schedule. Include it so the final schedule history can
		// still be archived.
		schedules, err := s.schedules.List(
			ctx,
			entity.ListBackupScheduleOptions{ClusterId: clusterID, IncludeDeleted: true},
		)
		if err != nil {
			return err
		}
		if len(schedules) > 1 {
			return bizerr.New(bizerr.ErrCodeUnknown, "multiple active backup schedules found")
		}
		if len(schedules) == 1 && !schedules[0].IsPending() {
			if err := s.histories.ArchiveCurrentSchedule(ctx, schedules[0], deletedAt, &deletedAt); err != nil {
				return err
			}
		}
		return s.histories.MarkDeleted(ctx, clusterID, deletedAt)
	})
}
