package export

import (
	"context"
	"strconv"

	eventdata "github.com/tidbcloud/eventbus-datastruct/event"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"

	globalngv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/nextgen/v1"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/domain/service/displayevent"
	"github.com/tidbcloud/tidb-management-service/nextgen-global-service/infra/repoimpl/schema"
	"github.com/tidbcloud/tidb-management-service/utilities/bizerr"
)

func (s *serviceImpl) DeleteExport(ctx context.Context, req *globalngv1.DeleteExportRequest) (*globalngv1.Export, bizerr.BizError) {
	if req == nil || req.GetClusterId() == "" || req.GetExportId() == "" {
		return nil, bizerr.New(bizerr.ErrCodeParams, "cluster_id and export_id are required")
	}

	tilog.Info(ctx, "delete export request", zap.String("cluster_id", req.GetClusterId()), zap.String("export_id", req.GetExportId()))

	ent, err := s.exportRepo.GetByClusterAndExportId(ctx, req.GetClusterId(), req.GetExportId())
	if err != nil {
		tilog.Error(ctx, "failed to get export", zap.Error(err))
		return nil, err
	}

	if ent.State == schema.ExportStateRunning {
		return nil, bizerr.New(bizerr.ErrCodeParams, "export is in running state, please cancel it first")
	}
	clusterID, parseErr := strconv.ParseUint(req.GetClusterId(), 10, 64)
	if parseErr != nil || clusterID == 0 {
		return nil, bizerr.New(bizerr.ErrCodeParams, "invalid cluster_id")
	}
	if lifecycleErr := s.checkResourcePoolLifecycle(ctx, clusterID, false); lifecycleErr != nil {
		return nil, lifecycleErr
	}

	transactionErr := s.transaction.Transaction(ctx, func(ctx context.Context) error {
		if lifecycleErr := s.checkResourcePoolLifecycle(ctx, clusterID, true); lifecycleErr != nil {
			return lifecycleErr
		}
		ent.State = schema.ExportStateDeleted
		if err := s.exportRepo.Delete(ctx, req.GetClusterId(), req.GetExportId()); err != nil {
			tilog.Error(ctx, "failed to delete export", zap.Error(err))
			return err
		}
		return nil
	})
	if transactionErr != nil {
		return nil, bizerr.WrapError(transactionErr, "failed to delete export")
	}

	displayEv := newExportDisplayEvent(ctx, ent, displayevent.DeleteExport, eventdata.EventStatusSucceeded, "Export deleted successfully.")
	displayevent.Write(ctx, s.eventCommitter, displayEv)

	return schemaToProto(ent.Export), nil
}
