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"
	orm2 "github.com/beego/beego/v2/client/orm"
	_ "github.com/go-sql-driver/mysql"
	"strconv"
	"time"
)

// 传感器 参数
type DeviceSensorParameter 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_Tlower  float32 `orm:"size(200);"` //  温度下限
	T_Tupper  float32 `orm:"size(200);"` //  温度上限
	T_RHlower float32 `orm:"size(200);"` //  湿度下限
	T_RHupper float32 `orm:"size(200);"` //  湿度上限

	// 预警
	T_enprel     int     `orm:"size(2);default(1)"` // 是否启用预警
	T_tprel      float32 `orm:"size(200);"`         //  温度预警下限
	T_tpreu      float32 `orm:"size(200);"`         //  温度预警上限
	T_hprel      float32 `orm:"size(200);"`         //  湿度预警下限
	T_hpreu      float32 `orm:"size(200);"`         //  温度预警上限
	T_enprelnote int     `orm:"size(2);default(1)"` // 是否启用预警记录

	//T_speed int `orm:"size(5);"`           // 传感器采样率   s(1~240) 默认：15 *
	//T_sense int `orm:"size(5);"`           // 传感器灵敏度   s(0~10) 默认：5
	T_en   int `orm:"size(2);default(1)"` // en:是否启用传感器，   0 停用   1 启用
	T_free int `orm:"size(2);default(1)"` //   是否为闲置状态    1：启用（正常 实时、记录, 不 报警、预警）
	//0：关闭（正常 实时、记录、报警、预警）  默认：0

	// 逻辑字段
	T_uuid      string `orm:"size(256);"`          //处理 人员
	T_Msid      int64  `orm:"size(50);default(0)"` // 消息识别ID
	T_SendState int    `orm:"size(2);default(0)"`  // 发送状态  0 待发送   1 发送成功  2 失败  3 覆盖
	T_State     int    `orm:"size(2);default(1)"`  //  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 保存时都会对时间自动更新
}

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

var redisCache_DeviceSensorParameter cache.Cache

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

