package service

import (
	"context"

	"github.com/go-errors/errors"
	"github.com/oapi-codegen/nullable"

	"github.com/google/uuid"
	"github.com/phishingclub/phishingclub/data"
	"github.com/phishingclub/phishingclub/errs"
	"github.com/phishingclub/phishingclub/model"
	"github.com/phishingclub/phishingclub/repository"
	"github.com/phishingclub/phishingclub/validate"
	"github.com/phishingclub/phishingclub/vo"
	"gorm.io/gorm"
)

// Recipient is the Recipient service
type Recipient struct {
	Common
	RecipientRepository         *repository.Recipient
	RecipientGroupRepository    *repository.RecipientGroup
	CampaignRepository          *repository.Campaign
	CampaignRecipientRepository *repository.CampaignRecipient
}

// Create creates a new recipient
func (r *Recipient) Create(
	ctx context.Context,
	session *model.Session,
	recipient *model.Recipient,
) (*uuid.UUID, error) {
	ae := NewAuditEvent("Recipient.Create", session)
	// check permissions
	isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
	if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
		r.LogAuthError(err)
		return nil, errs.Wrap(err)
	}
	if !isAuthorized {
		r.AuditLogNotAuthorized(ae)
		return nil, errs.ErrAuthorizationFailed
	}
	// validate recipient
	if err := recipient.Validate(); err != nil {
		r.Logger.Debugw("failed to create recipient - recipient is invalid", "error", err)
		return nil, errs.Wrap(err)
	}
	email := recipient.Email.MustGet()
	// check if recipient already exists to avoid a unique constraint error
	// and gorm does not return a unique constraint error but a string error depending on DB
	// the match is case insensitive so the same address in a different casing is rejected
	_, err = r.RecipientRepository.GetByEmailLower(
		ctx,
		&email,
	)
	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		r.Logger.Errorw("failed to create recipient - failed to get recipient by any identifier", "error", err)
		return nil, errs.Wrap(err)
	}
	if err == nil {
		r.Logger.Debugw("email is already taken", "email", email.String())
		return nil, validate.WrapErrorWithField(errors.New("not unique"), "email")
	}
	id, err := r.RecipientRepository.Insert(
		ctx,
		recipient,
	)
	if err != nil {
		r.Logger.Errorw("failed to create recipient - failed to insert recipient", "error", err)
		return nil, errs.Wrap(err)
	}
	ae.Details["id"] = id.String()
	r.AuditLogAuthorized(ae)

	return id, nil
}

// UpdateByID updates a recipient by ID
func (r *Recipient) UpdateByID(
	ctx context.Context,
	session *model.Session,
	id *uuid.UUID,
	incoming *model.Recipient,
) error {
	ae := NewAuditEvent("Recipient.UpdateByID", session)
	ae.Details["id"] = id.String()
	// check permissions
	isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
	if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
		r.LogAuthError(err)
		return err
	}
	if !isAuthorized {
		r.AuditLogNotAuthorized(ae)
		return errs.ErrAuthorizationFailed
	}
	// check if recipient already exists and the user is allowed to update the recipient
	current, err := r.RecipientRepository.GetByID(
		ctx,
		id,
		&repository.RecipientOption{},
	)
	if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
		r.Logger.Errorw("failed to update recipient - failed to get recipient by any identifier", "error", err)
		return err
	}
	if errors.Is(err, gorm.ErrRecordNotFound) {
		r.Logger.Debug("failed to update recipient - recipient not found")
		return err
	}
	// update config - if a field is present and not null, update it

	// the email is the recipient identity and is immutable, so any incoming
	// email is ignored and the stored one is preserved
	if v, err := incoming.Phone.Get(); err == nil {
		current.Phone.Set(v)
	}
	if v, err := incoming.ExtraIdentifier.Get(); err == nil {
		current.ExtraIdentifier.Set(v)
	}
	if v, err := incoming.FirstName.Get(); err == nil {
		current.FirstName.Set(v)
	}
	if v, err := incoming.LastName.Get(); err == nil {
		current.LastName.Set(v)
	}
	if v, err := incoming.Position.Get(); err == nil {
		current.Position.Set(v)
	}
	if v, err := incoming.Department.Get(); err == nil {
		current.Department.Set(v)
	}
	if v, err := incoming.City.Get(); err == nil {
		current.City.Set(v)
	}
	if v, err := incoming.Country.Get(); err == nil {
		current.Country.Set(v)
	}
	if v, err := incoming.Misc.Get(); err == nil {
		current.Misc.Set(v)
	}
	// validate
	if err := current.Validate(); err != nil {
		r.Logger.Debugw("failed to update recipient - recipient is invalid", "error", err)
		return err
	}
	// save config
	err = r.RecipientRepository.UpdateByID(
		ctx,
		id,
		current,
	)
	if err != nil {
		r.Logger.Errorw("failed to update recipient - failed to update recipient", "error", err)
		return err
	}
	r.AuditLogAuthorized(ae)

	return nil
}

