package edbmonitor

import (
	"errors"
	edbmonitor "eta/eta_api/models/edb_monitor"
	"eta/eta_api/models/edb_monitor/response"
	"eta/eta_api/utils"
	"strconv"
	"time"

	"github.com/gorilla/websocket"
	"github.com/rdlucklib/rdluck_tools/paging"
)

var (
	EDB_MONITOR_MESSAGE_CONNECT_CACHE = "edb_monitor_message_cache:"
)

var MonitorMessageConn = make(map[int]*websocket.Conn)

func ReadEdbMonitorMessage(messageId, adminId int) (msg string, err error) {
	message, err := edbmonitor.GetEdbMonitorMessageById(messageId)
	if err != nil {
		if err.Error() == utils.ErrNoRow() {
			msg = "消息不存在"
			return
		}
		msg = "获取消息失败"
		return
	}
	if message.AdminId != adminId {
		msg = "您没有权限查看该消息"
		err = errors.New("no permission")
		return
	}
	message.IsRead = 1
	err = message.Update([]string{"IsRead"})
	if err != nil {
		msg = "已读失败"
		return
	}
	return
}

func ReadEdbMonitorMessageList(messageId []int, adminId int) (msg string, err error) {
	err = edbmonitor.BatchModifyEdbMonitorMessageIsRead(messageId, adminId)
	if err != nil {
		msg = "已读失败"
		return
	}
	return
}

func EdbMonitorMessageHealth(adminId int) (isClose bool, err error) {
	conn := MonitorMessageConn[adminId]
	if conn == nil {
		err = errors.New("no connection")
		isClose = true
		return
	}
	_, msg, err := conn.ReadMessage()
	if err != nil {
		isClose = true
		return
	}
	if string(msg) == "ping" {
		healthKey := EDB_MONITOR_MESSAGE_CONNECT_CACHE + strconv.Itoa(adminId)
		err = utils.Rc.Put(healthKey, "1", time.Minute*1)
		if err != nil {
			return
		}
	}
	return
}

func LogMessage(content, uniqueCode string, triggerTime time.Time, edbInfoId, edbInfoType, adminId, isRead, classifyId int) (err error) {
	message := &edbmonitor.EdbMonitorMessage{
		EdbInfoId:          edbInfoId,
		EdbInfoType:        edbInfoType,
		EdbUniqueCode:      uniqueCode,
		EdbClassifyId:      classifyId,
		AdminId:            adminId,
		IsRead:             isRead,
		Message:            content + "触发预警",
		MonitorTriggerTime: triggerTime,
		CreateTime:         time.Now(),
	}
	_, err = message.Insert()

	return err
}

func SendMessages(adminId, edbInfoId, edbInfoType int, classifyId int, edbUniqueCode, message string, triggerTime string) (err error) {
	conn := MonitorMessageConn[adminId]
	if conn == nil {
		return errors.New("no connection")
	}
	msg := response.EdbMonitorMessageResp{
		EdbInfoId:     edbInfoId,
		EdbInfoType:   edbInfoType,
		EdbUniqueCode: edbUniqueCode,
		EdbClassifyId: classifyId,
		Message:       message,
		TriggerTime:   triggerTime,
	}
	return conn.WriteJSON(msg)
}

func GetHistoryMessages(adminId int) (items []*response.EdbMonitorMessageResp, err error) {
	messageList, err := edbmonitor.GetEdbMonitorMessageByAdminId(adminId)
	if err != nil {
		return
	}

	items = toEdbMonitorMessageResp(messageList)
	return
}

func GetMessageList(adminid int, currentIndex, pageSize int) (resp response.EdbMonitorMessageListResp, err error) {
	startSize := utils.StartIndex(currentIndex, pageSize)

	total, err := edbmonitor.GetEdbMonitorMessageCountByAdminId(adminid)
	if err != nil {
		return
	}
	if total == 0 {
		resp.List = make([]*response.EdbMonitorMessageResp, 0)
		resp.Paging = paging.GetPaging(currentIndex, pageSize, total)
		return
	}

	messageList, err := edbmonitor.GetEdbMonitorMessagePageByAdminId(adminid, startSize, pageSize)
	if err != nil {
		return
	}

	resp.List = toEdbMonitorMessageResp(messageList)
	resp.Paging = paging.GetPaging(currentIndex, pageSize, total)
	return
}

func toEdbMonitorMessageResp(items []*edbmonitor.EdbMonitorMessage) (list []*response.EdbMonitorMessageResp) {
	list = make([]*response.EdbMonitorMessageResp, 0)
	for _, message := range items {
		item := response.EdbMonitorMessageResp{
			EdbMonitorMessageId: message.EdbMonitorMessageId,
			EdbInfoId:           message.EdbInfoId,
			EdbInfoType:         message.EdbInfoType,
			EdbUniqueCode:       message.EdbUniqueCode,
			EdbClassifyId:       message.EdbClassifyId,
			IsRead:              message.IsRead,
			Message:             message.Message,
			TriggerTime:         utils.TimeTransferString(utils.FormatDateTime, message.MonitorTriggerTime),
		}
		list = append(list, &item)
	}
	return
}