package service

import (
	"context"
	"time"

	"wucher/internal/domain/dul"
)

type DULService struct {
	repo dul.Repository
}

func NewDULService(repo dul.Repository) *DULService {
	return &DULService{repo: repo}
}

func (s *DULService) Create(ctx context.Context, row *dul.DUL) error {
	return s.repo.Create(ctx, row)
}

func (s *DULService) Update(ctx context.Context, row *dul.DUL) error {
	return s.repo.Update(ctx, row)
}

func (s *DULService) Delete(ctx context.Context, id []byte, actorID []byte) error {
	row, err := s.repo.GetByID(ctx, id)
	if err != nil {
		return err
	}
	if row == nil {
		return nil
	}
	row.DeletedAt = ptrTimeDUL(time.Now().UTC())
	row.DeletedBy = actorID
	return s.repo.Delete(ctx, id)
}

func (s *DULService) GetByID(ctx context.Context, id []byte) (*dul.DUL, error) {
	return s.repo.GetByID(ctx, id)
}

func (s *DULService) List(ctx context.Context, filter, sort string, limit, offset int, baseIDs [][]byte) ([]dul.DUL, int64, error) {
	return s.repo.List(ctx, filter, sort, limit, offset, baseIDs)
}

func (s *DULService) WithTransaction(ctx context.Context, fn func(dul.Service) error) error {
	if s == nil || fn == nil {
		return nil
	}
	if txRepo, ok := s.repo.(dul.TransactionalRepository); ok {
		return txRepo.WithTransaction(ctx, func(repo dul.Repository) error {
			return fn(&DULService{repo: repo})
		})
	}
	return fn(s)
}

func ptrTimeDUL(t time.Time) *time.Time {
	return &t
}
