package adminapigrpc

import (
	"bytes"
	"context"
	"dataservices/commons/constants"
	"dataservices/commons/ginparser"
	commonhttp "dataservices/commons/http"
	"dataservices/commons/pagetoken"
	adminapiv1beta1 "dataservices/idl/pbgen/proto/v1beta1"
	dto "dataservices/internal/dto/dataapi"
	"dataservices/internal/entity"
	"dataservices/internal/repository"
	service "dataservices/internal/service/central"
	"encoding/json"
	"fmt"
	"net/http"
	"sort"
	"strconv"
	"time"

	dto2 "dataservices/internal/dto/dataapi_gateway"
	"github.com/tidbcloud/account/idl/pbgen/proto/account"
	"github.com/tidbcloud/tiinf/errs"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
	"google.golang.org/protobuf/types/known/emptypb"
)

type DataAppService struct {
	adminapiv1beta1.UnimplementedDataAppsServiceServer
}

func (s *DataAppService) CreateDataApp(ctx context.Context, req *adminapiv1beta1.CreateDataAppRequest) (*adminapiv1beta1.DataApp, error) {
	_, createdBy, err := ginparser.GetCreatedByFromGrpc(ctx)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-CreateDataApp Invalid request public key", zap.Error(err), zap.String("user", createdBy))
		return nil, errs.NewBadRequest("Invalid request public key", err)
	}
	innerOrgId, err := ginparser.GetRequestInnerOrgIdGrpc(ctx)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-CreateDataApp Invalid orgId", zap.String("innerOrgId", innerOrgId), zap.Error(err), zap.String("user", createdBy))
		return nil, errs.NewBadRequest("get innerOrgId failed", err)
	}
	input := entity.CreateDataAppParam{
		AppName:       req.DataApp.DisplayName,
		ClusterIDStrs: req.DataApp.ClusterIds,
		Description:   req.DataApp.Description,
		AppVersion:    req.DataApp.Version,
	}
	if req.DataApp.AppType == adminapiv1beta1.DataApp_DATAAPP {
		input.AppType = entity.DataAppTypeDataapi
	} else if req.DataApp.AppType == adminapiv1beta1.DataApp_CHAT2QUERY {
		input.AppType = entity.DataAppTypeChat2Query
	} else {
		tilog.Error(ctx, "AdminAPI-CreateDataApp Invalid request data app", zap.Int("app_type", int(req.DataApp.AppType)),
			zap.Error(err), zap.String("user", createdBy))
		return nil, errs.NewBadRequest("Invalid data type", err)
	}

	for _, clusterIDStr := range req.DataApp.ClusterIds {
		clusterID, err := strconv.ParseUint(clusterIDStr, 10, 64)
		if err != nil || clusterID == 0 {
			tilog.Error(ctx, "AdminAPI-CreateDataApp Invalid params cluster_ids", zap.Error(err), zap.String("user", createdBy))
			return nil, errs.NewBadRequest("Invalid params cluster_ids", err)
		}
		input.ClusterIDs = append(input.ClusterIDs, clusterID)
	}
	orgId, err := strconv.ParseUint(innerOrgId, 10, 64)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-CreateDataApp Parse org_id failed", zap.String("org_id", innerOrgId), zap.Error(err), zap.String("user", createdBy))
		return nil, errs.NewBadRequest("Parse org_id failed", err)
	}
	projectId, err := strconv.ParseUint(req.DataApp.ProjectId, 10, 64)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-CreateDataApp Parse project_id failed", zap.String("project_id", req.DataApp.ProjectId), zap.Error(err), zap.String("user", createdBy))
		return nil, errs.NewBadRequest("Parse project_id failed", err)
	}
	tilog.Info(ctx, "AdminAPI-CreateDataApp Payload", zap.Uint64("orgId", orgId), zap.Uint64("projectId", projectId), zap.Any("input", input), zap.Any("req", req), zap.String("user", createdBy))
	dataAPP, _, err := service.CreateDataApp(ctx, orgId, projectId, createdBy, &input)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-CreateDataApp failed", zap.String("org_id", innerOrgId), zap.String("project_id", req.DataApp.ProjectId), zap.Error(err), zap.String("user", createdBy))
		return nil, err
	}
	res := adminapiv1beta1.DataApp{
		DataAppId:   dataAPP.ExternalAppID,
		Name:        fmt.Sprintf("dataApps/%s", dataAPP.ExternalAppID),
		Version:     dataAPP.AppVersion,
		ProjectId:   req.DataApp.ProjectId,
		ClusterIds:  req.DataApp.ClusterIds,
		AppType:     req.DataApp.AppType,
		DisplayName: dataAPP.AppName,
		Description: dataAPP.Description,
		CreatedAt:   dataAPP.CreatedAt.Format(time.RFC3339),
		UpdatedAt:   dataAPP.UpdatedAt.Format(time.RFC3339),
	}
	tilog.Info(ctx, "AdminAPI-CreateDataApp Response", zap.Any("res", res), zap.String("user", createdBy))
	return &res, nil
}

