package service

import (
	"github.com/rs/zerolog"
	"netidhub-saas-be/app/database/entity"
	"netidhub-saas-be/app/module/article_nulis_ai/mapper"
	"netidhub-saas-be/app/module/article_nulis_ai/repository"
	"netidhub-saas-be/app/module/article_nulis_ai/request"
	"netidhub-saas-be/app/module/article_nulis_ai/response"
	articlesRepository "netidhub-saas-be/app/module/articles/repository"
	articles "netidhub-saas-be/app/module/articles/request"
	usersRepository "netidhub-saas-be/app/module/users/repository"
	"netidhub-saas-be/utils/paginator"

	utilSvc "netidhub-saas-be/utils/service"
)

// ArticleNulisAIService
type articleNulisAIService struct {
	Repo         repository.ArticleNulisAIRepository
	UsersRepo    usersRepository.UsersRepository
	ArticlesRepo articlesRepository.ArticlesRepository
	Log          zerolog.Logger
}

// ArticleNulisAIService define interface of IArticleNulisAIService
type ArticleNulisAIService interface {
	All(req request.ArticleNulisAIQueryRequest) (articleNulisAI []*response.ArticleNulisAIResponse, paging paginator.Pagination, err error)
	Show(id uint) (articleNulisAI *response.ArticleNulisAIResponse, err error)
	Save(req request.ArticleNulisAICreateRequest, authToken string) (articleNulisAI *entity.ArticleNulisAI, err error)
	Update(id uint, req request.ArticleNulisAIUpdateRequest) (err error)
	Publish(req request.ArticleNulisAICreateRequest, authToken string) (err error)
	Delete(id uint) error
}

// NewArticleNulisAIService init ArticleNulisAIService
func NewArticleNulisAIService(repo repository.ArticleNulisAIRepository, log zerolog.Logger, usersRepo usersRepository.UsersRepository, articlesRepo articlesRepository.ArticlesRepository) ArticleNulisAIService {

	return &articleNulisAIService{
		Repo:         repo,
		Log:          log,
		UsersRepo:    usersRepo,
		ArticlesRepo: articlesRepo,
	}
}

// All implement interface of ArticleNulisAIService
func (_i *articleNulisAIService) All(req request.ArticleNulisAIQueryRequest) (articleNulisAIs []*response.ArticleNulisAIResponse, paging paginator.Pagination, err error) {
	results, paging, err := _i.Repo.GetAll(req)
	if err != nil {
		return
	}

	for _, result := range results {
		articleNulisAIs = append(articleNulisAIs, mapper.ArticleNulisAIResponseMapper(result))
	}

	return
}

func (_i *articleNulisAIService) Show(id uint) (articleNulisAI *response.ArticleNulisAIResponse, err error) {
	result, err := _i.Repo.FindOne(id)
	if err != nil {
		return nil, err
	}

	return mapper.ArticleNulisAIResponseMapper(result), nil
}

func (_i *articleNulisAIService) Save(req request.ArticleNulisAICreateRequest, authToken string) (articleNulisAI *entity.ArticleNulisAI, err error) {
	_i.Log.Info().Interface("data", req).Msg("")

	newReq := req.ToEntity()

	createdBy := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)
	newReq.CreatorId = createdBy.ID

	return _i.Repo.Create(newReq)
}

func (_i *articleNulisAIService) Publish(req request.ArticleNulisAICreateRequest, authToken string) (err error) {
	_i.Log.Info().Interface("data", req).Msg("")

	newReq := req.ToEntity()
	articleReq := articles.ArticlesCreateRequest{
		Title:           newReq.Title,
		Slug:            utilSvc.MakeSlug(req.Title),
		Tags:            newReq.Tags,
		TypeId:          1,
		Description:     newReq.Description,
		HtmlDescription: newReq.HtmlDescription,
	}

	createdBy := utilSvc.GetUserInfo(_i.Log, _i.UsersRepo, authToken)

	newArticleReq := articleReq.ToEntity()
	newArticleReq.CreatedById = &createdBy.ID

	_, err = _i.ArticlesRepo.Create(nil, newArticleReq)
	if err != nil {
		return err
	} else {
		return nil
	}
}

func (_i *articleNulisAIService) Update(id uint, req request.ArticleNulisAIUpdateRequest) (err error) {
	_i.Log.Info().Interface("data", req).Msg("")
	return _i.Repo.Update(id, req.ToEntity())
}

func (_i *articleNulisAIService) Delete(id uint) error {
	result, err := _i.Repo.FindOne(id)
	if err != nil {
		return err
	}

	result.IsActive = false
	return _i.Repo.Update(id, result)
}
