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"
)

// TimeEntryRepositoryImpl implements the TimeEntryRepository interface.
type TimeEntryRepositoryImpl struct {
	dataSource data.TimeEntryDataSource
}

// NewTimeEntryRepository creates a new instance of TimeEntryRepositoryImpl.
func NewTimeEntryRepository(dataSource data.TimeEntryDataSource) repository.TimeEntryRepository {
	return &TimeEntryRepositoryImpl{dataSource: dataSource}
}

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

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

// FindByUserID delegates fetching TimeEntries by UserID to the data source.
func (r *TimeEntryRepositoryImpl) FindByUserID(ctx context.Context) func(userID string) E.Either[error, []entities.TimeEntry] {
	return F.Curry2(r.dataSource.FindByUserID)(ctx)
}

// FindByProjectID delegates fetching TimeEntries by ProjectID to the data source.
func (r *TimeEntryRepositoryImpl) FindByProjectID(ctx context.Context) func(projectID string) E.Either[error, []entities.TimeEntry] {
	return F.Curry2(r.dataSource.FindByProjectID)(ctx)
}

// Update delegates updating a TimeEntry to the data source.
func (r *TimeEntryRepositoryImpl) Update(ctx context.Context) func(entry entities.TimeEntryUpdate) E.Either[error, entities.TimeEntry] {
	return F.Curry2(r.dataSource.Update)(ctx)
}

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

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