func (s *DataAppService) ListDataApps(ctx context.Context, req *adminapiv1beta1.ListDataAppsRequest) (*adminapiv1beta1.ListDataAppsResponse, error) {
	_, createdBy, err := ginparser.GetCreatedByFromGrpc(ctx)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-ListDataApps Invalid request public key", zap.Error(err), zap.String("user", createdBy))
		return nil, errs.NewBadRequest("Invalid request public key", err)
	}
	projectId, err := strconv.ParseUint(req.ProjectId, 10, 64)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-ListDataApps Parse project_id failed", zap.String("project_id", req.ProjectId), zap.Error(err), zap.String("user", createdBy))
		return nil, errs.NewBadRequest("Parse project_id failed", err)
	}
	token := pagetoken.PageToken[uint64]{}
	if req.PageToken != "" {
		if err := token.DecodeFromString(req.PageToken); err != nil {
			return nil, errs.NewBadRequest("invalid page token", err)
		}
	}

	pageSize := req.PageSize
	if req.PageSize == 0 {
		pageSize = constants.AdminApiDefaultPageSize
	} else if req.PageSize < 0 || req.PageSize > constants.AdminApiDefaultPageSize {
		return nil, errs.NewBadRequest(fmt.Sprintf("invalid page size, the effective range is: [0,%d]", constants.AdminApiDefaultPageSize), nil)
	}

	tilog.Info(ctx, "AdminAPI-ListDataApps Payload", zap.Uint64("projectId", projectId), zap.Any("req", req), zap.String("user", createdBy))
	var appTypeList []string
	res, err := service.ListDataApps(ctx, projectId, appTypeList...)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-ListDataApps failed!", zap.String("project_id", req.ProjectId), zap.Error(err), zap.String("user", createdBy))
		return nil, err
	}
	sort.Slice(res, func(i, j int) bool {
		return res[i].ID < res[j].ID
	})
	count := 0
	total := len(res)
	nextToken := pagetoken.PageToken[uint64]{}
	dataApps := make([]*adminapiv1beta1.DataApp, 0, req.PageSize)
	for i, dataapp := range res {
		keyId := dataapp.ID
		if keyId > token.Prev {
			app, err := dataappEntity2GrpcEntity(ctx, dataapp)
			if err != nil {
				tilog.Error(ctx, "AdminAPI-ListDataApps Parse app info failed!", zap.Error(err), zap.String("user", createdBy))
				return nil, err
			}
			dataApps = append(dataApps, app)
			count++
			if count >= int(pageSize) && i < total-1 {
				nextToken.Prev = keyId
				break
			}
		}
	}
	resp := adminapiv1beta1.ListDataAppsResponse{
		DataApps: dataApps,
	}
	if nextToken.Prev > 0 {
		nextPageToken, err := nextToken.EncodeToString()
		if err != nil {
			tilog.Info(ctx, "next page token encode failed", zap.Error(err))
		} else {
			resp.NextPageToken = nextPageToken
		}
	}
	tilog.Info(ctx, "AdminAPI-ListDataApps Response", zap.Any("res", resp), zap.String("user", createdBy))
	return &resp, nil
}
func (s *DataAppService) GetDataApp(ctx context.Context, req *adminapiv1beta1.GetDataAppRequest) (*adminapiv1beta1.DataApp, error) {
	params := ginparser.ParseAdminApiPathParameters(ctx, req.Name)
	innerAppId, err := ginparser.GetRequestInnerAppIdGrpc(ctx)
	if err != nil {
		return nil, errs.NewBadRequest("invalid innerAppId", err)
	}
	_, createdBy, err := ginparser.GetCreatedByFromGrpc(ctx)
	if err != nil {
		return nil, errs.NewBadRequest("invalid request public key", err)
	}
	tilog.Info(ctx, "AdminAPI-GetDataApp Payload", zap.Uint64("app_id", innerAppId), zap.String("external_app_id", params.ExternalAppId), zap.Any("req", req), zap.String("user", createdBy))
	res, err := service.GetDataApp(ctx, innerAppId)
	if res.AppVersion == "" {
		res.AppVersion = "1.0.0"
	}
	if err != nil {
		tilog.Error(ctx, "AdminAPI-GetDataApp failed!", zap.Error(err), zap.String("user", createdBy))
		return nil, err
	}

	app, err := dataappEntity2GrpcEntity(ctx, res)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-GetDataApp Parse app info failed!", zap.Error(err), zap.String("user", createdBy))
		return nil, err
	}
	tilog.Info(ctx, "AdminAPI-GetDataApp Response", zap.Any("res", app), zap.String("user", createdBy))
	return app, nil
}

