package domain

import (
	"errors"
	"sort"
	"strings"
	"time"
)

type TaskState int

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

func (t TaskState) Named() string {
	switch t {
	case TaskWait:
		return "待启动"
	case TaskRunning:
		return "启动中"
	case TaskStop:
		return "停止"
	}
	return ""
}

type TaskWarnFlag int

const (
	TaskWarnNull TaskWarnFlag = 0
	TaskWarn     TaskWarnFlag = 1
)

type TaskSortBy int

const (
	TaskSortHight  TaskSortBy = 100
	TaskSortMiddle TaskSortBy = 200
	TaskSortLow    TaskSortBy = 300
	TaskSortNull   TaskSortBy = 400
)

func (t TaskSortBy) Named() string {
	switch t {
	case TaskSortHight:
		return "高"
	case TaskSortMiddle:
		return "中"
	case TaskSortLow:
		return "低"
	case TaskSortNull:
		return "无"
	}
	return ""
}

// 任务
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"`     // 字段表示的意义变更; 原来 (“优先级名称“)=> 现在 (“任务类型“)
	SortBy        TaskSortBy `json:"sortBy"`        // 优先级排序;值越小优先级越高
	EndTime       int64      `json:"endTime"`       // 任务截止的时间戳,单位:秒;等于0时表示未设置时间
	UseEndTime    int        `json:"useEndTime"`    // 是否应用任务截止的时间;默认值0:不应用,1:应用
	RelatedUser   []int      `json:"relatedUser"`   // 相关的员工id
	RunAt         int64      `json:"runAt"`         // 启动的时间戳,单位:秒
	StopAt        int64      `json:"stopAt"`        // 停止的时间戳,单位:秒
	Anomaly       int        `json:"anomaly"`       // 异常反馈的次数
	WarnFlag      int        `json:"warnFlag"`      // 里程碑异常标记
	AssistFlag    int        `json:"assistFlag"`    // 辅导异常标记
	AssistFlagMax int        `json:"assistFlagMax"` // 辅导异常标记最大值
	CurrentStage  TaskStage  `json:"currentStage"`  // 当前执行的里程碑
	LastStage     TaskStage  `json:"lastStage"`     // 上一个完成的里程碑
	CreatedBy     int        `json:"createdBy"`     // 任务的创建方式 0: 根据模板中的任务创建,1:页面主动直接创建
}

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) SetCurrentStage(stageList []*TaskStage) {
	if len(stageList) == 0 {
		return
	}
	sort.Slice(stageList, func(i, j int) bool {
		return stageList[i].SortBy < stageList[j].SortBy
	})
	t.LastStage = TaskStage{}
	t.CurrentStage = TaskStage{}
	for _, val := range stageList {
		if val.DeletedAt != nil {
			continue
		}
		t.LastStage = t.CurrentStage
		t.CurrentStage = *val
		if val.RealCompletedAt == 0 {
			break
		}
	}
	if t.CurrentStage.RealCompletedAt > 0 {
		t.LastStage = t.CurrentStage
		t.CurrentStage = TaskStage{}
	}
}

// 设置优先级的值
func (t *Task) SetSortBy(a int) error {
	switch TaskSortBy(a) {
	case TaskSortHight, TaskSortMiddle, TaskSortLow, TaskSortNull:
	default:
		return errors.New("优先级值错误")
	}

	t.SortBy = TaskSortBy(a)
	return nil
}

func (t *Task) DescriptTaskStatus() string {
	statusNamed := ""
	if t.Status == TaskRunning {
		statusNamed = "进行中"
	}
	if t.CurrentStage.Id == 0 && t.LastStage.PlanCompletedAt < t.LastStage.RealCompletedAt {
		statusNamed = "逾期完成"
	}
	if t.CurrentStage.Id == 0 && t.LastStage.PlanCompletedAt >= t.LastStage.RealCompletedAt {
		statusNamed = "如期完成"
	}
	if t.Status == TaskStop {
		statusNamed = "已停止"
	}
	if t.WarnFlag > 0 {
		statusNamed = "里程碑异常"
	}
	if t.Anomaly > 0 {
		statusNamed = "反馈异常"
	}
	return statusNamed
}

func (t *Task) Copy() Task {
	t2 := *t
	t2.RelatedUser = make([]int, len(t.RelatedUser))
	copy(t2.RelatedUser, t.RelatedUser)
	return t2
}

// 检查每日任务是否异常,并记录异常情况
func (t *Task) CheckAndRecordAnomaly(taskRecordData *TaskRecord) {
	nowTime := time.Now().Unix()
	// 检查是否是里程碑异常
	{
		if taskRecordData.TaskStageCheck.Id > 0 {
			if taskRecordData.TaskStageCheck.RealCompletedAt == 0 && taskRecordData.TaskStageCheck.PlanCompletedAt < nowTime {
				// 超期未完成
				t.WarnFlag += 1
			} else if taskRecordData.TaskStageCheck.RealCompletedAt > 0 {
				// 里程碑完成, 重置计数
				t.WarnFlag = 0
			}
		}
	}
	// 检查反馈异常
	{
		t.Anomaly += 1
		for _, val := range taskRecordData.RemarkContent {
			txt := strings.TrimSpace(val.RemarkText)
			if len(txt) == 0 || txt == "无" {
				continue
			}
			//反馈正常,重置计数
			t.Anomaly = 0
			break
		}
	}
	// 检查辅导异常
	{
		taskRecordData.AssistContent = strings.TrimSpace(taskRecordData.AssistContent)
		if t.Anomaly == 0 && t.WarnFlag == 0 {
			//里程碑正常,反馈正常, 设定为已辅导
			t.AssistFlag = 0
		} else {
			//里程碑和反馈 其中一个不正常,记录一次辅导异常
			t.AssistFlag += 1
		}
		if taskRecordData.AssistLevel != AssistLevel1 &&
			!(taskRecordData.AssistContent == "无" || len(taskRecordData.AssistContent) == 0) {
			//只要正常填写的辅导都设定为已辅导
			t.AssistFlag = 0
		}
	}
}

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)
}