package Task

import (
	"ColdVerify_server/conf"
	"ColdVerify_server/lib"
	"ColdVerify_server/logs"
	"encoding/json"
	"fmt"
	"github.com/astaxie/beego/cache"
	"github.com/beego/beego/v2/adapter/orm"
	orm2 "github.com/beego/beego/v2/client/orm"
	_ "github.com/go-sql-driver/mysql"
	"time"
)

// 模板
type Task struct {
	Id                     int    `orm:"column(ID);size(11);auto;pk"`
	T_class                int    `orm:"size(200);default(0)"` // 分类id
	T_task_id              string `orm:"size(256);null"`       // 任务ID
	T_uuid                 string `orm:"size(256);null"`       // 用户 UUID
	T_name                 string `orm:"size(256);null"`       // 标题
	T_VerifyTemplate_class string `orm:"size(256);null"`       // 模板id
	T_VerifyTemplate_id    string `orm:"size(256);null"`       // 模板id
	T_deadline             string `orm:"size(256);null"`       // 截止时间
	T_scheme               string `orm:"size(256);null"`       // 实施方案 负责人UUID
	T_collection           string `orm:"size(256);null"`       // 数据采集 负责人UUID
	T_reporting            string `orm:"size(256);null"`       // 报告编写 负责人UUID
	T_delivery             string `orm:"size(256);null"`       // 交付审核 负责人UUID
	T_scheme_state         int    `orm:"size(2);default(0)"`   // 实施方案 状态 0 未完成 1 已完成
	T_collection_state     int    `orm:"size(2);default(0)"`   // 数据采集 状态 0 未完成 1 已完成 2 处理中 3 已采集-无数据
	T_reporting_state      int    `orm:"size(2);default(0)"`   // 报告编写 状态 0 未完成 1 已完成
	T_delivery_state       int    `orm:"size(2);default(0)"`   // 交付审核 状态 0 未完成 1 已完成 2 处理中

	T_doc1 string `orm:"type(text);null"` // 封面
	T_pdf1 string `orm:"type(text);null"` // 封面
	T_doc2 string `orm:"type(text);null"` // 报告
	T_pdf2 string `orm:"type(text);null"` // 报告
	T_doc3 string `orm:"type(text);null"` // 证书
	T_pdf3 string `orm:"type(text);null"` // 证书

	T_Show     int       `orm:"size(2);default(1)"`                                    // 0 隐藏   1 公开
	T_Visit    int       `orm:"size(200);default(0)"`                                  // 浏览量
	T_State    int       `orm:"size(2);default(1)"`                                    // 0 删除   1 正常
	CreateTime time.Time `orm:"column(create_time);type(timestamp);null;auto_now_add"` //auto_now_add 第一次保存时才设置时间
	UpdateTime time.Time `orm:"column(update_time);type(timestamp);null;auto_now"`     //auto_now 每次 model 保存时都会对时间自动更新
}

type Task_R struct {
	T_task_id  string // id
	T_name     string // 标题
	T_doc1     string // 封面
	T_pdf1     string // 封面
	T_doc2     string // 报告
	T_pdf2     string // 报告
	T_doc3     string // 证书
	T_pdf3     string // 证书
	T_Show     int    // 公开/隐藏
	T_Visit    int    // 浏览量
	T_State    int    // 0    1
	CreateTime string
	UpdateTime string
}

type Task_ struct {
	Id                     int
	T_class                int    // 分类ID
	T_task_id              string // 任务ID
	T_uuid                 string // 用户 UUID
	T_user_name            string // 用户 UUID
	T_name                 string // 标题
	T_VerifyTemplate_class string // 任务模板id
	T_VerifyTemplate_id    string // 任务模板id
	T_deadline             string // 截止时间
	T_scheme               string // 实施方案 负责人UUID
	T_collection           string // 数据采集 负责人UUID
	T_reporting            string // 报告编写 负责人UUID
	T_delivery             string // 交付审核 负责人UUID
	T_scheme_state         int    // 实施方案 状态 0 未完成 1 已完成
	T_collection_state     int    // 数据采集 状态 0 未完成 1 已完成
	T_reporting_state      int    // 报告编写 状态 0 未完成 1 已完成
	T_delivery_state       int    // 交付审核 状态 0 未完成 1 已完成
	T_scheme_name          string // 实施方案 负责人姓名
	T_collection_name      string // 数据采集 负责人姓名
	T_reporting_name       string // 报告编写 负责人姓名
	T_delivery_name        string // 交付审核 负责人姓名
	T_doc1                 string // 封面
	T_pdf1                 string // 封面
	T_doc2                 string // 报告
	T_pdf2                 string // 报告
	T_doc3                 string // 证书
	T_pdf3                 string // 证书
	T_Show                 int    // 0 公开 1 隐藏
	T_Visit                int    // 浏览量
	T_State                int    // 0 删除 1 正常
}