func (s *DataAppService) UpdateDataApp(ctx context.Context, req *adminapiv1beta1.UpdateDataAppRequest) (*adminapiv1beta1.DataApp, error) {
	params := ginparser.ParseAdminApiPathParameters(ctx, req.DataApp.Name)
	innerAppId, err := ginparser.GetRequestInnerAppIdGrpc(ctx)
	if err != nil {
		return nil, errs.NewBadRequest("invalid innerAppId", err)
	}
	_, createdBy, err := ginparser.GetCreatedByFromGrpc(ctx)
	if err != nil {
		return nil, errs.NewBadRequest("invalid request public key", err)
	}
	tilog.Info(ctx, "AdminAPI-UpdateDataApp Payload", zap.Uint64("app_id", innerAppId), zap.String("external_app_id", params.ExternalAppId), zap.Any("req", req), zap.String("user", createdBy))
	err = service.UpdateDataApp(ctx, innerAppId, &entity.UpdateDataAppParam{
		AppName:     req.DataApp.DisplayName,
		Description: req.DataApp.Description,
		AppVersion:  req.DataApp.Version,
	}, createdBy)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-UpdateDataApp failed!", zap.Error(err), zap.String("user", createdBy))
		return nil, err
	}

	res, err := service.GetDataApp(ctx, innerAppId)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-UpdateDataApp Get DataApp info failed!", zap.Error(err), zap.String("user", createdBy))
		return nil, err
	}

	app, err := dataappEntity2GrpcEntity(ctx, res)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-UpdateDataApp Parse app info failed!", zap.Error(err), zap.String("user", createdBy))
		return nil, err
	}
	tilog.Info(ctx, "AdminAPI-UpdateDataApp Response", zap.Any("res", app), zap.String("user", createdBy))
	return app, nil
}

func (s *DataAppService) DeleteDataApp(ctx context.Context, req *adminapiv1beta1.DeleteDataAppRequest) (*emptypb.Empty, error) {
	params := ginparser.ParseAdminApiPathParameters(ctx, req.Name)
	innerAppId, err := ginparser.GetRequestInnerAppIdGrpc(ctx)
	if err != nil {
		return nil, errs.NewBadRequest("invalid innerAppId", err)
	}
	_, createdBy, err := ginparser.GetCreatedByFromGrpc(ctx)
	if err != nil {
		return nil, errs.NewBadRequest("invalid request public key", err)
	}
	tilog.Info(ctx, "AdminAPI-DeleteDataApp Payload", zap.Uint64("app_id", innerAppId), zap.String("external_app_id", params.ExternalAppId), zap.Any("req", req), zap.String("user", createdBy))
	err = service.DeleteDataApp(ctx, innerAppId, createdBy, account.OperatorType_OPERATOR_TYPE_APIKEY)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-DeleteDataApp failed!", zap.Error(err), zap.String("user", createdBy))
		return nil, err
	}
	tilog.Info(ctx, "AdminAPI-DeleteDataApp Response: success", zap.String("user", createdBy))
	return &emptypb.Empty{}, nil
}

