package repository

import (
	"actatempus_backend/internal/domain/data"
	"actatempus_backend/internal/domain/entities"
	"actatempus_backend/internal/domain/repository"
	"context"

	E "github.com/IBM/fp-go/either"
	F "github.com/IBM/fp-go/function"
)

// UserRepositoryImpl implements the UserRepository interface.
type UserRepositoryImpl struct {
	dataSource data.UserDataSource
}

// NewUserRepository creates a new instance of UserRepositoryImpl.
func NewUserRepository(dataSource data.UserDataSource) repository.UserRepository {
	return &UserRepositoryImpl{dataSource: dataSource}
}

// Create delegates the creation of a user to the data source.
func (r *UserRepositoryImpl) Create(ctx context.Context) func(user entities.UserCreate) E.Either[error, entities.User] {
	return F.Curry2(r.dataSource.Create)(ctx)
}

// FindByID delegates fetching a user by ID to the data source.
func (r *UserRepositoryImpl) FindByID(ctx context.Context) func(id string) E.Either[error, entities.User] {
	return F.Curry2(r.dataSource.FindByID)(ctx)
}

// FindByEmail delegates fetching a user by email to the data source.
func (r *UserRepositoryImpl) FindByEmail(ctx context.Context) func(email string) E.Either[error, entities.User] {
	return F.Curry2(r.dataSource.FindByEmail)(ctx)
}

// Update delegates updating a user to the data source.
func (r *UserRepositoryImpl) Update(ctx context.Context) func(user entities.UserUpdate) E.Either[error, entities.User] {
	return F.Curry2(r.dataSource.Update)(ctx)
}

// Delete delegates deleting a user to the data source.
func (r *UserRepositoryImpl) Delete(ctx context.Context) func(id string) E.Either[error, entities.User] {
	return F.Curry2(r.dataSource.Delete)(ctx)
}

// FindAll delegates fetching all users to the data source.
func (r *UserRepositoryImpl) FindAll(ctx context.Context) E.Either[error, []entities.User] {
	return F.Curry1(r.dataSource.FindAll)(ctx)
}
