package model

import (
	"time"

	"git.jiaxianghudong.com/go/logs"
	"git.jiaxianghudong.com/webs/pkg/dbx"
	"git.jiaxianghudong.com/webs/pkg/rds"
	"golang.org/x/sync/singleflight"
)

type ChangeLog struct {
	Id         int    `json:"id" sql:"id"`
	GameId     int    `json:"game_id" sql:"game_id"`
	Tab        string `json:"tab" sql:"tab"`
	Name       string `json:"name" sql:"name"`
	Version    int    `json:"version" sql:"version"`
	ChangeLogs []ChangeLogContent
}

type ChangeLogContent struct {
	Id         int    `json:"id" sql:"id"`
	LogId      int    `json:"log_id" sql:"log_id"`
	Content    string `json:"content" sql:"content"`
	UpdateTime int64  `json:"update_time" sql:"update_time"`
}

var (
	changelogVersion = -1
	changelogSF      singleflight.Group
	changelogs       []ChangeLog
)

func getChangeLogs() []ChangeLog {
	v, err, _ := changelogSF.Do("changelog", func() (interface{}, error) {
		version, err := rds.Redis8.Get("game_rule:changelog:version").Int()
		if err != nil {
			logs.Errorf("Get game_rule:changelog:version failed,err:%v", err)
		}
		if version == changelogVersion {
			return changelogs, nil
		}
		var logs []ChangeLog
		if err = dbx.MySQLExt.Query2("SELECT id,game_id,tab,name,version FROM `ext`.`changelog`", &logs); err != nil {
			return nil, err
		}
		var logIdMap = map[int]*ChangeLog{}
		for i := range logs {
			logIdMap[logs[i].Id] = &logs[i]
		}

		var logContents []ChangeLogContent
		if err = dbx.MySQLExt.Query2("SELECT id,log_id,content,UNIX_TIMESTAMP(update_time)update_time FROM `ext`.`changelog_content` order BY update_time DESC,id desc ", &logContents); err != nil {
			return nil, err
		}
		for _, content := range logContents {
			logIdMap[content.LogId].ChangeLogs = append(logIdMap[content.LogId].ChangeLogs, content)
		}
		changelogs = logs
		changelogVersion = version
		return changelogs, nil
	})
	if err != nil {
		logs.Errorf("getChangeLogs failed,err:%v", err)
	}
	return v.([]ChangeLog)
}

func GetAllChangeLogVersionInfo() (infos []map[string]interface{}) {
	now := time.Now().Unix()
	for _, log := range getChangeLogs() {
		var updateTime int64
		for _, c := range log.ChangeLogs {
			if c.UpdateTime > now {
				continue
			}
			if updateTime < c.UpdateTime {
				updateTime = c.UpdateTime
			}
		}
		infos = append(infos, map[string]interface{}{
			"game_id":     log.GameId,
			"tab":         log.Tab,
			"version":     log.Version,
			"update_time": updateTime,
		})
	}
	return
}

func GetChangeLog(gameId int, tab string) (contents []string) {
	now := time.Now().Unix()
	for _, log := range getChangeLogs() {
		if log.GameId != gameId || log.Tab != tab {
			continue
		}
		for _, content := range log.ChangeLogs {
			if content.UpdateTime > now {
				continue
			}
			contents = append(contents, content.Content)
		}
	}
	return
}
