package service

import (
	"context"

	"git.threesix.ai/jordan/slack5-1770544098/pkg/logging"
	"git.threesix.ai/jordan/slack5-1770544098/services/preferences-api/internal/domain"
	"git.threesix.ai/jordan/slack5-1770544098/services/preferences-api/internal/port"
)

// PreferencesService handles user preferences business logic.
type PreferencesService struct {
	repo   port.PreferencesRepository
	logger *logging.Logger
}

// NewPreferencesService creates a new preferences service.
func NewPreferencesService(repo port.PreferencesRepository, logger *logging.Logger) *PreferencesService {
	return &PreferencesService{
		repo:   repo,
		logger: logger.WithService("PreferencesService"),
	}
}

// Get returns preferences for a user.
// Returns an empty preferences struct (not nil) for users with no saved preferences.
func (s *PreferencesService) Get(ctx context.Context, userID string) (*domain.UserPreferences, error) {
	prefs, err := s.repo.Get(ctx, userID)
	if err != nil {
		return nil, err
	}

	if prefs == nil {
		return &domain.UserPreferences{
			UserID:      userID,
			Preferences: map[string]any{},
		}, nil
	}

	return prefs, nil
}

// Update validates and persists preferences for a user.
// Returns the full merged preferences after upsert.
func (s *PreferencesService) Update(ctx context.Context, userID string, prefs map[string]any) (*domain.UserPreferences, error) {
	if err := domain.ValidatePreferences(prefs); err != nil {
		return nil, err
	}

	result, err := s.repo.Upsert(ctx, userID, prefs)
	if err != nil {
		return nil, err
	}

	s.logger.Info("preferences updated", "user_id", userID)
	return result, nil
}