// GetByID gets a recipient by ID
func (r *Recipient) GetByID(
	ctx context.Context,
	session *model.Session,
	id *uuid.UUID,
	options *repository.RecipientOption,
) (*model.Recipient, error) {
	ae := NewAuditEvent("Recipient.GetByID", session)
	ae.Details["id"] = id.String()
	// check permissions
	isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
	if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
		r.LogAuthError(err)
		return nil, errs.Wrap(err)
	}
	if !isAuthorized {
		r.AuditLogNotAuthorized(ae)
		return nil, errs.ErrAuthorizationFailed
	}
	// get recipient
	recipient, err := r.RecipientRepository.GetByID(
		ctx,
		id,
		options,
	)
	if err != nil {
		r.Logger.Errorw("failed to get recipient by id - failed to get recipient", "error", err)
		return nil, errs.Wrap(err)
	}
	// no audit on read

	return recipient, nil
}

// GetByCompanyID gets a recipients by company ID
func (r *Recipient) GetByCompanyID(
	ctx context.Context,
	session *model.Session,
	id *uuid.UUID,
	options *repository.RecipientOption,
) (*model.Result[model.Recipient], error) {
	result := model.NewEmptyResult[model.Recipient]()
	ae := NewAuditEvent("Recipient.GetByCompanyID", session)
	if id != nil {
		ae.Details["id"] = id.String()
	}
	// check permissions
	isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
	if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
		r.LogAuthError(err)
		return result, errs.Wrap(err)
	}
	if !isAuthorized {
		r.AuditLogNotAuthorized(ae)
		return result, errs.ErrAuthorizationFailed
	}
	// get recipients
	result, err = r.RecipientRepository.GetAllByCompanyID(
		ctx,
		id,
		options,
	)
	if err != nil {
		r.Logger.Errorw("failed to get recipients by company id - failed to get recipient", "error", err)
		return result, errs.Wrap(err)
	}
	// no audit on read
	return result, nil
}

// GetStatsByID get campaign events stats by recipient ID
func (r *Recipient) GetStatsByID(
	ctx context.Context,
	session *model.Session,
	recipientID *uuid.UUID,
) (*model.RecipientCampaignStatsView, error) {
	ae := NewAuditEvent("Recipient.GetStatsByID", session)
	// check permissions
	isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
	if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
		r.LogAuthError(err)
		return nil, errs.Wrap(err)
	}
	if !isAuthorized {
		r.AuditLogNotAuthorized(ae)
		return nil, errs.ErrAuthorizationFailed
	}
	// get stats
	stats, err := r.RecipientRepository.GetStatsByID(
		ctx,
		recipientID,
	)
	if err != nil {
		r.Logger.Errorw("failed to get all recipient events", "error", err)
		return nil, errs.Wrap(err)
	}
	// no audit on read

	return stats, nil
}

