package controllers

import (
	"encoding/json"
	"errors"
	"fmt"
	"strconv"
	"strings"
	"sws_xcx/enums"
	"sws_xcx/models"
	"sws_xcx/service"
	"sws_xcx/utils"
)

type MessageApiControllor struct {
	BaseApiController
}

func (c *MessageApiControllor) PutEmqxMessage() {

	msg := &models.OpenEmqMsgReqVO{}
	err := json.Unmarshal(c.Ctx.Input.RequestBody, msg)
	if err != nil {
		c.ServeDynamicFailJsonSend(err.Error())
		return
	}

	ds := service.NewDeviceService()

	device, err := ds.GetDeviceByNo(msg.UserName)
	if err != nil {
		utils.ErrorLog("GetDeviceByNo %v:", err)
		c.ServeDynamicFailJsonSend(err.Error())
		return
	}
	if device.Id == 0 {
		msg := "非本系统设备，数据废弃"
		utils.WarningLog(msg)
		c.ServeDynamicFailJsonSend(msg)
		return
	}
	err = ds.CreateDeviceMessageLog(models.DeviceMessageLog{
		DeviceName: msg.DeviceName,
		Content:    string(c.Ctx.Input.RequestBody),
		EventType:  enums.EventTypeEmqx,
		MessageId:  msg.Id,
		Topic:      msg.Topic,
	})

	if err != nil {
		utils.ErrorLog("CreateDeviceMessageLog %v:", err)
		c.ServeDynamicFailJsonSend(err.Error())
		return
	}
	payload := &models.OpenEmqPayloadReqVO{}
	err = json.Unmarshal([]byte(msg.Payload), payload)
	if err != nil {
		utils.ErrorLog("json.Unmarshal %v:", err)
		c.ServeDynamicFailJsonSend(err.Error())
		return
	}
	if payload.Len != 23 {
		utils.WarningLog("非标准数据，数据废弃:%v", msg.Payload)
	}

	dr, err := ds.GetDeviceRelateByDeviceId(device.Id)
	if err != nil {
		utils.ErrorLog("GetDeviceRelateByDeviceId %v:", err)
		c.ServeDynamicFailJsonSend(err.Error())
		return
	}

	checkRecord := &models.CheckRecord{

		Acc:          payload.Acc,
		PutSources:   enums.EventTypeEmqx,
		MessageId:    msg.Id,
		DeviceId:     device.Id,
		UserId:       dr.UserId,
		DeviceStatus: device.Status,
	}

	if dr.UserId > 0 {

		hp, err := service.NewUserHealthProfileService().GetUserHealthProfileByUserId(dr.UserId)
		if err != nil {
			utils.ErrorLog("GetUserHealthProfileByUserId %v:", err)
			c.ServeDynamicFailJsonSend(err.Error())
			return
		}
		checkRecord.UserHealthProfileId = int64(hp.Id)
	}
	crs := service.NewCheckRecordService()
	err = crs.CreateCheckRecord(checkRecord)
	if err != nil {
		utils.ErrorLog("CreateCheckRecord %v:", err)
		c.ServeDynamicFailJsonSend(err.Error())
		return
	}

	da := strings.Split(payload.Data, ",")
	count := payload.Count
	if len(da) != count {
		utils.WarningLog("数据长度不匹配,截取存储 %+v", payload)
		if len(da) < count {
			count = len(da)
		}
	}

	checkItems, err := service.NewCheckItemService().GetCheckItems("cn", device.DeviceType)

	if err != nil {
		utils.ErrorLog("GetCheckItems %v:", err)
		c.ServeDynamicFailJsonSend(err.Error())
		return
	}

	if len(checkItems) < count {
		c.ServeDynamicFailJsonSend("接收的数据与检查项目配置不一致")
		return
	}

	alerts := make([]string, 0)
	for i := 0; i < count; i++ {
		vi, _ := strconv.Atoi(da[i])
		err = createCheckRecordItem(checkItems, checkRecord.Id, &alerts, vi, i+1, crs)
		if err != nil {
			utils.ErrorLog("createCheckRecordItem valule:%v, err:%v:", vi, err)
		}
	}

	if len(alerts) > 0 {
		alertItemIds := strings.Join(alerts, ",")
		err = crs.UpdateCheckRecordAlertItems(checkRecord.Id, alertItemIds)
		if err != nil {
			utils.ErrorLog("UpdateCheckRecordAlertItems %v:", err)
			c.ServeDynamicFailJsonSend(err.Error())
			return
		}

	}

}

func createCheckRecordItem(items []*models.CheckItem, crId int64, alerts *[]string, vi, n int, crs *service.CheckRecordService) error {
	item := findItem(items, n)
	if item == nil {
		return fmt.Errorf("检测项目不匹配，需要检查基础数据！序号：%v", n)
	}

	cri := models.CheckRecordItem{
		CheckId:         crId,
		CheckItemId:     n,
		CheckValueIndex: vi,
	}

	scopes := []*models.CheckItemScopeVO{}
	err := json.Unmarshal([]byte(item.ScopeList), &scopes)
	if err != nil {
		return fmt.Errorf("检测项目数值范围定义不正确 err:%v", err)
	}
	scope := findScope(scopes, vi)
	if scope == nil {
		return errors.New("检测结果不匹配")
	}

	cri.CheckValue = scope.Value
	if scope.Type != 1 {
		*alerts = append(*alerts, strconv.Itoa(n))
	}
	return crs.CreateCheckRecordItem(&cri)
}

func findScope(scopes []*models.CheckItemScopeVO, vi int) *models.CheckItemScopeVO {
	for _, scope := range scopes {
		if scope.Index == vi {
			return scope
		}
	}
	return nil
}

func findItem(items []*models.CheckItem, itemNumber int) *models.CheckItem {
	//循环items
	for _, item := range items {
		if item.CheckItemNumber == itemNumber {
			return item
		}
	}
	return nil
}
