package adapterimpl

import (
	"context"
	"errors"
	"fmt"

	"github.com/tidbcloud/account/idl/pbgen/proto/account"

	globalserverlessv1 "github.com/tidbcloud/tidb-management-service/api/spec/global/serverless/v1"
	"github.com/tidbcloud/tidb-management-service/serverless-global-service/domain/adapter"
	"github.com/tidbcloud/tidb-management-service/serverless-global-service/infra/adapterimpl/cli"
)

type accountServiceImpl struct{}

func NewAccountService() adapter.AccountService {
	return &accountServiceImpl{}
}

func (a *accountServiceImpl) GetClusterInitialDelegateUsers(
	ctx context.Context,
	tenantID, projectID uint64,
	serverlessToken string,
) ([]*adapter.DelegateDBUserInfo, error) {
	resp, err := cli.GetDBUsers(ctx, &account.GetDBUsersReq{
		OrgId:           tenantID,
		ProjectId:       projectID,
		IsServerless:    true,
		ServerlessToken: serverlessToken,
	})
	if err != nil {
		return nil, err
	}

	out := make([]*adapter.DelegateDBUserInfo, 0, len(resp.DbUsers))
	for _, each := range resp.DbUsers {
		out = append(out, &adapter.DelegateDBUserInfo{
			TenantId:    each.OrgId,
			Username:    each.Username,
			Email:       each.Email,
			BuiltinRole: convertBuiltinRole(each.BuiltinRole),
		})
	}

	return out, nil
}

func (a *accountServiceImpl) IsHitFeatureFlag(ctx context.Context, tenantID uint64, flagName string) (bool, error) {
	return cli.IsHitFeatureFlag(ctx, &account.HitFeatureFlagReq{OrgId: tenantID, FlagName: flagName})
}

func convertBuiltinRole(role account.BuiltinRole) globalserverlessv1.SqlUser_BuiltinRole {
	switch role {
	case account.BuiltinRole_BUILTIN_ROLE_USER_ADMIN:
		return globalserverlessv1.SqlUser_BUILTIN_ROLE_USER_ADMIN
	case account.BuiltinRole_BUILTIN_ROLE_UNSPECIFIED:
		return globalserverlessv1.SqlUser_BUILTIN_ROLE_UNSPECIFIED
	default:
		panic(fmt.Sprintf("invalid role: %s", role))
	}
}

type fakeAccountImpl struct{}

func NewFakeAccountImpl() adapter.AccountService {
	return &fakeAccountImpl{}
}

func (a *fakeAccountImpl) GetClusterInitialDelegateUsers(
	ctx context.Context,
	tenantID, projectID uint64,
	serverlessToken string,
) ([]*adapter.DelegateDBUserInfo, error) {
	if tenantID == 0 {
		return nil, errors.New("tenant id is not empty")
	}
	if projectID == 0 {
		return nil, errors.New("project id is not empty")
	}
	if serverlessToken == "" {
		return nil, errors.New("serverlessToken id is not empty")
	}

	return []*adapter.DelegateDBUserInfo{
		{
			TenantId: tenantID,
			Id:       1,
			Username: "test",
			Email:    "test",
		},
	}, nil
}

func (a *fakeAccountImpl) IsHitFeatureFlag(ctx context.Context, tenantID uint64, flagName string) (bool, error) {
	if tenantID == 0 {
		return false, errors.New("tenant id is not empty")
	}
	if flagName == "" {
		return false, errors.New("flag name is not empty")
	}
	return false, nil
}