// GetAllCampaignEvents get events by recipient ID
// gets all events if campaignID is nil
func (r *Recipient) GetAllCampaignEvents(
	ctx context.Context,
	session *model.Session,
	recipientID *uuid.UUID,
	campaignID *uuid.UUID,
	queryArgs *vo.QueryArgs,
) (*model.Result[model.RecipientCampaignEvent], error) {
	result := model.NewEmptyResult[model.RecipientCampaignEvent]()
	ae := NewAuditEvent("Recipient.GetAllCampaignEvents", session)
	if recipientID != nil {
		ae.Details["recipientId"] = recipientID.String()
	}
	if campaignID != nil {
		ae.Details["campaignId"] = campaignID.String()
	}
	// check permissions
	isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
	if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
		r.LogAuthError(err)
		return result, errs.Wrap(err)
	}
	if !isAuthorized {
		r.AuditLogNotAuthorized(ae)
		return result, errs.ErrAuthorizationFailed
	}
	// get all events
	result, err = r.RecipientRepository.GetAllCampaignEvents(
		ctx,
		recipientID,
		campaignID,
		queryArgs,
	)
	if err != nil {
		r.Logger.Errorw("failed to get all recipient events", "error", err)
		return nil, errs.Wrap(err)
	}
	// no audit log on read
	return result, nil
}

// GetAll gets all recipients
func (r *Recipient) GetAll(
	ctx context.Context,
	companyID *uuid.UUID, // can be null
	session *model.Session,
	options *repository.RecipientOption,
) (*model.Result[model.RecipientView], error) {
	result := model.NewEmptyResult[model.RecipientView]()
	ae := NewAuditEvent("Recipient.GetAll", session)
	// check permissions
	isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
	if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
		r.LogAuthError(err)
		return result, errs.Wrap(err)
	}
	if !isAuthorized {
		r.AuditLogNotAuthorized(ae)
		return result, errs.ErrAuthorizationFailed
	}
	// get all recipients
	result, err = r.RecipientRepository.GetAll(
		ctx,
		companyID,
		options,
	)
	if err != nil {
		r.Logger.Errorw("failed to get all recipients - failed to get all recipients", "error", err)
		return result, errs.Wrap(err)
	}
	// no audit on read
	return result, nil
}

func (r *Recipient) GetRepeatOffenderCount(
	ctx context.Context,
	session *model.Session,
	companyID *uuid.UUID,
) (int64, error) {
	ae := NewAuditEvent("Recipient.GetRepeatOffenderCount", session)
	// check permissions
	isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
	if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
		r.LogAuthError(err)
		return 0, errs.Wrap(err)
	}
	if !isAuthorized {
		r.AuditLogNotAuthorized(ae)
		return 0, errs.ErrAuthorizationFailed
	}

	count, err := r.RecipientRepository.GetRepeatOffenderCount(ctx, companyID)
	if err != nil {
		r.Logger.Errorw("failed to get repeat offender count", "error", err)
		return 0, errs.Wrap(err)
	}

	return count, nil
}

// GetOrphaned gets all recipients that are not in any group
func (r *Recipient) GetOrphaned(
	ctx context.Context,
	companyID *uuid.UUID, // can be null
	session *model.Session,
	options *repository.RecipientOption,
) (*model.Result[model.Recipient], error) {
	result := model.NewEmptyResult[model.Recipient]()
	ae := NewAuditEvent("Recipient.GetOrphaned", session)
	// check permissions
	isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
	if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
		r.LogAuthError(err)
		return result, errs.Wrap(err)
	}
	if !isAuthorized {
		r.AuditLogNotAuthorized(ae)
		return result, errs.ErrAuthorizationFailed
	}
	// get orphaned recipients — dynamic group exclusion is handled in SQL
	result, err = r.RecipientRepository.GetOrphaned(
		ctx,
		companyID,
		options,
	)
	if err != nil {
		r.Logger.Errorw("failed to get orphaned recipients", "error", err)
		return result, errs.Wrap(err)
	}
	// no audit on read
	return result, nil
}

