package dbuser

import (
	"context"
	"strconv"

	"github.com/tidbcloud/account/internel/dao/dbuser"

	"github.com/tidbcloud/account/internel/dao/entity"
	"gorm.io/gorm"

	"github.com/tidbcloud/account/central/utils"
	"github.com/tidbcloud/tiinf/monitor/tilog"
	"go.uber.org/zap"
)

const (
	kmsKeyDescription string = "account dbuser for org:"
)

func (r *DBUserSvc) CreateKmsKey(ctx context.Context, description string) (string, error) {
	kmsService := utils.GetKeyServiceSingleton()

	keyID, _, err := kmsService.CreateSignKey(description)
	return keyID, err
}

func (r *DBUserSvc) DeleteKmsKeyAndUpdateRecord(ctx context.Context, orgId uint64) error {
	filter := dbuser.OrgKeyFilter{
		OrgIDs: []entity.ID{entity.ID(orgId)},
		Status: []entity.OrgKeyStatus{entity.OrgKeyStatusActive},
	}
	orgKeys, err := r.ListOrgKeys(ctx, filter)
	for _, okgKey := range orgKeys {

		err = r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
			err := r.DeleteKmsKey(ctx, okgKey.KeyID)
			if err != nil {
				return err
			}
			err = r.UpdateOrgKey(ctx, orgId, okgKey.KeyID, entity.OrgKeyStatusDelete)
			if err != nil {
				tilog.Error(ctx, "UpdateOrgKey fail", zap.Any("keyID", okgKey.KeyID), zap.Any("orgId", orgId),
					zap.Any("status", entity.OrgKeyStatusDelete))
				return err
			}
			tilog.Info(ctx, "delete OrgKey set status = delete", zap.Any("id", okgKey.ID), zap.Any("keyID", okgKey.KeyID), zap.Any("orgId", orgId))
			return nil
		})
	}

	return err
}
func (r *DBUserSvc) DeleteKmsKey(ctx context.Context, keyID string) error {
	kmsService := utils.GetKeyServiceSingleton()
	err := kmsService.DeleteSignKeyById(keyID)
	if err != nil {
		tilog.Error(ctx, "deleteKmsKey fail", zap.Any("keyID", keyID))
		return err
	}
	tilog.Info(ctx, "delete KmsKey success", zap.Any("keyID", keyID))
	return nil
}

func (r *DBUserSvc) CreateKmsKeyAndUpdateRecord(ctx context.Context, orgKey entity.CommandOrgKey) error {
	description := kmsKeyDescription + strconv.Itoa(int(orgKey.OrgID.Uint64()))
	keyID, err := r.CreateKmsKey(ctx, description)
	if err != nil {
		tilog.Error(ctx, "CreateKmsKey fail", zap.Any("keyID", keyID),
			zap.Any("orgKey.OrgId", orgKey.OrgID), zap.Any("error", err.Error()))
		return err
	}
	tilog.Info(ctx, "CreateKmsKey success", zap.Any("keyID", keyID),
		zap.Any("orgKey.OrgId", orgKey.OrgID), zap.Any("description", description))

	err = r.CreateOrgKey(ctx, orgKey.OrgID.Uint64(), keyID, entity.OrgKeyStatusActive)

	if err != nil {
		tilog.Error(ctx, "CreateOrgKey fail", zap.Any("keyID", keyID),
			zap.Any("orgKey.OrgId", orgKey.OrgID), zap.Any("error", err.Error()))
		return err
	}
	tilog.Info(ctx, "CreateOrgKey success",
		zap.Any("orgKey.OrgId", orgKey.OrgID), zap.Any("description", description))
	return nil
}
