package InfoCollection

import (
	"ColdVerify_server/conf"
	"ColdVerify_server/lib"
	"ColdVerify_server/logs"
	"encoding/json"
	"errors"
	"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"
	"strings"
	"time"
)

var (
	InfoCollectionStatusWaitSubmit    = 1 // 待提交
	InfoCollectionStatusSubmitted     = 2 // 已提交
	InfoCollectionStatusReceipt       = 3 // 已接收
	InfoCollectionStatusReturn        = 4 // 已退回
	InfoCollectionStatusReturnedMoney = 5 // 已回款
	InfoCollectionStatusMap           = map[int]string{
		InfoCollectionStatusWaitSubmit:    "待提交",
		InfoCollectionStatusSubmitted:     "已提交",
		InfoCollectionStatusReceipt:       "已接收",
		InfoCollectionStatusReturn:        "已退回",
		InfoCollectionStatusReturnedMoney: "已回款",
	}
)

type AuditRecord struct {
	T_uuid      string `orm:"size(256);null"`     // 提交人 UUID
	T_uuid_name string `orm:"size(256);null"`     // 提交人名称
	T_status    int    `orm:"size(2);default(0)"` // 状态 1待提交 2已提交 3已接收 4已退回 5已回款
	T_reason    string `orm:"type(text)"`         // 原因
	T_time      string `orm:"type(256)"`          // 时间
}