// DeleteAllOrphaned deletes all recipients that are not in any group
func (r *Recipient) DeleteAllOrphaned(
	ctx context.Context,
	companyID *uuid.UUID, // can be null
	session *model.Session,
) (int64, error) {
	ae := NewAuditEvent("Recipient.DeleteAllOrphaned", session)
	// check permissions
	isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
	if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
		r.LogAuthError(err)
		return 0, errs.Wrap(err)
	}
	if !isAuthorized {
		r.AuditLogNotAuthorized(ae)
		return 0, errs.ErrAuthorizationFailed
	}

	// get orphaned recipients — dynamic group exclusion is handled in SQL
	orphanedRecipients, err := r.RecipientRepository.GetOrphaned(
		ctx,
		companyID,
		&repository.RecipientOption{}, // no pagination, get all
	)
	if err != nil {
		r.Logger.Errorw("failed to get orphaned recipients", "error", err)
		return 0, errs.Wrap(err)
	}

	// delete each orphaned recipient using core deletion logic
	var count int64
	for _, recipient := range orphanedRecipients.Rows {
		recipientID := recipient.ID.MustGet()
		err = r.deleteRecipientByID(ctx, &recipientID)
		if err != nil {
			r.Logger.Errorw("failed to delete orphaned recipient", "error", err, "recipientID", recipientID.String())
			return count, errs.Wrap(err)
		}
		count++
	}

	ae.Details["count"] = count
	r.AuditLogAuthorized(ae)
	return count, nil
}

// GetByEmail gets a recipient by email
func (r *Recipient) GetByEmail(
	ctx context.Context,
	session *model.Session,
	email *vo.Email,
	companyID *uuid.UUID,
) (*model.Recipient, error) {
	ae := NewAuditEvent("Recipient.GetByEmail", session)
	ae.Details["email"] = email.String()
	if companyID != nil {
		ae.Details["companyId"] = companyID.String()
	}
	// check permissions
	isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
	if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
		r.LogAuthError(err)
		return nil, errs.Wrap(err)
	}
	if !isAuthorized {
		r.AuditLogNotAuthorized(ae)
		return nil, errs.ErrAuthorizationFailed
	}
	// get recipient
	recipient, err := r.RecipientRepository.GetByEmailAndCompanyID(
		ctx,
		email,
		companyID,
	)
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, errs.Wrap(err)
	}
	if err != nil {
		r.Logger.Errorw("failed to get recipient by any identifier - failed to get recipient",
			"error", err,
		)
		return nil, errs.Wrap(err)
	}
	// no audit on read

	return recipient, nil
}

// Import imports recipients
// if the recipient does not exists, it will be created and added to the group
// if the recipient exits, it will be updated and added to the group

// RecipientImportResult contains the results of importing recipients
type RecipientImportResult struct {
	SuccessIDs        []*uuid.UUID             `json:"successIDs"`
	CreatedRecipients []RecipientImportSuccess `json:"createdRecipients"`
	UpdatedRecipients []RecipientImportSuccess `json:"updatedRecipients"`
	Failures          []RecipientImportFailure `json:"failures"`
	Summary           RecipientImportSummary   `json:"summary"`
}

// RecipientImportSuccess contains information about a successful import
type RecipientImportSuccess struct {
	Email     string `json:"email"`
	FirstName string `json:"firstName"`
	LastName  string `json:"lastName"`
	Index     int    `json:"index"`
}

// RecipientImportFailure contains information about a failed import
type RecipientImportFailure struct {
	Email  string `json:"email"`
	Index  int    `json:"index"`
	Reason string `json:"reason"`
}

// RecipientImportSummary contains summary statistics
type RecipientImportSummary struct {
	Total   int `json:"total"`
	Success int `json:"success"`
	Failed  int `json:"failed"`
	Created int `json:"created"`
	Updated int `json:"updated"`
}

