package controllers

import (
	"fmt"
	"io/ioutil"

	"github.com/astaxie/beego"

	"lc/common/models"
	"lc/common/protocol"
)

type IotModelController struct {
	BaseController
}

type ModelInfo struct {
	TID    uint16 `json:"tid"`
	SID    uint16 `json:"sid"`
	Name   string `json:"name"`
	NameZh string `json:"namezh"`
	Unit   string `json:"unit"`
	Type   uint8  `json:"type"`
}
type RespDeviceIotModelInfo struct {
	Code     string
	IotModel []ModelInfo
}

type ReqDeviceModel struct {
	Codes []string `json:"codes"`
	Type  int      `json:"type"` //1 环境监测设备，2 单灯控制器设备
}

// ModelUpload @Title 上传模型文件
// @Description 上传模型文件
// @router /v1/model/upload [post]
func (o *IotModelController) ModelUpload() {
	f, _, err := o.Ctx.Request.FormFile("file")
	if err != nil {
		o.Response(Failure, fmt.Sprintf("参数错误:%s", err.Error()), nil)
		return
	}
	defer f.Close()

	f.Seek(0, 0)
	content, err := ioutil.ReadAll(f)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("读文件错误:%s", err.Error()), nil)
		return
	}

	var obj protocol.IotModel
	if err := json.Unmarshal(content, &obj); err != nil {
		o.Response(Failure, fmt.Sprintf("内容解析错误:%s", err.Error()), nil)
		return
	}

	//模型存入数据库
	iot := models.IotModel{
		TID:      obj.TID,
		Version:  obj.Version,
		Device:   obj.Device,
		Model:    obj.Model,
		Protocol: obj.Protocol,
		File:     string(content),
	}
	if err := models.G_db.Save(&iot).Error; err != nil {
		o.Response(Failure, fmt.Sprintf("存数据库失败:%s", err.Error()), nil)
		beego.Error("存数据库失败:", err.Error())
		return
	}

	//上行数据项存入数据库
	for _, v := range obj.DataUp {
		var str string
		if v.Desc != nil {
			str, _ = json.MarshalToString(v.Desc)
		}
		oo := models.IotModelDataUp{
			TID:      obj.TID,
			Version:  obj.Version,
			Device:   obj.Device,
			Model:    obj.Model,
			Protocol: obj.Protocol,
			SID:      v.SID,
			Name:     v.Name,
			NameZh:   v.NameZh,
			Unit:     v.Unit,
			Endian:   v.Endian,
			Type:     v.Type,
			Ratio:    v.Ratio,
			Base:     v.Base,
			UpLimit:  v.UpLimit,
			LowLimit: v.LowLimit,
			Cid:      v.Cid,
			Start:    v.Start,
			Len:      v.Len,
			Alarm:    v.Alarm,
			Duration: v.Duration,
			Desc:     str,
			Bit:      v.Bit,
		}
		if err := models.G_db.Save(&oo).Error; err != nil {
			beego.Error("存数据库失败:", err.Error())
		}
	}
	//下行数据项存入数据库
	for _, v := range obj.DataDown {
		oo := models.IotModelCmdDown{
			TID:      obj.TID,
			Version:  obj.Version,
			Device:   obj.Device,
			Model:    obj.Model,
			Protocol: obj.Protocol,
			SID:      v.SID,
			Name:     v.Name,
			NameZh:   v.NameZh,
			Unit:     v.Unit,
			Endian:   v.Endian,
			Type:     v.Type,
			Ratio:    v.Ratio,
			Base:     v.Base,
			Code:     v.Code,
			Addr:     v.Addr,
			Quantity: v.Quantity,
			Vallen:   v.Vallen,
			Maxval:   v.Maxval,
			Minval:   v.Minval,
			Desc:     v.Desc,
		}
		if err := models.G_db.Save(&oo).Error; err != nil {
			beego.Error("存数据库失败:", err.Error())
		}
	}
}

// SelectModel @Title 获取设备物模型
// @Description 获取设备物模型
// @Param   body controllers.ReqDeviceModel true "数据"
// @Success 0 {int} BaseResponse.Code "成功"
// @Failure 1 {int} BaseResponse.Code "失败"
// @router /v1/select/model [post]
func (o *IotModelController) SelectModel() {
	var obj ReqDeviceModel
	err := json.Unmarshal(o.Ctx.Input.RequestBody, &obj)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("数据包解析错误:%s", err.Error()), nil)
		return
	}
	arr, err := models.GetMutilIotModelInfo(obj.Codes, obj.Type)
	if err != nil {
		o.Response(Failure, fmt.Sprintf("数据查询失败:%s", err.Error()), nil)
		return
	}

	ret := make(map[string][]ModelInfo)
	for _, v := range arr {
		mi := ModelInfo{
			TID:    v.TID,
			SID:    v.SID,
			Name:   v.Name,
			NameZh: v.NameZh,
			Unit:   v.Unit,
			Type:   v.Type,
		}
		ret[v.ID] = append(ret[v.ID], mi)
	}
	o.Response(Success, "成功", ret)
}
