// codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/service/blockedemail/list.go
package blockedemail

import (
	"context"

	"go.uber.org/zap"

	"github.com/gocql/gocql"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config/constants"
	uc_blockedemail "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/blockedemail"
	"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror"
)

type ListBlockedEmailsService interface {
	Execute(ctx context.Context) (*ListBlockedEmailsResponseDTO, error)
}

type listBlockedEmailsServiceImpl struct {
	config                   *config.Configuration
	logger                   *zap.Logger
	listBlockedEmailsUseCase uc_blockedemail.ListBlockedEmailsUseCase
}

func NewListBlockedEmailsService(
	config *config.Configuration,
	logger *zap.Logger,
	listBlockedEmailsUseCase uc_blockedemail.ListBlockedEmailsUseCase,
) ListBlockedEmailsService {
	logger = logger.Named("ListBlockedEmailsService")
	return &listBlockedEmailsServiceImpl{
		config:                   config,
		logger:                   logger,
		listBlockedEmailsUseCase: listBlockedEmailsUseCase,
	}
}

func (svc *listBlockedEmailsServiceImpl) Execute(ctx context.Context) (*ListBlockedEmailsResponseDTO, error) {
	//
	// STEP 1: Get user ID from context
	//
	userID, ok := ctx.Value(constants.SessionUserID).(gocql.UUID)
	if !ok {
		svc.logger.Error("Failed getting user ID from context")
		return nil, httperror.NewInternalServerError("Authentication context error")
	}

	//
	// STEP 2: List blocked emails
	//
	blockedEmails, err := svc.listBlockedEmailsUseCase.Execute(ctx, userID)
	if err != nil {
		svc.logger.Error("Failed to list blocked emails",
			zap.Any("error", err),
			zap.Any("user_id", userID))
		return nil, err
	}

	//
	// STEP 3: Map to response DTOs
	//
	responseDTOs := make([]*BlockedEmailResponseDTO, len(blockedEmails))
	for i, blockedEmail := range blockedEmails {
		responseDTOs[i] = &BlockedEmailResponseDTO{
			UserID:        blockedEmail.UserID,
			BlockedEmail:  blockedEmail.BlockedEmail,
			BlockedUserID: blockedEmail.BlockedUserID,
			Reason:        blockedEmail.Reason,
			CreatedAt:     blockedEmail.CreatedAt,
		}
	}

	response := &ListBlockedEmailsResponseDTO{
		BlockedEmails: responseDTOs,
		Count:         len(responseDTOs),
	}

	return response, nil
}
