package Device

import (
	"Cold_Data/conf"
	"Cold_Data/logs"
	"encoding/json"
	"fmt"
	"github.com/astaxie/beego/cache"
	_ "github.com/astaxie/beego/cache/redis"
	"github.com/beego/beego/v2/adapter/orm"
	_ "github.com/go-sql-driver/mysql"
	"strconv"
	"time"
)

// 模板
type DeviceSensor struct {
	Id     int    `orm:"column(ID);size(11);auto;pk"`
	T_sn   string `orm:"index;size(256);"` // 设备序列号 KF开头，环境监测主机。 YD开头，温途监测主机
	T_id   int    `orm:"index;size(11);"`  // 传感器编号
	T_name string `orm:"size(256);"`       // 标题

	T_pid      int    `orm:"index;size(256);"`           // Account.Company 绑定公司
	T_Class    string `orm:"size(256);"`                 // Device.DeviceClass.Id 设备分类  C1|C2|
	T_Notice   string `orm:"size(256);"`                 // 通知绑定    N1|N2|N3|
	T_datashow int    `orm:"index;size(2);default(1)"`   // 0 屏蔽数据展示  1 正常数据展示   （屏蔽后 数据展示无法看到，设备管理中 不受影响）
	T_sort     int    `orm:"index;size(200);default(1)"` // 排序
	T_3dview   string `orm:"size(256);"`                 //3D 视图ID
	T_type     int    `orm:"index;size(4);"`             // 0:未知类型   1库房   2移动
	T_link     int    `orm:"index;size(4);default(1)"`   // 0:断开/故障   1连接     ：实时数据
	T_State    int    `orm:"index;size(2);default(1)"`   // 0 屏蔽   1 正常  （屏蔽后 只有内部管理员才能看到，用户 输入SN\名称 搜索时 也能看到）

	// 设备同步参数
	T_Dattery  int    `orm:"size(4);"`                 // 电量
	T_Site     string `orm:"size(200);"`               // GPS                         ：实时数据
	T_monitor  int    `orm:"index;size(2);"`           // 监控状态 0 未监控 1 监控       ：记录数据(=0)   下线(=0)
	T_online   int    `orm:"index;size(2);default(1)"` // 在线状态 0 未启用  1 在线  2 离线    ：上下线
	T_online_s int    `orm:"index;size(2);default(0)"` // 在线状态-备用  0 未启用  1 在线  2 离线   ：上下线

	CreateTime time.Time `orm:"column(create_time);type(timestamp);auto_now_add"` //auto_now_add 第一次保存时才设置时间
	UpdateTime time.Time `orm:"column(update_time);type(timestamp);auto_now"`     //auto_now 每次 model 保存时都会对时间自动更新
}

type DeviceSensor_Del struct {
	T_sn string
	T_id int
}

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

var redisCache_DeviceSensor cache.Cache

func init() {
	//注册模型
	orm.RegisterModel(new(DeviceSensor))

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

}

// ---------------- Redis -------------------
// Redis_Set(m.T_sn,m) // Redis 更新缓存
func Redis_DeviceSensor_Set(r DeviceSensor) (err error) {
	key := r.T_sn + "|" + strconv.Itoa(r.T_id)

	//json序列化
	str, err := json.Marshal(r)
	if err != nil {
		logs.PrintlnError("Redis_DeviceSensor_Set", err)
		return
	}

	err = redisCache_DeviceSensor.Put(key, str, 24*time.Hour)
	if err != nil {
		logs.Println("set key:", key, ",value:", str, err)
	}
	return
}
func Redis_DeviceSensor_Get(key string) (r DeviceSensor, is bool) {
	if redisCache_DeviceSensor.IsExist(key) {
		//println("找到key:",key)
		v := redisCache_DeviceSensor.Get(key)
		json.Unmarshal(v.([]byte), &r)
		return r, true
	}
	//println("没有 找到key:",key)
	return DeviceSensor{}, false
}
func Redis_DeviceSensor_DelK(r DeviceSensor) (err error) {
	key := r.T_sn + "|" + strconv.Itoa(r.T_id)
	err = redisCache_DeviceSensor.Delete(key)
	return
}

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

// 添加
func Add_DeviceSensor(Device_r Device, Devicesensor_r DeviceSensor) int {
	//if(conf.Test_server) {return }

	o := orm.NewOrm()

	// 设备同步参数
	Devicesensor_r.T_Dattery = Device_r.T_Dattery   // 电量
	Devicesensor_r.T_Site = Device_r.T_Site         // GPS
	Devicesensor_r.T_monitor = Device_r.T_monitor   // 监控状态 0 未监控 1 监控
	Devicesensor_r.T_online = Device_r.T_online     // 在线状态 0 未启用  1 在线  2 离线
	Devicesensor_r.T_online_s = Device_r.T_online_s // 在线状态-备用  0 未启用  1 在线  2 离线

	// 三个返回参数依次为：是否新创建的，对象 Id 值，错误
	_, id, err := o.ReadOrCreate(&Devicesensor_r, "T_sn", "T_id")
	if err != nil {
		return 0
	}

	Redis_DeviceSensor_Set(Devicesensor_r)
	return int(id)
}

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

	return false
}

// 获取
func Read_DeviceSensor_ByT_pid(T_pid int) (r []DeviceSensor) {
	o := orm.NewOrm()
	// 也可以直接使用 Model 结构体作为表名

	qs := o.QueryTable(new(DeviceSensor))

	_, err := qs.Filter("T_pid", T_pid).Filter("T_datashow", 1).Filter("T_State", 1).All(&r)
	if err != nil {
		return
	}
	return
}

// 获取列表
func Read_DeviceSensor_ByTsn(T_sn string) []DeviceSensor {

	o := orm.NewOrm()
	// 也可以直接使用 Model 结构体作为表名
	qs := o.QueryTable(new(DeviceSensor))
	var r []DeviceSensor
	qs.Filter("T_sn", T_sn).OrderBy("T_id").All(&r)

	return r
}

// 设备同步参数
func Update_Device_To_DeviceSensor(r_Device Device) bool {
	DeviceSensor_list := Read_DeviceSensor_ByTsn(r_Device.T_sn)
	for _, v := range DeviceSensor_list {

		// 设备同步参数
		v.T_Dattery = r_Device.T_Dattery   // 电量
		v.T_Site = r_Device.T_Site         // GPS
		v.T_monitor = r_Device.T_monitor   // 监控状态 0 未监控 1 监控
		v.T_online = r_Device.T_online     // 在线状态 0 未启用  1 在线  2 离线
		v.T_online_s = r_Device.T_online_s // 在线状态-备用  0 未启用  1 在线  2 离线

		Update_DeviceSensor(v, "T_Dattery", "T_Site", "T_monitor", "T_online", "T_online_s")
	}

	return true
}
