package service

import (
	"campaign-pool-be/app/database/entity"
	"campaign-pool-be/app/module/campaign_destinations/mapper"
	"campaign-pool-be/app/module/campaign_destinations/repository"
	"campaign-pool-be/app/module/campaign_destinations/request"
	"campaign-pool-be/app/module/campaign_destinations/response"
	usersRepository "campaign-pool-be/app/module/users/repository"
	config "campaign-pool-be/config/config"
	"campaign-pool-be/utils/paginator"
	utilSvc "campaign-pool-be/utils/service"

	"github.com/rs/zerolog"
)

// CampaignDestinationsService
type campaignDestinationsService struct {
	Repo      repository.CampaignDestinationsRepository
	UsersRepo usersRepository.UsersRepository
	Log       zerolog.Logger
	Cfg       *config.Config
}

// CampaignDestinationsService define interface of ICampaignDestinationsService
type CampaignDestinationsService interface {
	All(req request.CampaignDestinationsQueryRequest, authToken string) (campaignDestinations []*response.CampaignDestinationsResponse, paging paginator.Pagination, err error)
	Show(id uint) (campaignDestinations *response.CampaignDestinationsResponse, err error)
	Save(req request.CampaignDestinationsCreateRequest, authToken string) (campaignDestinations *entity.CampaignDestinations, err error)
	Update(id uint, req request.CampaignDestinationsUpdateRequest) (err error)
	Delete(id uint) error
}

// NewCampaignDestinationsService init CampaignDestinationsService
func NewCampaignDestinationsService(repo repository.CampaignDestinationsRepository, usersRepo usersRepository.UsersRepository, log zerolog.Logger, cfg *config.Config) CampaignDestinationsService {
	return &campaignDestinationsService{
		Repo:      repo,
		UsersRepo: usersRepo,
		Log:       log,
		Cfg:       cfg,
	}
}

// All implement interface of CampaignDestinationsService
func (_i *campaignDestinationsService) All(req request.CampaignDestinationsQueryRequest, authToken string) (campaignDestinationss []*response.CampaignDestinationsResponse, paging paginator.Pagination, err error) {
	results, paging, err := _i.Repo.GetAll(req)
	if err != nil {
		return
	}

	for _, result := range results {
		campaignDestinationss = append(campaignDestinationss, mapper.CampaignDestinationsResponseMapper(result))
	}

	return
}

func (_i *campaignDestinationsService) Show(id uint) (campaignDestinations *response.CampaignDestinationsResponse, err error) {
	result, err := _i.Repo.FindOne(id)
	if err != nil {
		return nil, err
	}
	return mapper.CampaignDestinationsResponseMapper(result), nil
}

func (_i *campaignDestinationsService) Save(req request.CampaignDestinationsCreateRequest, authToken string) (campaignDestinations *entity.CampaignDestinations, err error) {
	_i.Log.Info().Interface("data", req).Msg("")
	newReq := req.ToEntity()

	if req.CreatedById != nil {
		createdBy, err := _i.UsersRepo.FindOne(*req.CreatedById)
		if err != nil {
			return nil, err
		}
		_ = createdBy
	} else {
		createdBy := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
		_ = createdBy
	}

	return _i.Repo.Create(newReq)
}

func (_i *campaignDestinationsService) Update(id uint, req request.CampaignDestinationsUpdateRequest) (err error) {
	_i.Log.Info().Interface("data", req).Msg("")

	newReq := req.ToEntity()
	return _i.Repo.Update(id, newReq)
}

func (_i *campaignDestinationsService) Delete(id uint) error {
	return _i.Repo.Delete(id)
}

