package cdr

import (
	"fmt"
	"net/http"
	"strings"

	"be.ems/lib/core/ctx"
	"be.ems/lib/dborm"
	"be.ems/lib/log"
	"be.ems/lib/services"
	"be.ems/restagent/config"
	neService "be.ems/src/modules/network_element/service"
	wsService "be.ems/src/modules/ws/service"
)

var (
	UriCDREvent = config.DefaultUriPrefix + "/cdrManagement/v1/elementType/{elementTypeValue}/objectType/cdrEvent"
	UriCDRFile  = config.DefaultUriPrefix + "/cdrManagement/v1/elementType/{elementTypeValue}/objectType/cdrFile"

	CustomUriCDREvent = config.UriPrefix + "/cdrManagement/v1/elementType/{elementTypeValue}/objectType/cdrEvent"
	CustomUriCDRFile  = config.UriPrefix + "/cdrManagement/v1/elementType/{elementTypeValue}/objectType/cdrFile"
)

// CDREvent CDR数据表格结构体
type CDREvent struct {
	NeType    string         `json:"neType" xorm:"ne_type"`
	NeName    string         `json:"neName" xorm:"ne_name"`
	RmUID     string         `json:"rmUID" xorm:"rm_uid"`
	Timestamp int            `json:"timestamp" xorm:"timestamp"`
	CDR       map[string]any `json:"CDR" xorm:"cdr_json"`
}

// PostCDREventFrom 接收CDR数据请求
func PostCDREventFrom(w http.ResponseWriter, r *http.Request) {
	log.Info("PostCDREventFrom processing... ")
	neType := ctx.GetParam(r, "elementTypeValue")
	var cdrEvent CDREvent
	if err := ctx.ShouldBindJSON(r, &cdrEvent); err != nil {
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	}

	neTypeLower := strings.ToLower(cdrEvent.NeType)
	if neType == "" || neType != neTypeLower {
		services.ResponseInternalServerError500ProcessError(w, fmt.Errorf("inconsistent network element types"))
		return
	}

	tableName := fmt.Sprintf("cdr_event_%s", neTypeLower)
	affected, err := dborm.XormInsertTableOne(tableName, cdrEvent)
	if err != nil && affected <= 0 {
		log.Error("Failed to insert "+tableName, err)
		services.ResponseInternalServerError500ProcessError(w, err)
		return
	}

	// 发送到匹配的网元
	neInfo := neService.NewNeInfo.SelectNeInfoByRmuid(cdrEvent.RmUID)
	if neInfo.RmUID == cdrEvent.RmUID {
		// 推送到ws订阅组
		switch neInfo.NeType {
		case "IMS":
			if v, ok := cdrEvent.CDR["recordType"]; ok && (v == "MOC" || v == "MTSM") {
				wsService.NewWSSend.ByGroupID(wsService.GROUP_IMS_CDR+neInfo.NeId, cdrEvent)
			}
		case "SMF":
			wsService.NewWSSend.ByGroupID(wsService.GROUP_SMF_CDR+neInfo.NeId, cdrEvent)
		case "SMSC":
			wsService.NewWSSend.ByGroupID(wsService.GROUP_SMSC_CDR+neInfo.NeId, cdrEvent)
		}
	}

	services.ResponseStatusOK204NoContent(w)
}