func dataappEntity2GrpcEntity(ctx context.Context, app *entity.DataApp) (*adminapiv1beta1.DataApp, error) {
	appType := adminapiv1beta1.DataApp_DATAAPP
	if app.AppType == entity.DataAppTypeChat2Query {
		appType = adminapiv1beta1.DataApp_CHAT2QUERY
	}
	dataappClusters, err := repository.ListAppClusterByAppId(ctx, app.ID)
	if err != nil {
		return nil, errs.NewInternalDB("list app clusters failed", err)
	}
	clusterIds := make([]string, 0)
	for _, cluster := range dataappClusters {
		clusterIds = append(clusterIds, strconv.FormatUint(cluster.ClusterID, 10))
	}
	return &adminapiv1beta1.DataApp{
		DataAppId:   app.ExternalAppID,
		Name:        fmt.Sprintf("dataApps/%s", app.ExternalAppID),
		Version:     app.AppVersion,
		ProjectId:   strconv.FormatUint(app.ProjectId, 10),
		ClusterIds:  clusterIds,
		AppType:     appType,
		DisplayName: app.AppName,
		Description: app.Description,
		CreatedAt:   app.CreatedAt.Format(time.RFC3339),
		UpdatedAt:   app.UpdatedAt.Format(time.RFC3339),
	}, nil
}

type Chat2QuerySettingsResp struct {
	Code   int                                `json:"code"`
	Msg    string                             `json:"msg"`
	Result adminapiv1beta1.Chat2QuerySettings `json:"result"`
}

func (s *DataAppService) GetChat2QuerySettings(ctx context.Context, req *adminapiv1beta1.GetChat2QuerySettingsRequest) (*adminapiv1beta1.Chat2QuerySettings, error) {
	params := ginparser.ParseAdminApiPathParameters(ctx, req.Name)
	innerAppId, err := ginparser.GetRequestInnerAppIdGrpc(ctx)
	if err != nil {
		return nil, errs.NewBadRequest("invalid innerAppId", err)
	}
	_, createdBy, err := ginparser.GetCreatedByFromGrpc(ctx)
	if err != nil {
		return nil, errs.NewBadRequest("invalid request public key", err)
	}
	tilog.Info(ctx, "AdminAPI-GetChat2QuerySettings Payload", zap.Uint64("app_id", innerAppId), zap.String("external_app_id", params.ExternalAppId), zap.Any("req", req), zap.String("user", createdBy))
	appInfo, err := service.GetDataApp(ctx, innerAppId)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-GetChat2QuerySettings Get DataApp info failed!", zap.Error(err), zap.String("user", createdBy))
		return nil, err
	}

	// edaservice.inner is just a placeholder, ProxyToEDAService will not use it
	fullUrl := fmt.Sprintf("http://edaservice.inner/api/v1/dataservices/central/orgs/%d/projects/%d/apps/%s/chat2query/settings", appInfo.OrgId, appInfo.ProjectId, appInfo.ExternalAppID)
	httpReq, err := http.NewRequest(http.MethodGet, fullUrl, bytes.NewReader(nil))
	if err != nil {
		return nil, errs.NewInternalHTTP("create http request failed", err)
	}

	respStr, statusCode, err := commonhttp.ProxyToEDAService(ctx, appInfo, httpReq, http.MethodGet, time.Second*60)
	if err != nil {
		return nil, errs.NewInternalHTTP("request to eda service failed", err)
	}

	if statusCode >= http.StatusInternalServerError {
		tilog.Info(ctx, "AdminAPI-GetChat2QuerySettings failed", zap.String("respStr", respStr), zap.Int("statusCode", statusCode))
		return nil, errs.NewInternalHTTP("request to eda service failed", fmt.Errorf("status code is %d", statusCode))
	}

	var chat2querySettingsResp Chat2QuerySettingsResp
	if err := json.Unmarshal([]byte(respStr), &chat2querySettingsResp); err != nil {
		return nil, errs.NewInternalHTTP("unmarshal response failed", err)
	}

	if chat2querySettingsResp.Code >= http.StatusBadRequest {
		tilog.Info(ctx, "AdminAPI-GetChat2QuerySettings failed", zap.String("respStr", respStr), zap.Int("statusCode", statusCode))
		return nil, errs.NewBadRequest(chat2querySettingsResp.Msg, nil)
	}

	chat2querySettingsResp.Result.Name = fmt.Sprintf("dataApps/%s/chat2QuerySettings", appInfo.ExternalAppID)
	return &chat2querySettingsResp.Result, nil
}

