package task

import (
	"context"
	"errors"
	"fmt"
	"go.uber.org/zap"
	"gorm.io/gorm"
	"log-server/global"
	"log-server/model/common/request"
	"log-server/model/task"
	"log-server/service/cache"
	"strings"
	"time"
)

type UrgentTaskService struct {
}

func (s *UrgentTaskService) CreateUrgentTask(task1 task.UrgentTaskConf) (err error) {
	//根据平均期望，将故障较大的放前面可以减少查询次数。那么需要先查是否有task_id以及create_date相等的
	var urgentEntity task.UrgentTaskConf
	var centralEntity task.CentralControlConf
	date := time.Now().Format("2006-01-02")
	task1.CreateDate = date
	err = global.GVA_DB.Model(&task.UrgentTaskConf{}).Where("task_id = ? and create_date = ?", task1.TaskId, date).First(&urgentEntity).Error
	if !errors.Is(err, gorm.ErrRecordNotFound) {
		return errors.New("任务已存在，请勿重复添加")
	}
	//查找中控配置是否存在
	err = global.GVA_DB.Model(&task.CentralControlConf{}).Where("task_id", task1.TaskId).First(&centralEntity).Error
	//若记录不存在，则报错返回
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return errors.New("请先添加此任务中控配置")
	}
	//创建紧急任务
	err = global.GVA_DB.Model(&task.UrgentTaskConf{}).Omit("create_time", "update_time").Create(&task1).Error
	if err != nil {
		return err
	}
	codeSplit := strings.Split(task1.PcCode, ",")
	ctx := context.Background()
	for _, code := range codeSplit {
		key := fmt.Sprintf(cache.TemporaryTaskPcCode, date, code)
		global.GVA_REDIS.Set(ctx, key, task1.TaskId, time.Hour*6)
	}
	return
}

func (s *UrgentTaskService) DeleteUrgentTask(task1 task.UrgentTaskConf) (err error) {
	//查找此任务是否存在
	var entity task.UrgentTaskConf
	err = global.GVA_DB.Model(&task.UrgentTaskConf{}).Where("id", task1.Id).First(&entity).Error
	if errors.Is(err, gorm.ErrRecordNotFound) {
		return errors.New("此任务不存在")
	}
	err = global.GVA_DB.Model(&task.UrgentTaskConf{}).Delete(&entity).Error
	if err != nil {
		return err
	}
	codeSplit := strings.Split(entity.PcCode, ",")
	date := entity.CreateDate[:10]
	ctx := context.Background()
	for _, code := range codeSplit {
		key := fmt.Sprintf(cache.TemporaryTaskPcCode, date, code)
		global.GVA_REDIS.Del(ctx, key)
	}
	return
}

//批量删除
func (s *UrgentTaskService) DeleteUrgentTaskByIds(ids []int) (err error) {
	err = global.GVA_DB.Model(&task.UrgentTaskConf{}).Delete("id in ?", ids).Error
	return err
}

func (s *UrgentTaskService) UpdateUrgentTask(task1 task.UrgentTaskConf) (err error) {
	//查找此task_id是否存在，如果存在不更新，否则更新
	var entity task.UrgentTaskConf
	err = global.GVA_DB.Model(&task.UrgentTaskConf{}).Where("task_id = ? and id != ? and create_date = ?", task1.TaskId, task1.Id, task1.CreateDate).First(&entity).Error
	if !errors.Is(err, gorm.ErrRecordNotFound) {
		return errors.New("已存在此task_id的任务，更新失败")
	}
	err = global.GVA_DB.Model(&task.UrgentTaskConf{}).Where("id", task1.Id).Updates(&task1).Error
	if err != nil {
		return err
	}
	date := entity.CreateDate[:10]
	if entity.PcCode != task1.PcCode {
		codeSplit := strings.Split(entity.PcCode, ",")
		ctx := context.Background()
		for _, code := range codeSplit {
			key := fmt.Sprintf(cache.TemporaryTaskPcCode, date, code)
			global.GVA_REDIS.Del(ctx, key)
		}
		upCodeSplit := strings.Split(task1.PcCode, ",")
		for _, upCode := range upCodeSplit {
			key := fmt.Sprintf(cache.TemporaryTaskPcCode, date, upCode)
			global.GVA_REDIS.Set(ctx, key, task1.TaskId, time.Hour*6)
		}
	}
	return
}

func (s *UrgentTaskService) GetUrgentTaskById(id int) (task1 task.UrgentTaskConf, err error) {
	err = global.GVA_DB.Model(&task.UrgentTaskConf{}).Where("id", id).First(&task1).Error
	return task1, err
}

//查询空闲租机
func (s *UrgentTaskService) GetUnusedPc() (unusedPcList []task.UnusedPc, err error) {
	//获取当日日期
	date := time.Now().Format("2006-01-02")
	db := global.GVA_DB.Table("computer_status").Where("status = ? and create_date = ?", -1, date)
	pcCodes, err := s.GetTemporaryTaskId(date)
	if pcCodes != "" {
		db.Not("pc_code", strings.Split(pcCodes, ","))
	}
	err = db.Order("pc_code").Find(&unusedPcList).Error
	return unusedPcList, err
}

func (s *UrgentTaskService) GetTemporaryTaskId(date string) (pcCodes string, err error) {
	var urgentTaskConf []task.UrgentTaskConf
	err = global.GVA_DB.Model(&task.UrgentTaskConf{}).Where("create_date = ?", date).Find(&urgentTaskConf).Error
	if len(urgentTaskConf) == 0 {
		return pcCodes, errors.New("没有任务数据")
	}
	for _, conf := range urgentTaskConf {
		pcCodes += conf.PcCode + ","
	}
	pcCodes = strings.Trim(pcCodes, ",")
	return
}

//获取紧急任务列表
func (s *UrgentTaskService) GetUrgentTaskList(conf task.UrgentTaskConfRequest, info request.PageInfo, order string, desc bool) (confList []task.UrgentTaskConf, total int64, err error) {
	limit := info.PageSize
	offset := info.PageSize * (info.Page - 1)
	db := global.GVA_DB.Model(&task.UrgentTaskConf{})
	startDate := time.Now().Format("2006-01-02")
	endDate := time.Now().Format("2006-01-02")
	if len(conf.Date) == 2 {
		startDate = conf.Date[0]
		endDate = conf.Date[1]
	}
	//筛选日期
	db = db.Where("create_date >= ? and create_date <= ?", startDate, endDate)
	if conf.TaskId != 0 {
		db = db.Where("task_id = ?", conf.TaskId)
	}
	err = db.Count(&total).Error
	if err != nil {
		return confList, total, err
	} else {
		db = db.Limit(limit).Offset(offset)
		if order != "" {
			var OrderStr string
			// 设置有效排序key 防止sql注入
			// 感谢 Tom4t0 提交漏洞信息
			orderMap := make(map[string]bool, 4)
			orderMap["task_id"] = true
			orderMap["create_date"] = true
			orderMap["create_time"] = true
			orderMap["update_time"] = true
			if orderMap[order] {
				if desc {
					OrderStr = order + " desc"
				} else {
					OrderStr = order
				}
			} else { // didn't matched any order key in `orderMap`
				global.GVA_LOG.Error("获取失败!", zap.Error(err))
				return confList, total, err
			}
			err = db.Order(OrderStr).Find(&confList).Error
		} else {
			err = db.Order("id desc").Find(&confList).Error
		}
	}
	//遍历更改日期格式
	for i, _ := range confList {
		confList[i].CreateDate = confList[i].CreateDate[:10]
	}
	return confList, total, err
}
