package domain

import (
	"sort"
	"time"
)

type TaskState int

const (
	TaskWait    TaskState = 1 //任务待启动
	TaskRunning TaskState = 2 //任务启动中
	TaskStop    TaskState = 3 //任务停止
)

type TaskWarnFlag int

const (
	TaskWarnNull TaskWarnFlag = 0
	TaskWarn     TaskWarnFlag = 1
)

// 任务
type Task struct {
	Id           int          `json:"id"`
	CreatedAt    time.Time    `json:"createdAt"`
	UpdatedAt    time.Time    `json:"updatedAt"`
	DeletedAt    *time.Time   `json:"deletedAt"`
	CompanyId    int          `json:"companyId,string"`
	Name         string       `json:"name"`         // 任务名称
	Alias        string       `json:"alias"`        // 任务别名
	Leader       TaskLeader   `json:"leader"`       // 任务负责人
	Status       TaskState    `json:"status"`       // 任务的状态
	Level        int          `json:"level"`        // 优先级,值越小优先级越高
	LevelName    string       `json:"levelName"`    // 优先级名称
	RelatedUser  []int        `json:"relatedUser"`  // 相关的员工id
	RunAt        int64        `json:"runAt"`        // 启动的时间戳,秒
	StopAt       int64        `json:"stopAt"`       // 停止的时间戳,秒
	Anomaly      int          `json:"anomaly"`      // 异常反馈的次数
	WarnFlag     TaskWarnFlag `json:"warnFlag"`     // 里程碑异常标记
	CurrentStage TaskStage    `json:"currentStage"` // 当前执行的里程碑
	LastStage    TaskStage    `json:"lastStage"`    // 上一个完成的里程碑
}

type TaskLeader struct {
	Id      int64  `json:"id,string"` // 用户Id
	Account string `json:"account"`   // 用户账号
	Name    string `json:"name"`      // 用户姓名
}

// 设置任务的优先级
// 值越小优先级越高,不是预定义的任务优先级,排在最后
func (t *Task) ApplyLevelName(name string) {
	t.LevelName = name
	switch name {
	case "战略任务":
		t.Level = 100
	case "重点任务":
		t.Level = 200
	case "常规任务":
		t.Level = 300
	default:
		t.Level = 9999
	}
}

// StatusDescript
func (t *Task) StatusDescription() string {
	switch t.Status {
	case TaskWait:
		return "待启动"
	case TaskRunning:
		return "启动中"
	case TaskStop:
		return "停止"
	}
	return ""
}

// 记录待执行的里程碑,和上一个执行的里程碑
func (t *Task) SetCurrentStage(stageList []*TaskStage) {
	sort.Slice(stageList, func(i, j int) bool {
		return stageList[i].SortBy < stageList[j].SortBy
	})
	t.CurrentStage = TaskStage{}
	for _, val := range stageList {
		if val.DeletedAt != nil {
			continue
		}
		t.LastStage = t.CurrentStage
		t.CurrentStage = *val
		if val.RealCompletedAt == 0 {
			break
		}
	}
}

type TaskRepository interface {
	Save(param *Task) error
	Remove(id int) error
	FindOne(queryOptions map[string]interface{}) (*Task, error)
	Find(queryOptions map[string]interface{}) (int, []*Task, error)
}