// ---------------- Redis -------------------
// Redis_Set(m.T_sn,m) // Redis 更新缓存
func Redis_DeviceSensorParameter_Set(key string, r DeviceSensorParameter) (err error) {

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

	err = redisCache_DeviceSensorParameter.Put(key, str, 8*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_DeviceSensorParameter_Get(key string) (r DeviceSensorParameter, is bool) {
	if redisCache_DeviceSensorParameter.IsExist(key) {
		//println("找到key:",key)
		v := redisCache_DeviceSensorParameter.Get(key)
		json.Unmarshal(v.([]byte), &r)
		return r, true
	}
	//println("没有 找到key:",key)
	return DeviceSensorParameter{}, false
}

// ---------------- 特殊方法 -------------------
func Add_DeviceSensorParameter_fun(Devicesensorparameter DeviceSensorParameter) bool {

	if Devicesensorparameter_r, is := Read_DeviceSensorParameter(Devicesensorparameter.T_sn, Devicesensorparameter.T_id); is {
		if Devicesensorparameter_r.T_name != Devicesensorparameter.T_name ||
			Devicesensorparameter_r.T_Tlower != Devicesensorparameter.T_Tlower ||
			Devicesensorparameter_r.T_Tupper != Devicesensorparameter.T_Tupper ||
			Devicesensorparameter_r.T_RHlower != Devicesensorparameter.T_RHlower ||
			Devicesensorparameter_r.T_RHupper != Devicesensorparameter.T_RHupper ||
			Devicesensorparameter_r.T_enprel != Devicesensorparameter.T_enprel ||
			Devicesensorparameter_r.T_tprel != Devicesensorparameter.T_tprel ||
			Devicesensorparameter_r.T_tpreu != Devicesensorparameter.T_tpreu ||
			Devicesensorparameter_r.T_hprel != Devicesensorparameter.T_hprel ||
			Devicesensorparameter_r.T_hpreu != Devicesensorparameter.T_hpreu ||
			Devicesensorparameter_r.T_enprelnote != Devicesensorparameter.T_enprelnote ||
			//Devicesensorparameter_r.T_speed != Devicesensorparameter.T_speed ||
			//Devicesensorparameter_r.T_sense != Devicesensorparameter.T_sense ||
			Devicesensorparameter_r.T_en != Devicesensorparameter.T_en ||
			Devicesensorparameter_r.T_free != Devicesensorparameter.T_free {

			// 添加记录
			if _, is := Add_DeviceSensorParameter(Devicesensorparameter); !is {
				logs.PrintlnError("Add_DeviceSensorParameter_fun", "插入失败 [DeviceParameter]")
			}
			return true
		}
	} else {
		// 添加记录
		if _, is := Add_DeviceSensorParameter(Devicesensorparameter); !is {
			logs.PrintlnError("Add_DeviceSensorParameter_fun", "插入失败 [DeviceParameter]")
		}
		return true
	}
	return false
}

// 添加
func Add_DeviceSensorParameter(m DeviceSensorParameter) (int64, bool) {
	o := orm.NewOrm()
	m.Id = 0
	key := m.T_sn + "|" + strconv.Itoa(m.T_id)
	m.T_SendState = 0
	m.T_State = 1
	id, err := o.Insert(&m)
	if err != nil {
		logs.PrintlnError("Add_DeviceSensorParameter", err)
		return id, false
	}
	Redis_DeviceSensorParameter_Set(key, m)
	return id, true
}

// 获取设备参数
func Read_DeviceSensorParameter(T_sn string, T_id int) (t DeviceSensorParameter, bool bool) {
	key := T_sn + "|" + strconv.Itoa(T_id)
	if t, is := Redis_DeviceSensorParameter_Get(key); is {
		return t, true
	}

	o := orm.NewOrm()
	qs := o.QueryTable(new(DeviceSensorParameter))

	cond := orm.NewCondition()
	cond = cond.And("T_sn", T_sn).And("T_id", T_id).And("T_State", 1)

	qs.SetCond((*orm2.Condition)(cond)).OrderBy("-UpdateTime").One(&t)
	// 判断是否有数据
	if t.Id == 0 {
		return t, false
	}

	Redis_DeviceSensorParameter_Set(key, t)
	return t, true
}

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

// 获取最新数据
func UPDATE_DeviceSensorParamete_SN_T_SendState_2_sql(T_sn string, T_id string) {
	o := orm.NewOrm()

	res, err := o.Raw("UPDATE device_sensor_parameter SET `t__send_state` = 3 WHERE `t_sn` LIKE '%" + T_sn + "%' AND `t_id` = " + T_id + " AND `t__send_state` = '0' AND `t__state` = '2'").Exec()
	if err == nil {
		num, _ := res.RowsAffected()
		logs.Println("mysql row affected nums: ", num)
	}

}

// 获取列表
func Read_DeviceSensorParameter_SN_T_id_Msid(T_sn string, T_Msid int64) (DeviceSensorParameter, bool) {

	o := orm.NewOrm()
	// 也可以直接使用 Model 结构体作为表名
	var r []DeviceSensorParameter
	qs := o.QueryTable(new(DeviceSensorParameter))

	qs.Filter("T_sn", T_sn).Filter("T_Msid", T_Msid).OrderBy("-Id").All(&r)

	if len(r) == 0 {
		return DeviceSensorParameter{}, false
	}

	return r[0], true
}

// 获取最新数据
func Read_DeviceSensorParameter_SN_T_SendState_0_sql(sn string) (maps []orm2.ParamsList) {
	o := orm.NewOrm()

	sql := "SELECT DISTINCT t_sn,t_id FROM device_sensor_parameter WHERE  `t_sn` = '" + sn + "' AND  `t__send_state` = '0' AND `t__state` = '2'"

	logs.Println(sql)
	o.Raw(sql).ValuesList(&maps)

	return maps
}

// 获取列表
func Read_DeviceSensorParameter_SN_T_id(T_sn string, T_id int) (r []DeviceSensorParameter) {

	o := orm.NewOrm()
	// 也可以直接使用 Model 结构体作为表名

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

	qs.Limit(3, 0).Filter("T_sn", T_sn).Filter("T_id", T_id).Filter("T_State", 2).OrderBy("-Id").All(&r)

	return r
}
