package monetization

import (
	"context"
	"errors"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/suite"
	"testing"
)

type MonetizationCommandsSuite struct {
	suite.Suite
	repo     *mockMonetizationRepository
	commands *MonetizationCommands
}

func (s *MonetizationCommandsSuite) SetupTest() {
	s.repo = &mockMonetizationRepository{}
	s.commands = NewMonetizationCommands(s.repo)
}

func TestMonetizationCommandsSuite(t *testing.T) {
	suite.Run(t, new(MonetizationCommandsSuite))
}

func (s *MonetizationCommandsSuite) TestAddMonetizationToWork_Success() {
	err := s.commands.AddMonetizationToWork(context.Background(), 1, 2)
	assert.NoError(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestAddMonetizationToWork_ZeroID() {
	err := s.commands.AddMonetizationToWork(context.Background(), 0, 2)
	assert.Error(s.T(), err)
	err = s.commands.AddMonetizationToWork(context.Background(), 1, 0)
	assert.Error(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestAddMonetizationToWork_RepoError() {
	s.repo.addMonetizationToWorkFunc = func(ctx context.Context, workID uint, monetizationID uint) error {
		return errors.New("db error")
	}
	err := s.commands.AddMonetizationToWork(context.Background(), 1, 2)
	assert.Error(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestRemoveMonetizationFromWork_Success() {
	err := s.commands.RemoveMonetizationFromWork(context.Background(), 1, 2)
	assert.NoError(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestRemoveMonetizationFromWork_ZeroID() {
	err := s.commands.RemoveMonetizationFromWork(context.Background(), 0, 2)
	assert.Error(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestRemoveMonetizationFromWork_RepoError() {
	s.repo.removeMonetizationFromWorkFunc = func(ctx context.Context, workID uint, monetizationID uint) error {
		return errors.New("db error")
	}
	err := s.commands.RemoveMonetizationFromWork(context.Background(), 1, 2)
	assert.Error(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestAddMonetizationToAuthor_Success() {
	err := s.commands.AddMonetizationToAuthor(context.Background(), 1, 2)
	assert.NoError(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestAddMonetizationToAuthor_ZeroID() {
	err := s.commands.AddMonetizationToAuthor(context.Background(), 0, 2)
	assert.Error(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestAddMonetizationToAuthor_RepoError() {
	s.repo.addMonetizationToAuthorFunc = func(ctx context.Context, authorID uint, monetizationID uint) error {
		return errors.New("db error")
	}
	err := s.commands.AddMonetizationToAuthor(context.Background(), 1, 2)
	assert.Error(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestRemoveMonetizationFromAuthor_Success() {
	err := s.commands.RemoveMonetizationFromAuthor(context.Background(), 1, 2)
	assert.NoError(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestRemoveMonetizationFromAuthor_ZeroID() {
	err := s.commands.RemoveMonetizationFromAuthor(context.Background(), 0, 2)
	assert.Error(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestRemoveMonetizationFromAuthor_RepoError() {
	s.repo.removeMonetizationFromAuthorFunc = func(ctx context.Context, authorID uint, monetizationID uint) error {
		return errors.New("db error")
	}
	err := s.commands.RemoveMonetizationFromAuthor(context.Background(), 1, 2)
	assert.Error(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestAddMonetizationToBook_Success() {
	err := s.commands.AddMonetizationToBook(context.Background(), 1, 2)
	assert.NoError(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestAddMonetizationToBook_ZeroID() {
	err := s.commands.AddMonetizationToBook(context.Background(), 0, 2)
	assert.Error(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestAddMonetizationToBook_RepoError() {
	s.repo.addMonetizationToBookFunc = func(ctx context.Context, bookID uint, monetizationID uint) error {
		return errors.New("db error")
	}
	err := s.commands.AddMonetizationToBook(context.Background(), 1, 2)
	assert.Error(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestRemoveMonetizationFromBook_Success() {
	err := s.commands.RemoveMonetizationFromBook(context.Background(), 1, 2)
	assert.NoError(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestRemoveMonetizationFromBook_ZeroID() {
	err := s.commands.RemoveMonetizationFromBook(context.Background(), 0, 2)
	assert.Error(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestRemoveMonetizationFromBook_RepoError() {
	s.repo.removeMonetizationFromBookFunc = func(ctx context.Context, bookID uint, monetizationID uint) error {
		return errors.New("db error")
	}
	err := s.commands.RemoveMonetizationFromBook(context.Background(), 1, 2)
	assert.Error(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestAddMonetizationToPublisher_Success() {
	err := s.commands.AddMonetizationToPublisher(context.Background(), 1, 2)
	assert.NoError(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestAddMonetizationToPublisher_ZeroID() {
	err := s.commands.AddMonetizationToPublisher(context.Background(), 0, 2)
	assert.Error(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestAddMonetizationToPublisher_RepoError() {
	s.repo.addMonetizationToPublisherFunc = func(ctx context.Context, publisherID uint, monetizationID uint) error {
		return errors.New("db error")
	}
	err := s.commands.AddMonetizationToPublisher(context.Background(), 1, 2)
	assert.Error(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestRemoveMonetizationFromPublisher_Success() {
	err := s.commands.RemoveMonetizationFromPublisher(context.Background(), 1, 2)
	assert.NoError(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestRemoveMonetizationFromPublisher_ZeroID() {
	err := s.commands.RemoveMonetizationFromPublisher(context.Background(), 0, 2)
	assert.Error(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestRemoveMonetizationFromPublisher_RepoError() {
	s.repo.removeMonetizationFromPublisherFunc = func(ctx context.Context, publisherID uint, monetizationID uint) error {
		return errors.New("db error")
	}
	err := s.commands.RemoveMonetizationFromPublisher(context.Background(), 1, 2)
	assert.Error(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestAddMonetizationToSource_Success() {
	err := s.commands.AddMonetizationToSource(context.Background(), 1, 2)
	assert.NoError(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestAddMonetizationToSource_ZeroID() {
	err := s.commands.AddMonetizationToSource(context.Background(), 0, 2)
	assert.Error(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestAddMonetizationToSource_RepoError() {
	s.repo.addMonetizationToSourceFunc = func(ctx context.Context, sourceID uint, monetizationID uint) error {
		return errors.New("db error")
	}
	err := s.commands.AddMonetizationToSource(context.Background(), 1, 2)
	assert.Error(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestRemoveMonetizationFromSource_Success() {
	err := s.commands.RemoveMonetizationFromSource(context.Background(), 1, 2)
	assert.NoError(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestRemoveMonetizationFromSource_ZeroID() {
	err := s.commands.RemoveMonetizationFromSource(context.Background(), 0, 2)
	assert.Error(s.T(), err)
}

func (s *MonetizationCommandsSuite) TestRemoveMonetizationFromSource_RepoError() {
	s.repo.removeMonetizationFromSourceFunc = func(ctx context.Context, sourceID uint, monetizationID uint) error {
		return errors.New("db error")
	}
	err := s.commands.RemoveMonetizationFromSource(context.Background(), 1, 2)
	assert.Error(s.T(), err)
}
