package integration

import (
	"context"
	"fmt"

	"github.com/pingcap/errcode"
	consolev1 "github.com/tidbcloud/metrics-integration/global/api/integration/v1"
	controller "github.com/tidbcloud/metrics-integration/global/internal/domain/controller/integration"
	"github.com/tidbcloud/metrics-integration/global/internal/domain/entity"
	"github.com/tidbcloud/metrics-integration/global/internal/infrastructure/account"
	"github.com/tidbcloud/metrics-integration/global/internal/infrastructure/config"
	"github.com/tidbcloud/metrics-integration/global/internal/infrastructure/di"
	"github.com/tidbcloud/metrics-integration/global/pkg/helm/pipeline"
	"google.golang.org/protobuf/types/known/emptypb"
	"google.golang.org/protobuf/types/known/timestamppb"
	"gorm.io/gorm"
)

func (i *integrationServiceServer) CreateMetricsKey(ctx context.Context, req *consolev1.CreateMetricsKeyRequest) (resp *consolev1.CreateMetricsKeyResp, err error) {
	user := account.GetUserFromContext(ctx)
	clusterID := entity.ID(req.ClusterId)

	metricsKey, queryEndpoint, err := controller.CreateMetricsKey(ctx, clusterID, user.Email)
	if err != nil {
		return nil, err
	}

	return &consolev1.CreateMetricsKeyResp{
		Key: &consolev1.MetricsKey{
			KeyId:     uint64(metricsKey.ID),
			Key:       metricsKey.KeyHash,
			CreatedAt: timestamppb.New(metricsKey.CreatedAt),
		},
		QueryEndpoint: queryEndpoint,
	}, nil
}

func (i *integrationServiceServer) GetAllMetricsKey(ctx context.Context, req *consolev1.GetAllMetricsKeyRequest) (resp *consolev1.GetAllMetricsKeyResp, err error) {
	clusterID := entity.ID(req.ClusterId)

	metricsKeys := make([]*entity.MetricsKey, 0)
	var queryEndpoint string

	if err := di.DiCall(func(db *gorm.DB) error {
		return db.Where("cluster_id = ?", clusterID).Find(&metricsKeys).Error
	}); err != nil {
		return nil, errcode.NewInternalErr(fmt.Errorf("failed to get metrics keys: %w", err))
	}

	cluster, err := pipeline.GetTargetClusterByClusterID(uint64(clusterID))
	if err != nil {
		return nil, errcode.NewInternalErr(fmt.Errorf("failed to get cluster info: %w", err))
	}
	queryEndpoint = config.Global().RegionalExecutorConfig.GetPrometheusQueryEndpoint(cluster.CloudProviderName, cluster.RegionName)

	resp = &consolev1.GetAllMetricsKeyResp{
		QueryEndpoint: queryEndpoint,
	}

	for _, metricsKey := range metricsKeys {
		resp.MetricsKeys = append(resp.MetricsKeys, &consolev1.MetricsKey{
			KeyId:     uint64(metricsKey.ID),
			Key:       metricsKey.KeyHash,
			CreatedAt: timestamppb.New(metricsKey.CreatedAt),
		})
	}

	return resp, nil
}

func (s *integrationServiceServer) DeleteMetricsKey(ctx context.Context, req *consolev1.DeleteMetricsKeyRequest) (resp *emptypb.Empty, err error) {
	if err := controller.DeleteMetricsKey(ctx, req.KeyId); err != nil {
		return nil, err
	}

	return &emptypb.Empty{}, nil
}
