package handler

import (
	"git.dmitriygnatenko.ru/dima/go-common/db"
	"git.dmitriygnatenko.ru/dima/go-common/logger"
	"github.com/gofiber/fiber/v2"

	customErrors "git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/helper/errors"
	"git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/mapper"
	"git.dmitriygnatenko.ru/dima/dmitriygnatenko-v2/internal/service/i18n"
)

const (
	TagCacheKey = "tag"
	tagParam    = "tag"
)

type tagPage struct {
	cacheService      CacheService
	articleRepository ArticleRepository
	tagRepository     TagRepository
}

func NewTagPageHandler(
	cacheService CacheService,
	articleRepository ArticleRepository,
	tagRepository TagRepository,
) fiber.Handler {
	h := tagPage{
		cacheService:      cacheService,
		articleRepository: articleRepository,
		tagRepository:     tagRepository,
	}

	return h.handler()
}

func (h *tagPage) handler() fiber.Handler {
	return func(fctx *fiber.Ctx) error {
		ctx := fctx.Context()
		url := fctx.Params(tagParam)
		lang := i18n.LanguageFromContext(fctx)
		cacheKey := TagCacheKey + url + string(lang)

		renderData, found := h.cacheService.Get(cacheKey)
		if !found {
			tag, err := h.tagRepository.GetByURL(ctx, url)
			if err != nil {
				if db.IsNotFoundError(err) {
					return fiber.ErrNotFound
				}

				logger.Error(ctx, customErrors.Wrap(err, "tag page: can't get tag").Error())
				return err
			}

			articleModels, err := h.articleRepository.GetPreviewByTagID(
				ctx,
				tag.ID,
				i18n.LanguageID(lang),
			)
			if err != nil {
				logger.Error(ctx, customErrors.Wrap(err, "tag page: can't get articles").Error())
				return err
			}

			renderData = fiber.Map{
				"lang":            lang,
				"headTitle":       i18n.T(lang, "head_title"),
				"pageTitle":       i18n.T(lang, "tag_page_title", tag.Tag),
				"headDescription": i18n.T(lang, "tag_page_desc", tag.Tag),
				"headKeywords":    i18n.T(lang, "tag_page_keywords", tag.Tag),
				"articles":        mapper.ToArticlesPreview(lang, articleModels),
			}

			h.cacheService.Set(cacheKey, renderData, nil)
		}

		return fctx.Render("tag", renderData, "_layout")
	}
}
