package service

import (
	"encoding/json"
	"gadmin/config"
	"gadmin/internal/admin/forms"
	"gadmin/utility/serializer"
	"github.com/gin-gonic/gin"
	"github.com/patrickmn/go-cache"
	"github.com/sirupsen/logrus"
	"net/http"
	"time"
)

type sAnnouncement struct{}

var announcementCache = cache.New(10*time.Minute, 10*time.Minute)

var Announcement = new(sAnnouncement)

var AnnouncementKey = "announcement"

type AnnouncementItem struct {
	Title     string `json:"title"`
	Content   string `json:"content"`
	CreatedAt int64  `json:"created_at"`
}

func (s *sAnnouncement) List() serializer.Response {

	var models forms.ListRes
	models.List = []*AnnouncementItem{}
	models.Page = 1

	announcementCacheStr, found := announcementCache.Get(AnnouncementKey)
	if found {
		announcementCacheItem, ok := announcementCacheStr.(*AnnouncementItem)
		if ok {
			models.PageCount = 0
			models.List = []*AnnouncementItem{announcementCacheItem}
			return serializer.Suc(models)
		}
	}
	announcementItem := new(AnnouncementItem)
	announcementStr := config.LogRedis.Get(AnnouncementKey).Val()
	if announcementStr == "" {
		models.PageCount = 0
		return serializer.Suc(models)
	}
	err := json.Unmarshal([]byte(announcementStr), announcementItem)
	if err != nil {
		return serializer.Err(1, "json.Unmarshal err", err)
	}

	announcementCache.Set(AnnouncementKey, announcementItem, -1)

	models.PageCount = 1
	models.List = []*AnnouncementItem{announcementItem}

	return serializer.Suc(models)
}

func (s *sAnnouncement) Add(req forms.AnnouncementAddReq) serializer.Response {
	announcementItem := &AnnouncementItem{
		Title:     req.Title,
		Content:   req.Content,
		CreatedAt: time.Now().Unix(),
	}
	announcementStr, err := json.Marshal(announcementItem)
	if err != nil {
		return serializer.Err(1, "json.Marshal err", err)
	}

	err = config.LogRedis.Set(AnnouncementKey, announcementStr, -1).Err()
	if err != nil {
		logrus.Errorf("log redis.Set Key:%v,Value:%v. err %v", AnnouncementKey, announcementStr, err)
	}

	announcementCache.Set(AnnouncementKey, announcementItem, -1)

	return serializer.Suc(nil)
}

func (s *sAnnouncement) Del() serializer.Response {

	err := config.LogRedis.Del(AnnouncementKey).Err()
	if err != nil {
		logrus.Errorf("log redis.Del Key:%v. err %v", AnnouncementKey, err)
		return serializer.Err(1, "redis.Del err", err)
	}

	announcementCache.Delete(AnnouncementKey)

	return serializer.Suc(nil)
}

type ResponseAnnouncement struct {
	ErrCode int               `json:"errCode"`
	Msg     string            `json:"msg,omitempty"`
	Data    *AnnouncementItem `json:"data"`
}

func Get(c *gin.Context) {
	res := &ResponseAnnouncement{}
	cacheData, ok := announcementCache.Get(AnnouncementKey)
	if ok {
		res.Data = cacheData.(*AnnouncementItem)
		c.JSON(http.StatusOK, res)
		return
	}

	announcementStr := config.LogRedis.Get(AnnouncementKey).Val()
	if announcementStr == "" {
		c.JSON(http.StatusOK, res)
		return
	}
	announcementItem := new(AnnouncementItem)
	err := json.Unmarshal([]byte(announcementStr), announcementItem)
	if err != nil {
		res.ErrCode = 1
		res.Msg = err.Error()
		c.JSON(http.StatusOK, res)
		return
	}

	announcementCache.Set(AnnouncementKey, announcementItem, -1)

	res.Data = announcementItem
	c.JSON(http.StatusOK, res)
}
