package Function

import (
	"Cold_GoodsOrder/Nats/NatsServer"
	"Cold_GoodsOrder/conf"
	"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"
	"strconv"
	"time"
)

// 模板
type GoodsOrder struct {
	Id int `orm:"column(ID);size(11);auto;pk"`
	//T_id   string `orm:"size(50);null"` // 订单唯一ID
	T_pid int `orm:"index;size(256);null"` // Account.Company 绑定公司

	T_orderid    string `orm:"size(256);null"` // 订单号
	T_outorderid string `orm:"size(256);null"` // 出库订单号
	T_sn         string `orm:"size(256);null"` // 设备sn
	//T_snid         int `orm:"size(256);0"` // 设备id
	T_receiving string `orm:"size(256);null"` // 收货单位

	T_start_Ut   time.Time `orm:"type(timestamp);null;"` // 起运时间
	T_start_Ut_T float32   `orm:"size(10);default(0)"`   // 起运温度
	T_end_Ut     time.Time `orm:"type(timestamp);null;"` // 到达时间
	T_end_Ut_T   float32   `orm:"size(10);default(0);"`  // 到达温度

	T_text string `orm:"type(text);null"` // 详情

	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 GoodsOrderR struct {
	Id           int     // ID
	T_orderid    string  // 订单号
	T_outorderid string  // 出库订单号
	T_name       string  // 设备名称
	T_sn         string  // 设备sn
	T_receiving  string  // 收货单位
	T_start_Ut   string  // 起运时间
	T_start_Ut_T float32 // 起运温度
	T_end_Ut     string  // 到达时间
	T_end_Ut_T   float32 // 到达时间
	T_text       string  // 详情

}

func GoodsOrderToGoodsOrderR(t GoodsOrder) (r GoodsOrderR) {
	r.Id = t.Id
	r.T_orderid = t.T_orderid
	r.T_outorderid = t.T_outorderid
	Device_r, err := NatsServer.ReadDeviceByT_sn(t.T_sn)
	r.T_name = t.T_sn
	if err == nil {
		r.T_name = Device_r.T_devName
	}

	r.T_sn = t.T_sn
	r.T_receiving = t.T_receiving
	r.T_start_Ut = t.T_start_Ut.Format("2006-01-02 15:04:05")
	r.T_start_Ut_T = t.T_start_Ut_T
	r.T_end_Ut = t.T_end_Ut.Format("2006-01-02 15:04:05")
	r.T_end_Ut_T = t.T_end_Ut_T
	r.T_text = t.T_text
	return
}

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

var redisCache_GoodsOrder cache.Cache

func init() {
	//注册模型
	orm.RegisterModel(new(GoodsOrder))
	config := fmt.Sprintf(`{"key":"%s","conn":"%s","dbNum":"%s","password":"%s"}`,
		"redis_Cold_GoodsOrder", conf.Redis_address, conf.Redis_dbNum, conf.Redis_password)
	fmt.Println(config)
	var err error
	redisCache_GoodsOrder, err = cache.NewCache("redis", config)
	if err != nil || redisCache_GoodsOrder == nil {
		errMsg := "failed to init redis"
		fmt.Println(errMsg, err)
	}

}

// ---------------- Redis -------------------
func Redis_GoodsOrder_Set(r GoodsOrder) (err error) {
	//json序列化
	str, err := json.Marshal(r)
	if err != nil {
		fmt.Print(err)
		return
	}

	err = redisCache_GoodsOrder.Put(strconv.Itoa(r.Id), str, 24*time.Hour)
	if err != nil {
		fmt.Println("set key:", strconv.Itoa(r.Id), ",value:", str, err)
	}
	return
}

func Redis_GoodsOrder_Get(key string) (r GoodsOrder, is bool) {
	if redisCache_GoodsOrder.IsExist(key) {
		//println("找到key:",key)
		v := redisCache_GoodsOrder.Get(key)

		json.Unmarshal(v.([]byte), &r)
		return r, true
	}
	//println("没有 找到key:",key)
	return GoodsOrder{}, false
}

func Redis_GoodsOrder_DelK(key string) (err error) {
	err = redisCache_GoodsOrder.Delete(key)
	return
}

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

// 获取 ById
func Read_GoodsOrder_ById(id int) (r GoodsOrder) {
	if r, is := Redis_GoodsOrder_Get(strconv.Itoa(id)); is {
		return r
	}

	o := orm.NewOrm()
	r = GoodsOrder{Id: id, T_State: 1}
	err := o.Read(&r)
	if err != nil {
		fmt.Println(err)
	}
	return r
}

// 添加
func Add_GoodsOrder(m GoodsOrder) (id int64, err error) {
	o := orm.NewOrm()

	id, err = o.Insert(&m)
	if err != nil {
		fmt.Println(err)
	}
	Redis_GoodsOrder_Set(m)
	return id, err
}

// 修改
func Update_GoodsOrder(r GoodsOrder, cols ...string) bool {
	o := orm.NewOrm()
	if num, err := o.Update(&r, cols...); err == nil {
		fmt.Println("Number of records updated in database:", num)
		Redis_GoodsOrder_Set(r)
		return true
	}
	return false
}

// 删除
func Delete_GoodsOrder(m GoodsOrder) bool {
	o := orm.NewOrm()
	m.T_State = 0
	if num, err := o.Delete(&m); err == nil {
		fmt.Println("Number of records deleted in database:", num)
		Redis_GoodsOrder_DelK(strconv.Itoa(m.Id))
		return true
	}
	return false
}

// 获取列表
func Read_GoodsOrder_List(T_pid int, page int, page_z int, Name string) (t []GoodsOrderR, cnt int64) {
	o := orm.NewOrm()

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

	cond := orm.NewCondition()
	cond1 := cond.And("T_pid", T_pid).And("T_State", 1)

	if len(Name) > 0 {
		cond1 = cond.AndCond(cond1).AndCond(cond.Or("T_sn__icontains", Name).Or("T_orderid__icontains", Name).Or("T_outorderid__icontains", Name))
	}

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

	for _, v := range r {
		t = append(t, GoodsOrderToGoodsOrderR(v))
	}
	return t, cnt
}