func (t *Task) TableName() string {
	return "task" // 数据库名称   // ************** 替换 FormulaList **************
}

var redisCache_Task cache.Cache

func init() {

	//注册模型
	orm.RegisterModel(new(Task))

	config := fmt.Sprintf(`{"key":"%s","conn":"%s","dbNum":"%s","password":"%s"}`,
		"redis_"+"Task", conf.Redis_address, conf.Redis_dbNum, conf.Redis_password)
	logs.Println(config)
	var err error
	redisCache_Task, err = cache.NewCache("redis", config)
	if err != nil || redisCache_Task == nil {
		errMsg := "failed to init redis"
		logs.Println(errMsg, err)
	}
}

// -------------------------------------------------------------
func TaskToTask_R(T Task) (T_r Task_R) {
	T_r.T_task_id = T.T_task_id
	T_r.T_name = T.T_name
	T_r.T_doc1 = T.T_doc1
	T_r.T_pdf1 = T.T_pdf1
	T_r.T_doc2 = T.T_doc2
	T_r.T_pdf2 = T.T_pdf2
	T_r.T_doc3 = T.T_doc3
	T_r.T_pdf3 = T.T_pdf3
	T_r.T_Show = T.T_Show
	T_r.T_State = T.T_State
	T_r.T_Visit = T.T_Visit
	T_r.UpdateTime = T.UpdateTime.Format("2006-01-02 15:04:05")
	T_r.CreateTime = T.CreateTime.Format("2006-01-02 15:04:05")

	//......
	return T_r
}

func TaskToTask_(T Task, userMap, adminMap map[string]string) (T_ Task_) {
	T_.Id = T.Id
	T_.T_class = T.T_class
	T_.T_task_id = T.T_task_id
	T_.T_uuid = T.T_uuid
	T_.T_user_name = userMap[T.T_uuid]
	T_.T_name = T.T_name
	T_.T_VerifyTemplate_class = T.T_VerifyTemplate_class
	T_.T_VerifyTemplate_id = T.T_VerifyTemplate_id
	T_.T_deadline = T.T_deadline
	T_.T_scheme = T.T_scheme
	T_.T_collection = T.T_collection
	T_.T_reporting = T.T_reporting
	T_.T_delivery = T.T_delivery
	T_.T_scheme_state = T.T_scheme_state
	T_.T_collection_state = T.T_collection_state
	T_.T_reporting_state = T.T_reporting_state
	T_.T_delivery_state = T.T_delivery_state
	T_.T_scheme_name = adminMap[T.T_scheme]
	T_.T_collection_name = adminMap[T.T_collection]
	T_.T_reporting_name = adminMap[T.T_reporting]
	T_.T_delivery_name = adminMap[T.T_delivery]
	T_.T_doc1 = T.T_doc1
	T_.T_pdf1 = T.T_pdf1
	T_.T_doc2 = T.T_doc2
	T_.T_pdf2 = T.T_pdf2
	T_.T_doc3 = T.T_doc3
	T_.T_pdf3 = T.T_pdf3
	T_.T_Show = T.T_Show
	T_.T_Visit = T.T_Visit
	T_.T_State = T.T_State

	//......
	return T_
}

// ---------------- Redis -------------------
// Redis_Set(m.T_sn,m) // Redis 更新缓存
func Redis_Task_Set(key string, r Task) (err error) {
	//json序列化
	str, err := json.Marshal(r)
	if err != nil {
		logs.Error(lib.FuncName(), err)
		return
	}
	err = redisCache_Task.Put(key, str, 24*time.Hour)
	if err != nil {
		logs.Println("set key:", key, ",value:", str, err)
	}
	return
}

// if r,is :=Redis_Get(T_sn);is{
// return r,nil
// }
func Redis_Task_Get(key string) (r Task, is bool) {
	if redisCache_Task.IsExist(key) {
		logs.Println("找到key:", key)
		v := redisCache_Task.Get(key)
		json.Unmarshal(v.([]byte), &r)
		return r, true
	}
	logs.Println("没有 找到key:", key)
	return Task{}, false
}
func Redis_Task_DelK(key string) (err error) {
	err = redisCache_Task.Delete(key)
	return
}

// ---------------- 特殊方法 -------------------

// 获取 ById
func Read_Task_ById(id int) (r Task, is bool) {
	o := orm.NewOrm()
	r = Task{Id: id}
	err := o.Read(&r) // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
	if err != nil {
		logs.Error(lib.FuncName(), err)
		return r, false
	}
	return r, true
}