// 模版
type InfoCollection struct {
	Id                   int     `orm:"column(ID);size(11);auto;pk"`
	T_InfoCollection_id  string  `orm:"size(256);null"`     // 信息采集ID
	T_uuid               string  `orm:"size(256);null"`     // 公司 UUID
	T_name               string  `orm:"size(256);null"`     // 标题
	T_InfoTemplate_class string  `orm:"size(256);null"`     // 模版分类
	T_InfoTemplate_id    string  `orm:"size(256);null"`     // 模版id
	T_status             int     `orm:"size(2);default(0)"` // 状态 1待提交 2已提交 3已接收 4已退回 5已回款
	T_State              int     `orm:"size(2);default(1)"` // 0 删除  1 正常
	T_submit_uuid        string  `orm:"size(256);null"`     // 提交人 UUID
	T_start_time         string  `orm:"size(256);null"`     // 开始时间
	T_end_time           string  `orm:"size(256);null"`     // 结束时间
	T_time_interval      float64 `orm:"size(256);null"`     // 时间间隔

	T_return_times int    `orm:"size(200);null"` // 退回次数
	T_audit_record string `orm:"type(text)"`

	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 InfoCollection_R struct {
	Id                        int
	T_InfoCollection_id       string  // 信息采集ID
	T_uuid                    string  // 用户 UUID
	T_uuid_name               string  // 用户姓名
	T_name                    string  // 标题
	T_InfoTemplate_class      string  // 模版分类
	T_InfoTemplate_class_name string  // 模版分类名称
	T_InfoTemplate_id         string  // 模版id
	T_InfoTemplate_name       string  // 模版名称
	T_status                  int     // 状态
	T_status_str              string  // 状态字符串
	T_State                   int     // 0 删除   1 正常
	T_submit_uuid             string  // 提交人uuid
	T_submit_uuid_name        string  // 提交人姓名
	T_start_time              string  // 开始时间
	T_end_time                string  // 结束时间
	T_time_interval           float64 // 时间间隔
	T_return_times            int     // 退回次数
	T_audit_record            string
	CreateTime                string
	UpdateTime                string
}

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

var redisCache_InfoCollection cache.Cache

func init() {

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

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

// -------------------------------------------------------------
func InfoCollectionToInfoCollection_R(T InfoCollection, userMap, adminMap, infoTemplateMap, infoTemplateClassMap map[string]string) (T_r InfoCollection_R) {
	T_r.Id = T.Id
	T_r.T_InfoCollection_id = T.T_InfoCollection_id
	T_r.T_uuid = T.T_uuid
	T_r.T_name = T.T_name
	T_r.T_InfoTemplate_class = T.T_InfoTemplate_class
	T_r.T_InfoTemplate_id = T.T_InfoTemplate_id
	T_r.T_status = T.T_status
	T_r.T_status_str = InfoCollectionStatusMap[T.T_status]
	T_r.T_State = T.T_State
	T_r.T_uuid_name = userMap[T.T_uuid]
	T_r.T_submit_uuid = T.T_submit_uuid
	T_r.T_submit_uuid_name = adminMap[T.T_submit_uuid]

	T_r.T_InfoTemplate_name = infoTemplateMap[T.T_InfoTemplate_id]
	classList := strings.Split(strings.Trim(T.T_InfoTemplate_class, "/"), "/")
	for _, s := range classList {
		T_r.T_InfoTemplate_class_name += infoTemplateClassMap[s] + "/"
	}
	T_r.T_InfoTemplate_class_name = strings.TrimRight(T_r.T_InfoTemplate_class_name, "/")

	T_r.T_start_time = T.T_start_time
	T_r.T_end_time = T.T_end_time
	T_r.T_time_interval = T.T_time_interval
	T_r.T_return_times = T.T_return_times
	T_r.T_audit_record = T.T_audit_record

	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
}

// ---------------- Redis -------------------
// Redis_Set(m.T_sn,m) // Redis 更新缓存
func Redis_InfoCollection_Set(key string, r InfoCollection) (err error) {
	//json序列化
	str, err := json.Marshal(r)
	if err != nil {
		logs.Error(lib.FuncName(), err)
		return
	}
	err = redisCache_InfoCollection.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_InfoCollection_Get(key string) (r InfoCollection, is bool) {
	if redisCache_InfoCollection.IsExist(key) {
		logs.Println("找到key:", key)
		v := redisCache_InfoCollection.Get(key)
		json.Unmarshal(v.([]byte), &r)
		return r, true
	}
	logs.Println("没有 找到key:", key)
	return InfoCollection{}, false
}
func Redis_InfoCollection_DelK(key string) (err error) {
	err = redisCache_InfoCollection.Delete(key)
	return
}

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

// 获取 ById
func Read_InfoCollection_ById(id int) (r InfoCollection, is bool) {
	o := orm.NewOrm()
	r = InfoCollection{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_InfoCollection(T_InfoCollection_id string) (r InfoCollection, is bool) {
	if r, is = Redis_InfoCollection_Get(T_InfoCollection_id); is == true {
		return r, true
	}

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

	Redis_InfoCollection_Set(T_InfoCollection_id, r)
	return r, true
}

// 添加
func Add_InfoCollection(r InfoCollection) (string, error) {
	o := orm.NewOrm()
	// 查询标题是否重复
	qs := o.QueryTable(new(InfoCollection))
	err := qs.Filter("T_name", r.T_name).Filter("T_uuid", r.T_uuid).Filter("T_State", 1).One(&r)
	if err == nil {
		return "", errors.New("信息采集标题重复")
	}

	// 生成编号
	rand_x := 0
	for true {
		r.T_InfoCollection_id = lib.GetRandstring(12, "abcdefghijklmnopqrstuvwxyz0123456789", int64(rand_x)) // 1,336,336
		err = o.Read(&r, "T_InfoCollection_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 "", errors.New("添加失败")
	}
	Redis_InfoCollection_Set(r.T_InfoCollection_id, r)
	return r.T_InfoCollection_id, nil
}

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

	Redis_InfoCollection_DelK(v.T_InfoCollection_id)
	return true
}

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

// 获取用户信息采集列表
func Read_UserInfoCollection_List(T_admin string, T_name string, T_status int, userMap, adminMap, infoTemplateMap, infoTemplateClassMap map[string]string, page int, page_z int) ([]InfoCollection_R, int) {

	o := orm.NewOrm()

	qs := o.QueryTable(new(InfoCollection))
	var r []InfoCollection
	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).And("T_submit_uuid", T_admin)

	if T_status > 0 {
		cond1 = cond1.And("T_status", T_status)
	}
	if page_z == 9999 {
		qs.SetCond((*orm2.Condition)(cond1)).OrderBy("-Id").All(&r)

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

	// 转换
	var InfoCollectionList []InfoCollection_R
	for _, v := range r {
		InfoCollectionList = append(InfoCollectionList, InfoCollectionToInfoCollection_R(v, userMap, adminMap, infoTemplateMap, infoTemplateClassMap))
	}

	return InfoCollectionList, int(cnt)
}

// 获取信息采集列表
func Read_InfoCollection_List(T_uuid, T_name string, T_status int, userMap, adminMap, infoTemplateMap, infoTemplateClassMap map[string]string, page int, page_z int) ([]InfoCollection_R, int) {

	o := orm.NewOrm()

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

	if len(T_uuid) > 0 {
		cond1 = cond1.And("T_uuid", T_uuid)
	}

	if T_status > 0 {
		cond1 = cond1.And("T_status", T_status)
	}

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

	// 转换
	var InfoCollectionList []InfoCollection_R
	for _, v := range r {
		InfoCollectionList = append(InfoCollectionList, InfoCollectionToInfoCollection_R(v, userMap, adminMap, infoTemplateMap, infoTemplateClassMap))
	}

	return InfoCollectionList, int(cnt)
}
