package service

import (
	"errors"
	"narasi-ahli-be/app/database/entity"
	"narasi-ahli-be/app/module/ebooks/mapper"
	"narasi-ahli-be/app/module/ebooks/repository"
	"narasi-ahli-be/app/module/ebooks/response"
	usersRepository "narasi-ahli-be/app/module/users/repository"
	"narasi-ahli-be/utils/paginator"
	utilSvc "narasi-ahli-be/utils/service"

	"github.com/rs/zerolog"
)

// EbookWishlistsService
type ebookWishlistsService struct {
	Repo       repository.EbookWishlistsRepository
	EbooksRepo repository.EbooksRepository
	Log        zerolog.Logger
	UsersRepo  usersRepository.UsersRepository
}

// EbookWishlistsService define interface of IEbookWishlistsService
type EbookWishlistsService interface {
	GetByUserId(authToken string, pagination *paginator.Pagination) (wishlists []*response.EbookWishlistResponse, paging paginator.Pagination, err error)
	AddToWishlist(authToken string, ebookId uint) (err error)
	RemoveFromWishlist(authToken string, ebookId uint) (err error)
	IsInWishlist(authToken string, ebookId uint) (isInWishlist bool, err error)
}

// NewEbookWishlistsService init EbookWishlistsService
func NewEbookWishlistsService(
	repo repository.EbookWishlistsRepository,
	ebooksRepo repository.EbooksRepository,
	log zerolog.Logger,
	usersRepo usersRepository.UsersRepository) EbookWishlistsService {

	return &ebookWishlistsService{
		Repo:       repo,
		EbooksRepo: ebooksRepo,
		Log:        log,
		UsersRepo:  usersRepo,
	}
}

// GetByUserId implement interface of EbookWishlistsService
func (_i *ebookWishlistsService) GetByUserId(authToken string, pagination *paginator.Pagination) (wishlists []*response.EbookWishlistResponse, paging paginator.Pagination, err error) {
	user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
	if user == nil {
		return nil, paginator.Pagination{}, errors.New("user not found")
	}

	wishlistsData, paging, err := _i.Repo.GetByUserId(user.ID, pagination)
	if err != nil {
		return nil, paging, err
	}

	wishlists = mapper.ToEbookWishlistResponseList(wishlistsData)

	return wishlists, paging, nil
}

// AddToWishlist implement interface of EbookWishlistsService
func (_i *ebookWishlistsService) AddToWishlist(authToken string, ebookId uint) (err error) {
	user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
	if user == nil {
		return errors.New("user not found")
	}

	// Check if ebook exists
	_, err = _i.EbooksRepo.FindOne(ebookId)
	if err != nil {
		return errors.New("ebook not found")
	}

	// Check if already in wishlist
	existingWishlist, err := _i.Repo.FindByUserAndEbook(user.ID, ebookId)
	if err == nil && existingWishlist != nil {
		return errors.New("ebook already in wishlist")
	}

	// Add to wishlist
	wishlist := &entity.EbookWishlists{
		UserId:  user.ID,
		EbookId: ebookId,
	}

	_, err = _i.Repo.Create(wishlist)
	if err != nil {
		return err
	}

	// Update wishlist count
	err = _i.EbooksRepo.UpdateWishlistCount(ebookId)
	if err != nil {
		_i.Log.Error().Err(err).Msg("Failed to update wishlist count")
	}

	return nil
}

// RemoveFromWishlist implement interface of EbookWishlistsService
func (_i *ebookWishlistsService) RemoveFromWishlist(authToken string, ebookId uint) (err error) {
	user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
	if user == nil {
		return errors.New("user not found")
	}

	// Check if in wishlist
	existingWishlist, err := _i.Repo.FindByUserAndEbook(user.ID, ebookId)
	if err != nil || existingWishlist == nil {
		return errors.New("ebook not in wishlist")
	}

	// Remove from wishlist
	err = _i.Repo.Delete(existingWishlist.ID)
	if err != nil {
		return err
	}

	return nil
}

// IsInWishlist implement interface of EbookWishlistsService
func (_i *ebookWishlistsService) IsInWishlist(authToken string, ebookId uint) (isInWishlist bool, err error) {
	user := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
	if user == nil {
		return false, errors.New("user not found")
	}

	existingWishlist, err := _i.Repo.FindByUserAndEbook(user.ID, ebookId)
	if err != nil {
		return false, nil // Not in wishlist
	}

	return existingWishlist != nil, nil
}