// 获取 By
func Read_Task(T_task_id string) (r Task, is bool) {
	if r, is = Redis_Task_Get(T_task_id); is == true {
		return r, true
	}

	o := orm.NewOrm()
	qs := o.QueryTable(new(Task))
	//err := qs.Filter("T_task_id", T_task_id).Filter("T_State", 1).One(&r)
	err := qs.Filter("T_task_id", T_task_id).One(&r)
	if err != nil {
		return r, false
	}

	Redis_Task_Set(T_task_id, r)
	return r, true
}

// 添加
func Add_Task(r Task) (string, bool) {
	o := orm.NewOrm()

	// 生成编号
	rand_x := 0
	for true {
		r.T_task_id = lib.GetRandstring(12, "abcdefghijklmnopqrstuvwxyz0123456789", int64(rand_x)) // 1,336,336
		err := o.Read(&r, "T_task_id")                                                             // o.Read(&r,"Tokey") 如果不是 主键 就得指定字段名
		if err != nil {
			break
		}
		rand_x += 1
	}

	_, err := o.Insert(&r)
	if err != nil {
		logs.Error(lib.FuncName(), err)
		return "", false
	}
	if !CREATE_TaskData(r.T_task_id) {
		return "", false
	}
	Redis_Task_Set(r.T_task_id, r)
	return r.T_task_id, true
}
func Add_Task_Tool(r Task) (string, bool) {
	o := orm.NewOrm()
	_, err := o.Insert(&r)
	if err != nil {
		logs.Error(lib.FuncName(), err)
		return "", false
	}
	return r.T_task_id, true
}

// 删除
func Delete_Task(v Task) bool {
	o := orm.NewOrm()
	if num, err := o.Delete(&v); err == nil {
		logs.Println("Number of records deleted in database:", num)
	} else {
		logs.Error(lib.FuncName(), err)
		return false
	}

	Redis_Task_DelK(v.T_task_id)
	return true
}

// 删除
func Delete_Task_(v Task) bool {
	o := orm.NewOrm()
	v.T_State = 0
	if num, err := o.Update(&v, "T_State"); err == nil {
		fmt.Println("Number of records updated in database:", num)
	} else {
		logs.Error(lib.FuncName(), err)
		return false
	}

	Redis_Task_DelK(v.T_task_id)
	return true
}

// 修改
func Update_Task(m Task, cols ...string) bool {
	o := orm.NewOrm()
	if num, err := o.Update(&m, cols...); err == nil {
		fmt.Println("Number of records updated in database:", num)
		Redis_Task_Set(m.T_task_id, m)
		return true
	} else {
		logs.Error(lib.FuncName(), err)
	}
	return false
}

// 添加浏览量
func Add_Task_Visit(m Task) bool {
	o := orm.NewOrm()
	m.T_Visit += 1
	if num, err := o.Update(&m, "T_Visit"); err == nil {
		fmt.Println("Number of records updated in database:", num)
		Redis_Task_Set(m.T_task_id, m)
		return true
	} else {
		logs.Error(lib.FuncName(), err)
	}
	return false
}

//// 获取列表
//func Read_Task_List(T_name string, page int, page_z int) ([]Task_R, int64) {
//
//	o := orm.NewOrm()
//	// 也可以直接使用 Model 结构体作为表名
//	var r []Task
//	qs := o.QueryTable(new(Task))
//	var offset int64
//	if page <= 1 {
//		offset = 0
//	} else {
//		offset = int64((page - 1) * page_z)
//	}
//	cond := orm.NewCondition()
//	cond1 := cond.And("T_name__icontains", T_name) // .AndNot("status__in", 1).Or("profile__age__gt", 2000)
//
//
//	qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&r)
//	cnt, _ := qs.SetCond((*orm2.Condition)(cond1)).Count()
//
//	// 转换
//	var Task_r []Task_R
//	for _, v := range r {
//		Task_r = append(Task_r, TaskToTask_R(v))
//	}
//
//	return Task_r, cnt
//}

// 获取用户任务列表
func Read_UserTask_List(T_uuid string, T_name string, userMap, adminMap map[string]string, page int, page_z int) ([]Task_, int) {

	o := orm.NewOrm()

	qs := o.QueryTable(new(Task))
	var r []Task
	var offset int64
	if page <= 1 {
		offset = 0
	} else {
		offset = int64((page - 1) * page_z)
	}
	cond := orm.NewCondition()
	//cond1 := cond.And("T_name__icontains", T_name).And("T_State", 1)
	cond1 := cond.And("T_name__icontains", T_name).And("T_Show", 1)
	if len(T_uuid) > 0 {
		cond1 = cond1.And("T_uuid", T_uuid)
	}

	qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&r)
	cnt, _ := qs.SetCond((*orm2.Condition)(cond1)).Count()

	// 转换
	var TaskList []Task_
	for _, v := range r {
		TaskList = append(TaskList, TaskToTask_(v, userMap, adminMap))
	}

	return TaskList, int(cnt)
}

