package apikey

import (
	"context"

	"github.com/tidbcloud/account/internel/dao/dbuser"
	"github.com/tidbcloud/account/internel/dao/entity"
	"github.com/tidbcloud/account/thirdparty/dataapi"
	dataapipb "github.com/tidbcloud/dataservices/idl/pbgen/proto/dataapi"
	"gorm.io/gorm"
)

func CreateDBUser(ctx context.Context, dbUser dbuser.DBUserDaoIface, tx *gorm.DB, keyEntity *entity.ApiKey, scopeType entity.ScopeType, resourceID uint64, operatorID uint64, operatorType int32) error {
	// dataapp create db user when receive dataapp's kafka msg
	if scopeType == entity.RoleBindingScopeDataAPP {
		return nil
	}
	var operType = entity.RoleBindingTargetUser
	if operatorType == entity.OperatorTypeApiKey {
		operType = entity.RoleBindingTargetAPIKey
	}
	orgID, projectID, err := convertResource(ctx, scopeType, resourceID)
	if err != nil {
		return err
	}
	return dbUser.CreateCommandUserAction(ctx, tx,
		operatorID, keyEntity.ID.Uint64(), keyEntity.AccessKey, orgID, projectID, entity.CommandStatusWaiting, entity.CommandActionCreate, entity.RoleBindingTargetAPIKey, operType)
}

func convertResource(ctx context.Context, scopeType entity.ScopeType, resourceID uint64) (orgID, projectID uint64, err error) {
	if scopeType == entity.RoleBindingScopeOrg {
		orgID = resourceID
	} else if scopeType == entity.RoleBindingScopeProject {
		projectID = resourceID
	} else {
		req := &dataapipb.ShowDataAppReq{
			AppId: resourceID,
		}
		app, err := dataapi.ShowDataApp(ctx, req)
		if err != nil {
			return orgID, projectID, err
		}
		orgID = app.AppInfo.OrgId
		projectID = app.AppInfo.ProjectId
	}
	return orgID, projectID, nil
}

func DeleteDBUser(ctx context.Context, dbUser dbuser.DBUserDaoIface, tx *gorm.DB, keyEntity *entity.ApiKey, scopeType entity.ScopeType, resourceID uint64, operatorID uint64, operatorType int32) error {
	// 	// dataapp delete db user when receive dataapp's kafka msg
	if scopeType == entity.RoleBindingScopeDataAPP || scopeType == entity.RoleBindingScopeTiDB {
		return nil
	}
	var operType = entity.RoleBindingTargetUser
	if operatorType == entity.OperatorTypeApiKey {
		operType = entity.RoleBindingTargetAPIKey
	}
	orgID, projectID, err := convertResource(ctx, scopeType, resourceID)
	if err != nil {
		return err
	}
	return dbUser.CreateCommandUserAction(ctx, tx,
		operatorID, keyEntity.ID.Uint64(), keyEntity.AccessKey, orgID, projectID, entity.CommandStatusWaiting, entity.CommandActionDelete, entity.RoleBindingTargetAPIKey, operType)
}
