package jobs

import (
	"encoding/json"
	"fmt"
	"gadmin/config"
	model2 "gadmin/internal/gorm/model"
	"gadmin/internal/gorm/query"
	"github.com/sirupsen/logrus"
	"gorm.io/gorm"
)

var OldGuide = new(jOldGuide)

type jOldGuide struct{}

var GuideLimit map[int64][]int64

func (j *jOldGuide) Run() {
	logrus.Info("OldGuide Run.....")
	j.loadGuideLimit()
	j.screen()
	j.saveGuide()
}

func (j *jOldGuide) loadGuideLimit() {
	GuideLimit = make(map[int64][]int64)
	//GuideLimit[1] = []int64{11,21, 31, 71, 51, 81} //
	GuideLimit[2] = []int64{11, 21, 41}
	GuideLimit[3] = []int64{11, 21, 41, 91, 61, 161}
	GuideLimit[4] = []int64{11, 21, 41, 91, 61, 131, 111, 161}
	GuideLimit[5] = []int64{11, 21, 41, 91, 61, 131, 171, 111, 161, 241}
	GuideLimit[6] = []int64{11, 21, 41, 91, 61, 131, 171, 251, 111, 161, 241}
	GuideLimit[7] = []int64{11, 21, 41, 91, 61, 131, 171, 251, 173, 201, 111, 161, 241}
	GuideLimit[8] = []int64{11, 21, 41, 91, 61, 131, 171, 251, 173, 201, 111, 161, 181, 211, 241}
	GuideLimit[9] = []int64{11, 21, 41, 91, 61, 131, 171, 251, 173, 201, 111, 161, 181, 221, 231, 211, 241}
	GuideLimit[10] = []int64{11, 21, 41, 91, 61, 131, 171, 251, 173, 201, 111, 161, 181, 221, 231, 211, 241}
	GuideLimit[11] = []int64{11, 21, 41, 91, 61, 131, 171, 251, 173, 201, 111, 161, 181, 221, 231, 211, 241}
	GuideLimit[12] = []int64{11, 21, 41, 91, 61, 131, 171, 251, 173, 201, 111, 161, 181, 221, 231, 211, 65, 261, 241}
	GuideLimit[13] = []int64{11, 21, 41, 91, 61, 131, 171, 251, 173, 201, 111, 161, 181, 221, 231, 151, 370, 211, 65, 261, 241, 271}
	GuideLimit[14] = []int64{11, 21, 41, 91, 61, 131, 171, 251, 173, 201, 111, 161, 181, 221, 231, 151, 370, 211, 65, 261, 241, 271}
	GuideLimit[15] = []int64{11, 21, 41, 91, 61, 131, 171, 251, 173, 201, 111, 161, 181, 221, 231, 151, 370, 211, 64, 291, 65, 261, 241, 271}
	GuideLimit[16] = []int64{11, 21, 41, 91, 61, 131, 171, 251, 173, 201, 111, 161, 181, 221, 231, 151, 370, 211, 64, 291, 65, 261, 241, 271}
	GuideLimit[17] = []int64{11, 21, 41, 91, 61, 131, 171, 251, 173, 201, 111, 161, 181, 221, 231, 151, 370, 211, 64, 291, 65, 261, 241, 271}
	GuideLimit[18] = []int64{11, 21, 41, 91, 61, 131, 171, 251, 173, 201, 111, 161, 181, 221, 231, 151, 370, 211, 64, 291, 65, 261, 241, 271}
	GuideLimit[19] = []int64{11, 21, 41, 91, 61, 131, 171, 251, 173, 201, 111, 161, 181, 221, 231, 151, 370, 211, 64, 291, 65, 261, 241, 271}
	GuideLimit[20] = []int64{11, 21, 41, 91, 61, 131, 171, 251, 173, 201, 111, 161, 181, 221, 231, 151, 370, 211, 64, 291, 65, 261, 241, 271}
}

// screen 将全表数据整理成倒排规则，再以规则作为条件批量更新
func (j *jOldGuide) screen() {
	type Getter struct {
		Total int64  `json:"total"`
		Task  string `json:"task"`
	}

	var (
		results   []*Getter
		levels    = []int64{2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20} // 1,
		levelSql  = "SELECT COUNT(*) AS `total`, `task` FROM `player_task` LEFT JOIN player_attr ON player_task.playerid = player_attr.playerid WHERE player_attr.level = ? GROUP BY `task` ORDER BY `total` DESC"
		handleSql = `update player_task t, player_attr a set t.task = '%s' where t.playerid = a.playerid and a.level = %d and t.task = '%s'`
	)

	handle := func(level int64, oldTask string) {
		change, task := j.inspect(level, oldTask)
		if !change {
			return
		}
		newSql := fmt.Sprintf(handleSql, task, level, oldTask)
		logrus.Warningf("newSql:%v", newSql)
		db := config.GDB1.Exec(newSql)
		if db.Error != nil {
			logrus.Panicf("screen handle Exec err:%+v", db.Error)
		}
	}

	for _, level := range levels {
		config.GDB1.Raw(levelSql, level).Scan(&results)
		if len(results) > 0 {
			for _, result := range results {
				handle(level, result.Task)
			}
		}
	}
}

// saveGuide 遍历更新
func (j *jOldGuide) saveGuide() {

	type Ret struct {
		Playerid int64  `json:"playerid"`
		Level    int64  `json:"level"`
		Task     string `json:"task"`
	}
	var (
		results []*Ret
		t       = query.Use(config.GDB1).PlayerTask
	)

	config.GDB1.Model(&model2.PlayerTask{}).
		Select("player_task.playerid,player_task.task,player_attr.level").
		Joins("LEFT JOIN player_attr ON player_task.playerid = player_attr.playerid").
		//Where("player_task.playerid = 206").
		FindInBatches(&results, 3000, func(tx *gorm.DB, batch int) error {
			for _, result := range results {
				if result.Level <= 1 || result.Level > 20 {
					continue
				}
				change, task := j.inspect(result.Level, result.Task)
				if !change {
					continue
				}

				if _, err := query.Use(config.GDB1).PlayerTask.
					Where(t.Playerid.Eq(result.Playerid)).
					Updates(&model2.PlayerTask{Task: task}); err != nil {
					panic(err)
				}
			}
			return nil
		})

	logrus.Println("update finished")
}

// inspect 检查是否需要更新
func (j *jOldGuide) inspect(level int64, task string) (bool, string) {
	var (
		guide  map[int64]struct{}
		change bool
		err    error
	)

	if err = json.Unmarshal([]byte(task), &guide); err != nil {
		panic(err)
	}

	// 获取限制引导
	limits := GuideLimit[level]

	// 检查是否有需要添加的引导
	for _, limit := range limits {
		_, ok := guide[limit]
		if !ok {
			change = true
			guide[limit] = struct{}{}
		}
	}

	if change {
		newTask, err := json.Marshal(guide)
		if err != nil {
			panic(err)
		}
		return change, string(newTask)
	}

	return false, ""
}