// 获取任务列表
func Read_Task_List(T_uuid, T_admin string, T_name string, userMap, adminMap map[string]string, page int, page_z int) ([]Task_, int) {

	o := orm.NewOrm()

	qs := o.QueryTable(new(Task))
	var r []Task
	var offset int64
	if page <= 1 {
		offset = 0
	} else {
		offset = int64((page - 1) * page_z)
	}
	cond := orm.NewCondition()
	//cond1 := cond.And("T_name__icontains", T_name).And("T_State", 1)
	cond1 := cond.And("T_name__icontains", T_name)
	if len(T_uuid) > 0 {
		cond1 = cond1.And("T_uuid", T_uuid)

	}
	if len(T_admin) > 0 {
		cond1 = cond1.AndCond(cond.Or("T_scheme", T_admin).Or("T_collection", T_admin).
			Or("T_reporting", T_admin).Or("T_delivery", T_admin))
	}

	qs.Limit(page_z, offset).SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&r)
	cnt, _ := qs.SetCond((*orm2.Condition)(cond1)).Count()

	// 转换
	var TaskList []Task_
	for _, v := range r {
		TaskList = append(TaskList, TaskToTask_(v, userMap, adminMap))
	}

	return TaskList, int(cnt)
}

// 获取列表 /时间筛选  Time_start_ Time_end_    2021-12-30，所以下面要加后缀 时间
func Read_Task_List_Time(page int, T_sn string, T_Title string, Time_start_ string, Time_end_ string) ([]Task_R, int64) {

	o := orm.NewOrm()
	// 也可以直接使用 Model 结构体作为表名
	var r []Task
	var cnt int64
	qs := o.QueryTable(new(Task))
	var offset int64
	if page <= 1 {
		offset = 0
	} else {
		offset = int64((page - 1) * conf.Page_size)
	}

	if len(Time_start_) > 1 && len(Time_end_) > 1 {
		fmt.Println(Time_start_, Time_end_)
		qs.Limit(conf.Page_size, offset).Filter("T_Ut__lte", Time_end_+" 23:59:59").Filter("T_Ut__gte", Time_start_+" 00:00:00").Filter("T_Title__icontains", T_Title).Filter("T_sn__icontains", T_sn).OrderBy("-Id").Filter("T_State", 1).All(&r)
		cnt, _ = qs.Filter("T_Ut__lte", Time_end_+" 23:59:59").Filter("T_Ut__gte", Time_start_+" 00:00:00").Filter("T_Title__icontains", T_Title).Filter("T_sn__icontains", T_sn).Filter("T_State", 1).Count()
		return []Task_R{}, cnt
	}

	if len(Time_start_) > 1 {
		qs.Limit(conf.Page_size, offset).Filter("T_Ut__gte", Time_start_+" 00:00:00").Filter("T_Title__icontains", T_Title).Filter("T_sn__icontains", T_sn).OrderBy("-Id").Filter("T_State", 1).All(&r)
		cnt, _ = qs.Filter("T_Ut__gte", Time_start_+" 00:00:00").Filter("T_Title__icontains", T_Title).Filter("T_sn__icontains", T_sn).Filter("T_State", 1).Count()
		return []Task_R{}, cnt
	} else if len(Time_end_) > 1 {
		qs.Limit(conf.Page_size, offset).Filter("T_Ut__lte", Time_end_+" 23:59:59").Filter("T_Title__icontains", T_Title).Filter("T_sn__icontains", T_sn).OrderBy("-Id").Filter("T_State", 1).All(&r)
		cnt, _ = qs.Filter("T_Ut__lte", Time_end_+" 23:59:59").Filter("T_Title__icontains", T_Title).Filter("T_sn__icontains", T_sn).Filter("T_State", 1).Count()
		return []Task_R{}, cnt
	}

	qs.Limit(conf.Page_size, offset).Filter("T_Title__icontains", T_Title).Filter("T_sn__icontains", T_sn).OrderBy("-Id").Filter("T_State", 1).All(&r)
	cnt, _ = qs.Filter("T_Title__icontains", T_Title).Filter("T_sn__icontains", T_sn).Filter("T_State", 1).Count()

	var Task_r []Task_R
	for _, v := range r {
		Task_r = append(Task_r, TaskToTask_R(v))
	}

	return Task_r, cnt
}