func (r *Recipient) Import(
	ctx context.Context,
	session *model.Session,
	recipients []*model.Recipient,
	ignoreOverwriteEmptyFields bool,
	companyID *uuid.UUID,
) (*RecipientImportResult, error) {
	ae := NewAuditEvent("Recipient.Import", session)
	result := &RecipientImportResult{
		SuccessIDs:        []*uuid.UUID{},
		CreatedRecipients: []RecipientImportSuccess{},
		UpdatedRecipients: []RecipientImportSuccess{},
		Failures:          []RecipientImportFailure{},
		Summary: RecipientImportSummary{
			Total: len(recipients),
		},
	}
	// check permissions
	isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
	if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
		r.LogAuthError(err)
		return result, errs.Wrap(err)
	}
	if !isAuthorized {
		r.AuditLogNotAuthorized(ae)
		return result, errs.ErrAuthorizationFailed
	}
	if len(recipients) == 0 {
		return result, validate.WrapErrorWithField(errors.New("no recipients"), "add recipients")
	}

	// process each recipient individually, collecting successes and failures
	for i, incoming := range recipients {
		// validate the recipient
		if err := incoming.Validate(); err != nil {
			result.Failures = append(result.Failures, RecipientImportFailure{
				Email:  getEmailFromRecipient(incoming),
				Index:  i,
				Reason: err.Error(),
			})
			result.Summary.Failed++
			continue
		}

		// check if the recipient exists, case insensitively so the same address
		// in a different casing updates the existing recipient instead of creating
		// a duplicate
		email := incoming.Email.MustGet()
		current, err := r.RecipientRepository.GetByEmailLower(
			ctx,
			&email,
			"id", "email", "company_id",
		)
		if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
			r.Logger.Debugw("failed to import recipient - failed to get recipient",
				"error", err,
				"email", email.String(),
			)
			result.Failures = append(result.Failures, RecipientImportFailure{
				Email:  email.String(),
				Index:  i,
				Reason: "database error: " + err.Error(),
			})
			result.Summary.Failed++
			continue
		}
		if current == nil {
			// create recipient
			if companyID != nil {
				incoming.CompanyID.Set(*companyID)
			}
			recipientID, err := r.Create(
				ctx,
				session,
				incoming,
			)
			if err != nil {
				r.Logger.Debugw("failed to import recipient - failed to create recipient",
					"error", err,
					"email", email.String(),
				)
				result.Failures = append(result.Failures, RecipientImportFailure{
					Email:  email.String(),
					Index:  i,
					Reason: "create failed: " + err.Error(),
				})
				result.Summary.Failed++
				continue
			}
			result.SuccessIDs = append(result.SuccessIDs, recipientID)
			result.Summary.Success++
			result.Summary.Created++
			result.CreatedRecipients = append(result.CreatedRecipients, RecipientImportSuccess{
				Email:     email.String(),
				FirstName: getStringFromOptional(incoming.FirstName),
				LastName:  getStringFromOptional(incoming.LastName),
				Index:     i,
			})
		} else {
			// set the companyID to NOT SET, so it is not overwritten if supplied
			incoming.CompanyID.SetUnspecified()
			if ignoreOverwriteEmptyFields {
				incoming.NullifyEmptyOptionals()
			} else {
				incoming.EmptyStringNulledOptionals()
			}
			// update recipient
			recipientID := current.ID.MustGet()
			err = r.UpdateByID(
				ctx,
				session,
				&recipientID,
				incoming,
			)
			if err != nil {
				r.Logger.Debugw("failed to import recipient - failed to update recipient",
					"error", err,
					"email", email.String(),
				)
				result.Failures = append(result.Failures, RecipientImportFailure{
					Email:  email.String(),
					Index:  i,
					Reason: "update failed: " + err.Error(),
				})
				result.Summary.Failed++
				continue
			}
			result.SuccessIDs = append(result.SuccessIDs, &recipientID)
			result.Summary.Success++
			result.Summary.Updated++
			result.UpdatedRecipients = append(result.UpdatedRecipients, RecipientImportSuccess{
				Email:     email.String(),
				FirstName: getStringFromOptional(incoming.FirstName),
				LastName:  getStringFromOptional(incoming.LastName),
				Index:     i,
			})
		}
	}
	r.AuditLogAuthorized(ae)
	return result, nil
}

