package usecase

import (
	"context"

	"github.com/gofrs/uuid/v5"
	"golang.org/x/crypto/bcrypt"

	"github.com/saveinmed/backend-go/internal/domain"
)

// CreateUser hashes the password and persists a new user record.
func (s *Service) CreateUser(ctx context.Context, user *domain.User, password string) error {
	hashed, err := bcrypt.GenerateFromPassword([]byte(s.pepperPassword(password)), bcrypt.DefaultCost)
	if err != nil {
		return err
	}
	user.ID = uuid.Must(uuid.NewV7())
	user.PasswordHash = string(hashed)
	return s.repo.CreateUser(ctx, user)
}

// ListUsers returns a paginated list of users matching the filter.
func (s *Service) ListUsers(ctx context.Context, filter domain.UserFilter, page, pageSize int) (*domain.UserPage, error) {
	if page < 1 {
		page = 1
	}
	if pageSize <= 0 {
		pageSize = 20
	}
	filter.Limit = pageSize
	filter.Offset = (page - 1) * pageSize

	users, total, err := s.repo.ListUsers(ctx, filter)
	if err != nil {
		return nil, err
	}
	return &domain.UserPage{Users: users, Total: total, Page: page, PageSize: pageSize}, nil
}

// GetUser retrieves a user by ID.
func (s *Service) GetUser(ctx context.Context, id uuid.UUID) (*domain.User, error) {
	return s.repo.GetUser(ctx, id)
}

// UpdateUser persists changes to a user, optionally updating the password.
func (s *Service) UpdateUser(ctx context.Context, user *domain.User, newPassword string) error {
	if newPassword != "" {
		hashed, err := bcrypt.GenerateFromPassword([]byte(s.pepperPassword(newPassword)), bcrypt.DefaultCost)
		if err != nil {
			return err
		}
		user.PasswordHash = string(hashed)
	}
	return s.repo.UpdateUser(ctx, user)
}

// DeleteUser removes a user by ID.
func (s *Service) DeleteUser(ctx context.Context, id uuid.UUID) error {
	return s.repo.DeleteUser(ctx, id)
}