func (s *DataAppService) UpdateChat2QuerySettings(ctx context.Context, req *adminapiv1beta1.UpdateChat2QuerySettingsRequest) (*adminapiv1beta1.Chat2QuerySettings, error) {
	params := ginparser.ParseAdminApiPathParameters(ctx, req.Chat2QuerySettings.Name)
	innerAppId, err := ginparser.GetRequestInnerAppIdGrpc(ctx)
	if err != nil {
		return nil, errs.NewBadRequest("invalid innerAppId", err)
	}
	_, createdBy, err := ginparser.GetCreatedByFromGrpc(ctx)
	if err != nil {
		return nil, errs.NewBadRequest("invalid request public key", err)
	}
	tilog.Info(ctx, "AdminAPI-UpdateChat2QuerySettings Payload", zap.Uint64("app_id", innerAppId), zap.String("external_app_id", params.ExternalAppId), zap.Any("req", req), zap.String("user", createdBy))
	appInfo, err := service.GetDataApp(ctx, innerAppId)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-UpdateChat2QuerySettings Get DataApp info failed!", zap.Error(err), zap.String("user", createdBy))
		return nil, err
	}

	// edaservice.inner is just a placeholder, ProxyToEDAService will not use it
	fullUrl := fmt.Sprintf("http://edaservice.inner/api/v1/dataservices/central/orgs/%d/projects/%d/apps/%s/chat2query/settings", appInfo.OrgId, appInfo.ProjectId, appInfo.ExternalAppID)
	payload := map[string]string{
		"llm_api_key":   req.Chat2QuerySettings.LlmApiKey,
		"llm_model":     req.Chat2QuerySettings.LlmModel,
		"language_code": req.Chat2QuerySettings.LanguageCode,
	}
	payloadBytes, err := json.Marshal(payload)
	if err != nil {
		return nil, errs.NewInternalHTTP("marshal payload failed", err)
	}
	httpReq, err := http.NewRequest(http.MethodPut, fullUrl, bytes.NewReader(payloadBytes))
	if err != nil {
		return nil, errs.NewInternalHTTP("create http request failed", err)
	}

	respStr, statusCode, err := commonhttp.ProxyToEDAService(ctx, appInfo, httpReq, http.MethodPut, time.Second*60)
	if err != nil {
		return nil, errs.NewInternalHTTP("request to eda service failed", err)
	}

	if statusCode >= http.StatusInternalServerError {
		tilog.Info(ctx, "AdminAPI-UpdateChat2QuerySettings failed", zap.String("respStr", respStr), zap.Int("statusCode", statusCode))
		return nil, errs.NewInternalHTTP("request to eda service failed", fmt.Errorf("status code is %d", statusCode))
	}

	var chat2querySettingsResp Chat2QuerySettingsResp
	if err := json.Unmarshal([]byte(respStr), &chat2querySettingsResp); err != nil {
		return nil, errs.NewInternalHTTP("unmarshal response failed", err)
	}

	if chat2querySettingsResp.Code >= http.StatusBadRequest {
		tilog.Info(ctx, "AdminAPI-UpdateChat2QuerySettings failed", zap.String("respStr", respStr), zap.Int("statusCode", statusCode))
		return nil, errs.NewBadRequest(chat2querySettingsResp.Msg, nil)
	}

	chat2querySettingsResp.Result.Name = fmt.Sprintf("dataApps/%s/chat2QuerySettings", appInfo.ExternalAppID)
	return &chat2querySettingsResp.Result, nil
}