// getEmailFromRecipient safely extracts email from recipient for error reporting
func getEmailFromRecipient(r *model.Recipient) string {
	if r.Email.IsSpecified() && !r.Email.IsNull() {
		return r.Email.MustGet().String()
	}
	return "<no email>"
}

// getStringFromOptional safely extracts string from optional field
func getStringFromOptional(field nullable.Nullable[vo.OptionalString127]) string {
	if field.IsSpecified() && !field.IsNull() {
		return field.MustGet().String()
	}
	return ""
}

// deleteRecipientByID is the core deletion logic without permission checks or audit logging
func (r *Recipient) deleteRecipientByID(
	ctx context.Context,
	id *uuid.UUID,
) error {
	// remove recipient from all groups
	err := r.RecipientGroupRepository.RemoveRecipientByIDFromAllGroups(ctx, id)
	if err != nil {
		r.Logger.Errorw("failed to delete recipient - failed to remove recipient from all groups",
			"error", err,
		)
		return err
	}
	// cancel the recipient's not-yet-sent rows in any open (non-closed) campaign,
	// including future-scheduled ones, so anonymization never leaves an uncancelled
	// pending row behind
	err = r.CampaignRecipientRepository.CancelUnsentInOpenCampaigns(ctx, id)
	if err != nil {
		r.Logger.Errorw("failed to cancel campaign recipient sends before deletion", "error", err)
		return err
	}
	// anonymize all recipient data
	anonymizedID := uuid.New()
	err = r.CampaignRecipientRepository.Anonymize(
		ctx,
		nil, // nil campaignID means anonymize across all campaigns
		id,
		&anonymizedID,
	)
	if err != nil {
		r.Logger.Errorw("failed to add anonymized ID to campaign recipient", "error", err)
		return err
	}
	// anonymize events and assign each anonymized ID so the events can still be tracked
	err = r.CampaignRepository.AnonymizeCampaignEventsByRecipientID(
		ctx,
		id,
		&anonymizedID,
	)
	if err != nil {
		r.Logger.Errorw("failed to anonymize campaign event", "error", err)
		return err
	}
	// remove recipient id from all campaign recipients
	err = r.CampaignRecipientRepository.RemoveRecipientIDByRecipientID(
		ctx,
		id,
	)
	if err != nil {
		r.Logger.Errorw("failed to remove recipient id from campaign recipient", "error", err)
		return err
	}
	// delete recipient
	err = r.RecipientRepository.DeleteByID(
		ctx,
		id,
	)
	if err != nil {
		r.Logger.Errorw("failed to delete recipient - failed to delete recipient", "error", err)
		return err
	}

	return nil
}

// DeleteByID deletes a recipient
func (r *Recipient) DeleteByID(
	ctx context.Context,
	session *model.Session,
	id *uuid.UUID,
) error {
	ae := NewAuditEvent("Recipient.DeleteByID", session)
	ae.Details["id"] = id.String()
	// check permissions
	isAuthorized, err := IsAuthorized(session, data.PERMISSION_ALLOW_GLOBAL)
	if err != nil && !errors.Is(err, errs.ErrAuthorizationFailed) {
		r.LogAuthError(err)
		return err
	}
	if !isAuthorized {
		r.AuditLogNotAuthorized(ae)
		return errs.ErrAuthorizationFailed
	}

	err = r.deleteRecipientByID(ctx, id)
	if err != nil {
		return err
	}

	r.AuditLogAuthorized(ae)
	return nil
}
