package comsvc

import (
	"context"
	"fmt"

	"github.com/tidbcloud/account/central/events/publish"
	"github.com/tidbcloud/account/commons/database"
	"github.com/tidbcloud/account/internel/dao"
	"github.com/tidbcloud/account/internel/dao/entity"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
)

func SendUserRoleBindingChangeEvent(ctx context.Context, userId, orgId uint64, bizLogPre string) error {
	tilog.Info(ctx, fmt.Sprintf("%s SendUserRoleBindingChangeEvent", bizLogPre), zap.Any("user_id", userId), zap.Any("org_id", orgId))

	user, err := dao.GetDaoHub().User.GetUserByID(ctx, database.DBConn.DB, userId)
	if err != nil {
		tilog.Warn(ctx, fmt.Sprintf("%s SendUserRoleBindingChangeEvent GetUserByID error", bizLogPre), zap.Any("err", err))
		return err
	}
	org, err := dao.GetDaoHub().Org.GetOrgByOrgID(ctx, database.DBConn.DB, orgId)
	if err != nil {
		tilog.Warn(ctx, fmt.Sprintf("%s SendUserRoleBindingChangeEvent GetOrgByOrgID error", bizLogPre), zap.Any("err", err))
		return err
	}

	rBindings, err := ListIdentRoleBindings(ctx, entity.RoleBindingTargetUser, userId, orgId, []entity.ScopeType{entity.RoleBindingScopeOrg, entity.RoleBindingScopeProject}, []string{entity.RoleBindingStatusActive})
	if err != nil {
		tilog.Warn(ctx, fmt.Sprintf("%s SendUserRoleBindingChangeEvent ListIdentRoleBindings error", bizLogPre), zap.Any("err", err))
		return err
	}

	return publish.PublishDataChangeEventWithEntData(ctx, publish.BizEventUserRoleBindingChanged, user, nil, org, rBindings)
}

func SendApiKeyRoleBindingChangeEvent(ctx context.Context, keyId, orgId uint64, bizLogPre string) error {
	tilog.Info(ctx, fmt.Sprintf("%s SendApiKeyRoleBindingChangeEvent", bizLogPre), zap.Any("key_id", keyId), zap.Any("org_id", orgId))

	key, err := dao.GetDaoHub().ApiKey.GetApiKeyByID(ctx, database.DBConn.DB, keyId)
	if err != nil {
		tilog.Warn(ctx, fmt.Sprintf("%s SendApiKeyRoleBindingChangeEvent GetApiKeyByID error", bizLogPre), zap.Any("err", err))
		return err
	}
	org, err := dao.GetDaoHub().Org.GetOrgByOrgID(ctx, database.DBConn.DB, orgId)
	if err != nil {
		tilog.Warn(ctx, fmt.Sprintf("%s SendApiKeyRoleBindingChangeEvent GetOrgByOrgID error", bizLogPre), zap.Any("err", err))
		return err
	}

	rBindings, err := ListIdentRoleBindings(ctx, entity.RoleBindingTargetAPIKey, keyId, orgId, []entity.ScopeType{entity.RoleBindingScopeOrg, entity.RoleBindingScopeProject}, []string{entity.RoleBindingStatusActive})
	if err != nil {
		tilog.Warn(ctx, fmt.Sprintf("%s SendApiKeyRoleBindingChangeEvent ListIdentRoleBindings error", bizLogPre), zap.Any("err", err))
		return err
	}

	bizEventType := publish.BizEventApiKeyRoleBindingChanged

	return publish.PublishDataChangeEventWithEntData(ctx, bizEventType, nil, key, org, rBindings)
}