func (s *DataAppService) UpdateSystemEndpointConfig(ctx context.Context, req *adminapiv1beta1.UpdateSystemEndpointConfigRequest) (*adminapiv1beta1.SystemEndpointConfig, error) {
	innerAppId, err := ginparser.GetRequestInnerAppIdGrpc(ctx)
	if err != nil {
		return nil, errs.NewBadRequest("invalid innerAppId", err)
	}
	_type, createdBy, err := ginparser.GetCreatedByFromGrpc(ctx)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-UpdateSystemEndpointConfig Invalid request public key", zap.Error(err), zap.String("user", createdBy))
		return nil, errs.NewBadRequest("Invalid request public key", err)
	}
	res, err := service.GetDataApp(ctx, innerAppId)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-UpdateDataApp Get DataApp info failed!", zap.Error(err), zap.String("user", createdBy))
		return nil, err
	}

	credential := dto2.Credential{
		Type: _type.String(),
		Key:  createdBy,
	}
	systemEndpointConfigData := &dto.SystemEndpointConfigData{
		DataEndpoints: []*dto.EndpointConfig{},
	}
	for _, i := range req.SystemEndpointConfig.Items {
		systemEndpointConfigData.DataEndpoints = append(systemEndpointConfigData.DataEndpoints, &dto.EndpointConfig{
			Type:      i.Type,
			Key:       i.Key,
			IsEnabled: i.Enabled,
		})
	}

	err = repository.Transaction(ctx, func(ctx context.Context) error {
		err = service.SaveSystemEndpointConfig(ctx, res.ProjectId, res.ID, systemEndpointConfigData, createdBy, credential)
		if err != nil {
			return err
		}

		systemEndpointConfigData, err = service.GetSystemEndpointConfig(ctx, res.ID)
		if err != nil {
			return err
		}

		return nil
	})
	if err != nil {
		tilog.Error(ctx, "AdminAPI-SaveSystemEndpointConfig failed", zap.Error(err), zap.String("user", createdBy))
		return nil, err
	}

	tilog.Info(ctx, "AdminAPI-SaveSystemEndpointConfig Response", zap.Any("res", systemEndpointConfigData), zap.String("user", createdBy))

	result := adminapiv1beta1.SystemEndpointConfig{}
	for _, i := range systemEndpointConfigData.DataEndpoints {
		result.Items = append(result.Items, &adminapiv1beta1.SystemEndpointConfigItem{
			Type:    i.Type,
			Key:     i.Key,
			Enabled: i.IsEnabled,
		})
	}
	result.Name = fmt.Sprintf("dataApps/%s/systemEndpointConfig", res.ExternalAppID)

	return &result, nil
}

func (s *DataAppService) GetSystemEndpointConfig(ctx context.Context, req *adminapiv1beta1.GetSystemEndpointConfigRequest) (*adminapiv1beta1.SystemEndpointConfig, error) {
	innerAppId, err := ginparser.GetRequestInnerAppIdGrpc(ctx)
	if err != nil {
		return nil, errs.NewBadRequest("invalid innerAppId", err)
	}
	_, createdBy, err := ginparser.GetCreatedByFromGrpc(ctx)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-GetSystemEndpointConfig Invalid request public key", zap.Error(err), zap.String("user", createdBy))
		return nil, errs.NewBadRequest("Invalid request public key", err)
	}
	res, err := service.GetDataApp(ctx, innerAppId)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-GetSystemEndpointConfig Get DataApp info failed!", zap.Error(err), zap.String("user", createdBy))
		return nil, err
	}

	systemEndpointConfigData, err := service.GetSystemEndpointConfig(ctx, res.ID)
	if err != nil {
		tilog.Error(ctx, "AdminAPI-GetSystemEndpointConfig failed", zap.Error(err), zap.String("user", createdBy))
		return nil, err
	}

	tilog.Info(ctx, "AdminAPI-GetSystemEndpointConfig Response", zap.Any("res", systemEndpointConfigData), zap.String("user", createdBy))

	result := adminapiv1beta1.SystemEndpointConfig{}
	for _, i := range systemEndpointConfigData.DataEndpoints {
		result.Items = append(result.Items, &adminapiv1beta1.SystemEndpointConfigItem{
			Type:    i.Type,
			Key:     i.Key,
			Enabled: i.IsEnabled,
		})
	}
	result.Name = fmt.Sprintf("dataApps/%s/systemEndpointConfig", res.ExternalAppID)

	return &result, nil
}
