package monetization

import (
	"context"
	"errors"
	"tercul/internal/domain"
	"tercul/internal/platform/log"
)

// MonetizationCommands contains the command handlers for monetization.
type MonetizationCommands struct {
	repo domain.MonetizationRepository
}

// NewMonetizationCommands creates a new MonetizationCommands handler.
func NewMonetizationCommands(repo domain.MonetizationRepository) *MonetizationCommands {
	return &MonetizationCommands{repo: repo}
}

// AddMonetizationToWork adds a monetization to a work.
func (c *MonetizationCommands) AddMonetizationToWork(ctx context.Context, workID uint, monetizationID uint) error {
	if workID == 0 || monetizationID == 0 {
		return errors.New("invalid work ID or monetization ID")
	}
	log.FromContext(ctx).With("work_id", workID).With("monetization_id", monetizationID).Debug("Adding monetization to work")
	return c.repo.AddMonetizationToWork(ctx, workID, monetizationID)
}

// RemoveMonetizationFromWork removes a monetization from a work.
func (c *MonetizationCommands) RemoveMonetizationFromWork(ctx context.Context, workID uint, monetizationID uint) error {
	if workID == 0 || monetizationID == 0 {
		return errors.New("invalid work ID or monetization ID")
	}
	log.FromContext(ctx).With("work_id", workID).With("monetization_id", monetizationID).Debug("Removing monetization from work")
	return c.repo.RemoveMonetizationFromWork(ctx, workID, monetizationID)
}

func (c *MonetizationCommands) AddMonetizationToAuthor(ctx context.Context, authorID uint, monetizationID uint) error {
	if authorID == 0 || monetizationID == 0 {
		return errors.New("invalid author ID or monetization ID")
	}
	log.FromContext(ctx).With("author_id", authorID).With("monetization_id", monetizationID).Debug("Adding monetization to author")
	return c.repo.AddMonetizationToAuthor(ctx, authorID, monetizationID)
}

func (c *MonetizationCommands) RemoveMonetizationFromAuthor(ctx context.Context, authorID uint, monetizationID uint) error {
	if authorID == 0 || monetizationID == 0 {
		return errors.New("invalid author ID or monetization ID")
	}
	log.FromContext(ctx).With("author_id", authorID).With("monetization_id", monetizationID).Debug("Removing monetization from author")
	return c.repo.RemoveMonetizationFromAuthor(ctx, authorID, monetizationID)
}

func (c *MonetizationCommands) AddMonetizationToBook(ctx context.Context, bookID uint, monetizationID uint) error {
	if bookID == 0 || monetizationID == 0 {
		return errors.New("invalid book ID or monetization ID")
	}
	log.FromContext(ctx).With("book_id", bookID).With("monetization_id", monetizationID).Debug("Adding monetization to book")
	return c.repo.AddMonetizationToBook(ctx, bookID, monetizationID)
}

func (c *MonetizationCommands) RemoveMonetizationFromBook(ctx context.Context, bookID uint, monetizationID uint) error {
	if bookID == 0 || monetizationID == 0 {
		return errors.New("invalid book ID or monetization ID")
	}
	log.FromContext(ctx).With("book_id", bookID).With("monetization_id", monetizationID).Debug("Removing monetization from book")
	return c.repo.RemoveMonetizationFromBook(ctx, bookID, monetizationID)
}

func (c *MonetizationCommands) AddMonetizationToPublisher(ctx context.Context, publisherID uint, monetizationID uint) error {
	if publisherID == 0 || monetizationID == 0 {
		return errors.New("invalid publisher ID or monetization ID")
	}
	log.FromContext(ctx).With("publisher_id", publisherID).With("monetization_id", monetizationID).Debug("Adding monetization to publisher")
	return c.repo.AddMonetizationToPublisher(ctx, publisherID, monetizationID)
}

func (c *MonetizationCommands) RemoveMonetizationFromPublisher(ctx context.Context, publisherID uint, monetizationID uint) error {
	if publisherID == 0 || monetizationID == 0 {
		return errors.New("invalid publisher ID or monetization ID")
	}
	log.FromContext(ctx).With("publisher_id", publisherID).With("monetization_id", monetizationID).Debug("Removing monetization from publisher")
	return c.repo.RemoveMonetizationFromPublisher(ctx, publisherID, monetizationID)
}

func (c *MonetizationCommands) AddMonetizationToSource(ctx context.Context, sourceID uint, monetizationID uint) error {
	if sourceID == 0 || monetizationID == 0 {
		return errors.New("invalid source ID or monetization ID")
	}
	log.FromContext(ctx).With("source_id", sourceID).With("monetization_id", monetizationID).Debug("Adding monetization to source")
	return c.repo.AddMonetizationToSource(ctx, sourceID, monetizationID)
}

func (c *MonetizationCommands) RemoveMonetizationFromSource(ctx context.Context, sourceID uint, monetizationID uint) error {
	if sourceID == 0 || monetizationID == 0 {
		return errors.New("invalid source ID or monetization ID")
	}
	log.FromContext(ctx).With("source_id", sourceID).With("monetization_id", monetizationID).Debug("Removing monetization from source")
	return c.repo.RemoveMonetizationFromSource(ctx, sourceID, monetizationID)
}
