package ne_alarm_state_check_license

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

	"be.ems/src/framework/constants"
	"be.ems/src/framework/cron"
	"be.ems/src/framework/logger"
	"be.ems/src/framework/utils/parse"
	"github.com/tsmask/go-oam"

	neModel "be.ems/src/modules/ne/model"
	neService "be.ems/src/modules/ne/service"
	oamService "be.ems/src/modules/oam/service"
)

var NewProcessor = &NeAlarmStateCheckLicenseProcessor{
	neInfoService: neService.NewNeInfo,
	count:         0,
}

// NeAlarmStateCheckLicenseProcessor 网元告警License到期检查
type NeAlarmStateCheckLicenseProcessor struct {
	neInfoService *neService.NeInfo // 网元信息服务
	count         int               // 执行次数
}

// alarmParams 告警参数
type alarmParams struct {
	AlarmTitle        string `json:"alarmTitle"`        // NE State Check Alarm License
	AlarmType         string `json:"alarmType"`         // EquipmentAlarm=2
	OrigSeverity      string `json:"origSeverity"`      // Major=2
	SpecificProblem   string `json:"specificProblem"`   // Alarm Cause: License received from target NE is about to expire
	SpecificProblemID string `json:"specificProblemId"` // AC10200
	AddInfo           string `json:"addInfo"`           // 告警补充信息
	DayLt             int64  `json:"dayLt"`             // 天数小于，默认30天

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

func (s *NeAlarmStateCheckLicenseProcessor) Execute(data any) (any, error) {
	s.count++ // 执行次数加一
	options := data.(cron.JobData)
	sysJob := options.SysJob
	logger.Infof("重复:%v 任务ID:%d  执行次数:%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)
	}
	// 检查参数值
	if params.DayLt == 0 {
		params.DayLt = 30
	}

	neList := s.neInfoService.Find(neModel.NeInfo{}, true, false)
	for _, neInfo := range neList {
		if neInfo.CreateTime == 0 {
			continue
		}

		// 网元在线状态
		isOnline := parse.Boolean(neInfo.ServerState["online"])
		if !isOnline {
			continue
		}

		// 检查状态
		err := s.cheackState(neInfo.ServerState, params.DayLt)
		if err == nil {
			continue
		}
		addInfo := params.AddInfo
		if addInfo != "" {
			addInfo = addInfo + ", " + err.Error()
		} else {
			addInfo = err.Error()
		}

		// 告警ID
		params.AlarmId = fmt.Sprintf("%d%d", constants.ALARM_LICENSE_CHECK, neInfo.CreateTime)
		// 创建告警
		alarm := oam.Alarm{
			NeUid:             neInfo.RmUID,                  // 网元唯一标识
			AlarmTime:         time.Now().UnixMilli(),        // 事件产生时间
			AlarmId:           params.AlarmId,                // 告警ID 唯一，清除时对应
			AlarmCode:         constants.ALARM_LICENSE_CHECK, // 告警状态码
			AlarmType:         params.AlarmType,              // 告警类型
			AlarmTitle:        params.AlarmTitle,             // 告警标题
			PerceivedSeverity: params.OrigSeverity,           // 告警级别
			AlarmStatus:       oam.ALARM_STATUS_ACTIVE,       // 告警状态
			SpecificProblem:   params.SpecificProblem,        // 告警问题原因
			SpecificProblemID: params.SpecificProblemID,      // 告警问题原因ID
			AddInfo:           addInfo,                       // 告警辅助信息
			LocationInfo:      "NE License: Heartbeat",       // 告警定位信息
		}
		if err = oamService.NewAlarm.Resolve(alarm); err == nil {
			result[neInfo.RmUID] = "license alarm"
		}
	}

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

// cheackState 检查网元状态
func (s NeAlarmStateCheckLicenseProcessor) cheackState(state map[string]any, dayLt int64) error {
	expire := fmt.Sprint(state["expire"])
	if expire == "" || expire == "<nil>" || expire == "-" || expire == "2099-12-31" {
		return nil
	}

	// 解析过期时间
	expireTime, err := time.Parse("2006-01-02", expire)
	if err != nil {
		return fmt.Errorf("parse expire time error: %v", err)
	}

	// 计算距离天数
	daysLeft := time.Until(expireTime).Hours() / 24
	expireDay := int64(math.Ceil(daysLeft))
	if expireDay <= dayLt {
		if expireDay <= 0 {
			return fmt.Errorf("license will expire after today")
		}
		return fmt.Errorf("license will expire in %d days", expireDay)
	}
	return nil
}
