package ne_alarm_state_check

import (
	"encoding/json"
	"fmt"
	"time"

	"be.ems/src/framework/constants"
	"be.ems/src/framework/cron"
	"be.ems/src/framework/logger"
	"be.ems/src/framework/utils/parse"

	neDataModel "be.ems/src/modules/network_data/model"
	neDataService "be.ems/src/modules/network_data/service"
	neModel "be.ems/src/modules/network_element/model"
	neService "be.ems/src/modules/network_element/service"
	wsService "be.ems/src/modules/ws/service"
)

var NewProcessor = &NeAlarmStateCheckProcessor{
	neConfigBackupService: neService.NewNeConfigBackup,
	neInfoService:         neService.NewNeInfo,
	alarmService:          neDataService.NewAlarm,
	wsSendService:         wsService.NewWSSend,
	count:                 0,
}

// NeAlarmStateCheckProcessor 网元告警状态检查
type NeAlarmStateCheckProcessor struct {
	neConfigBackupService *neService.NeConfigBackup // 网元配置文件备份记录服务
	neInfoService         *neService.NeInfo         // 网元信息服务
	alarmService          *neDataService.Alarm      // 告警信息服务
	wsSendService         *wsService.WSSend         // ws发送服务
	count                 int                       // 执行次数
}

// alarmParams 告警参数
type alarmParams struct {
	AlarmTitle        string `json:"alarmTitle"`        // NE State Check Alarm
	AlarmType         string `json:"alarmType"`         // EquipmentAlarm=2
	OrigSeverity      string `json:"origSeverity"`      // Major=2
	SpecificProblem   string `json:"specificProblem"`   // alarm cause: the system state of target NE has not been received
	SpecificProblemID string `json:"specificProblemId"` // AC10000
	AddInfo           string `json:"addInfo"`

	// === 非参数字段 ===
	AlarmId string // 告警ID
}

func (s *NeAlarmStateCheckProcessor) Execute(data any) (any, error) {
	s.count++ // 执行次数加一
	options := data.(cron.JobData)
	sysJob := options.SysJob
	logger.Infof("重复:%v 任务ID:%s  执行次数:%d", options.Repeat, sysJob.JobID, s.count)
	// 返回结果，用于记录执行结果
	result := map[string]any{
		"count": s.count,
	}

	// 读取参数值
	var params alarmParams
	err := json.Unmarshal([]byte(sysJob.TargetParams), &params)
	if err != nil {
		return nil, fmt.Errorf("json params err: %v", err)
	}

	neList := s.neInfoService.SelectList(neModel.NeInfo{}, true, false)
	for _, neInfo := range neList {
		if neInfo.CreateTime == 0 {
			continue
		}
		neTypeAndId := fmt.Sprintf("%s_%s", neInfo.NeType, neInfo.NeId)
		// 网元在线状态
		isOnline := parse.Boolean(neInfo.ServerState["online"])
		// 告警ID
		params.AlarmId = fmt.Sprintf("%d%d", constants.ALARM_STATE_CHECK, neInfo.CreateTime)
		// 检查网元告警ID是否唯一
		alarmIdArr := s.alarmService.Find(neDataModel.Alarm{
			NeType:  neInfo.NeType,
			NeId:    neInfo.RmUID,
			AlarmId: params.AlarmId,
		})
		// 告警状态
		alarmStatus := ""
		if len(alarmIdArr) > 0 {
			alarmStatus = fmt.Sprint(alarmIdArr[0].AlarmStatus)
		}
		// 在线且状态为活动告警
		if isOnline && alarmStatus == "1" {
			// 进行清除
			clearAlarm, err := s.alarmClear(neInfo, alarmIdArr[0])
			if err != nil {
				result[neTypeAndId] = err.Error()
				continue
			}
			groupID := fmt.Sprintf("%s_%s_%s", wsService.GROUP_ALARM, neInfo.NeType, neInfo.NeId)
			s.wsSendService.ByGroupID(groupID, clearAlarm)
			result[neTypeAndId] = "alarm clear"
		}

		// 不在线
		if !isOnline && alarmStatus == "" {
			// 进行新增
			newAlarm, err := s.alarmNew(neInfo, params)
			if err != nil {
				result[neTypeAndId] = err.Error()
				continue
			}
			groupID := fmt.Sprintf("%s_%s_%s", wsService.GROUP_ALARM, neInfo.NeType, neInfo.NeId)
			s.wsSendService.ByGroupID(groupID, newAlarm)
			result[neTypeAndId] = "alarm new"
		}
	}

	// 返回结果，用于记录执行结果
	return result, nil
}

// alarmClear 清除告警
func (s NeAlarmStateCheckProcessor) alarmClear(neInfo neModel.NeInfo, v neDataModel.Alarm) (neDataModel.Alarm, error) {
	// 变更告警ID为告警清除ID
	v.AlarmId = fmt.Sprintf("%s%d", v.AlarmCode, v.EventTime.UnixMilli())
	v.AlarmStatus = "0"
	// 告警清除
	clearTime := time.UnixMilli(neInfo.UpdateTime)
	v.ClearType = "1"
	v.ClearTime = &clearTime
	v.ClearUser = "system"
	rows := s.alarmService.Update(v)
	if rows > 0 {
		return v, nil
	}
	return neDataModel.Alarm{}, fmt.Errorf("clear alarm fail")
}

// alarmNew 新增告警
func (s NeAlarmStateCheckProcessor) alarmNew(neInfo neModel.NeInfo, v alarmParams) (neDataModel.Alarm, error) {
	// seq 告警序号
	lastSeq := s.alarmService.FindAlarmSeqLast(neInfo.NeType, neInfo.RmUID)
	lastTime := neInfo.UpdateTime // 网元最后更新时间
	if lastTime < neInfo.CreateTime {
		lastTime = time.Now().UnixMilli()
	}
	alarm := neDataModel.Alarm{
		NeType:            neInfo.NeType,
		NeId:              neInfo.RmUID, // neInfo.NeId,
		NeName:            neInfo.NeName,
		Province:          neInfo.Province,
		PvFlag:            neInfo.PvFlag,
		AlarmSeq:          fmt.Sprint(lastSeq + 1),
		AlarmId:           v.AlarmId,
		AlarmTitle:        v.AlarmTitle,
		AlarmCode:         fmt.Sprint(constants.ALARM_STATE_CHECK),
		EventTime:         time.UnixMilli(lastTime),
		AlarmType:         v.AlarmType,
		OrigSeverity:      v.OrigSeverity,
		PerceivedSeverity: v.OrigSeverity,
		ObjectUid:         neInfo.RmUID,
		ObjectName:        "NE State",
		ObjectType:        "state",
		LocationInfo:      "NE State: Heartbeat",
		AlarmStatus:       "1", // 活动告警
		SpecificProblem:   v.SpecificProblem,
		SpecificProblemId: v.SpecificProblemID,
		AddInfo:           v.AddInfo,
		Counter:           "0",
		AckState:          "0",
		ClearType:         "0",
	}
	insertId := s.alarmService.InsertAndForword(alarm)
	if insertId != "" {
		alarm.ID = insertId
		return alarm, nil
	}
	return neDataModel.Alarm{}, fmt.Errorf("new alarm fail")
}
