package dataflow

import (
	"context"
	"fmt"
	"sync"

	"github.com/tidbcloud/account/commons/config"
	"github.com/tidbcloud/dataflow-service/idl/pbgen/proto/dataflow"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	tigrpc "github.com/tidbcloud/tiinf/transport/tigrpc/client"
	"go.uber.org/zap"
)

var (
	backupCli         dataflow.BackupInternalServiceClient
	importInternalCli dataflow.ImportInnerServiceClient
	backupSvcOnce     sync.Once
	importSvcOnce     sync.Once
)

type DataflowHandlerImpl struct{}

func GetBackupSvcClient() dataflow.BackupInternalServiceClient {
	backupSvcOnce.Do(func() {
		ctx := context.Background()
		addr := config.Global().GrpcConfig.DataflowSvcAddr
		conn, err := tigrpc.NewClientConn(addr, tigrpc.WithDefault())
		tilog.Info(ctx, "init dataflow backup service client", zap.Any("err", err), zap.String("addr", addr))
		if err != nil {
			panic(fmt.Sprintf("dial backup-svc: %s", err))
		}

		backupCli = dataflow.NewBackupInternalServiceClient(conn)

	})
	return backupCli
}

func GetImportInternalServiceClient() dataflow.ImportInnerServiceClient {
	importSvcOnce.Do(func() {
		ctx := context.Background()
		addr := config.Global().GrpcConfig.DataflowSvcAddr //dataflow-grpc:10000
		//addr := "dataflow-service:f95d4ebb05e8665b1cc81ccbbe6a1d4063877198:4444"
		conn, err := tigrpc.NewClientConn(addr, tigrpc.WithDefault())
		tilog.Info(ctx, "init dataflow importService  client", zap.Any("err", err), zap.String("addr", addr))
		if err != nil {
			panic(fmt.Sprintf("dial importService  client: %s", err))
		}

		importInternalCli = dataflow.NewImportInnerServiceClient(conn)

	})
	return importInternalCli
}

func (*DataflowHandlerImpl) DeleteDeletedClusterBackups(ctx context.Context, tenantID, projectID, clusterID uint64) error {
	client := GetBackupSvcClient()
	req := &dataflow.ClusterIdReq{
		OrgId:     tenantID,
		ProjectId: projectID,
		ClusterId: clusterID,
	}
	logger := tilog.WithContextL(ctx)

	resp, err := client.DeleteDeletedClusterBackups(ctx, req)
	logger.Info("delete deleted cluster's backups", zap.Any("resp", resp), zap.Any("err", err), zap.Any("req", req))
	if err != nil {
		return err
	}

	return nil
}

func (*DataflowHandlerImpl) DeleteAllManualBackups(ctx context.Context, tenantID uint64) error {
	client := GetBackupSvcClient()
	req := &dataflow.DeleteAllManualBackupsReq{
		OrgId: tenantID,
	}
	logger := tilog.WithContextL(ctx)

	resp, err := client.DeleteAllManualBackups(ctx, req)
	logger.Info("delete all manual backups", zap.Any("resp", resp), zap.Any("err", err), zap.Any("req", req))
	if err != nil {
		return err
	}
	return nil
}

func (*DataflowHandlerImpl) DeleteAllBackups(ctx context.Context, tenantID uint64) error {
	client := GetBackupSvcClient()
	req := &dataflow.DeleteAllBackupsReq{
		BackupType: dataflow.BackupType_ALL,
		OrgId:      tenantID,
	}
	logger := tilog.WithContextL(ctx)

	resp, err := client.DeleteAllBackups(ctx, req)
	logger.Info("delete all backups", zap.Any("resp", resp), zap.Any("err", err), zap.Any("req", req))
	if err != nil {
		return err
	}
	return nil
}

/*
func (*DataflowHandlerImpl) QueryBackups(ctx context.Context, tenantID uint64) error {
	client := GetBackupSvcClient()
	req := &dataflow.DeleteAllBackupsReq{
		BackupType: dataflow.BackupType_ALL,
		OrgId:      tenantID,
	}
	logger := tilog.WithContextL(ctx)

	resp, err := client.(ctx, req)
	logger.Info("delete all backups", zap.Any("resp", resp), zap.Any("err", err), zap.Any("req", req))
	if err != nil {
		return err
	}
	return nil
}
*/
