package service

import (
	"encoding/json"
	"fmt"
	"strconv"

	"be.ems/src/framework/logger"
	"be.ems/src/framework/utils/file"
	"be.ems/src/framework/utils/parse"
	"be.ems/src/modules/network_data/model"
	"be.ems/src/modules/network_data/repository"
)

// 实例化数据层 CDREventSMF 结构体
var NewCDREventSMF = &CDREventSMF{
	cdrEventRepository: repository.NewCDREventSMF,
}

// CDREventSMF CDR会话事件SMF 服务层处理
type CDREventSMF struct {
	cdrEventRepository *repository.CDREventSMF // CDR会话事件数据信息
}

// SelectPage 根据条件分页查询
func (r *CDREventSMF) SelectPage(querys model.CDREventSMFQuery) ([]model.CDREventSMF, int64) {
	return r.cdrEventRepository.SelectByPage(querys)
}

// DeleteByIds 批量删除信息
func (r *CDREventSMF) DeleteByIds(cdrIds []string) (int64, error) {
	// 检查是否存在
	ids := r.cdrEventRepository.SelectByIds(cdrIds)
	if len(ids) <= 0 {
		return 0, fmt.Errorf("not data")
	}

	if len(ids) == len(cdrIds) {
		rows := r.cdrEventRepository.DeleteByIds(cdrIds)
		return rows, nil
	}
	// 删除信息失败！
	return 0, fmt.Errorf("delete fail")
}

// ExportXlsx 导出数据到 xlsx 文件
func (r CDREventSMF) ExportXlsx(rows []model.CDREventSMF, fileName string) (string, error) {
	// 第一行表头标题
	headerCells := map[string]string{
		"A1": "ID",
		"B1": "Charging ID",
		"C1": "NE Name",
		"D1": "Resource Unique ID",
		"E1": "Subscriber ID Data",
		"F1": "Subscriber ID Type",
		"G1": "Data Volume Uplink",
		"H1": "Data Volume Downlink",
		"I1": "Data Total Volume",
		"J1": "Duration",
		"K1": "Invocation Time",
		"L1": "User Identifier",
		"M1": "SSC Mode",
		"N1": "DNN ID",
		"O1": "PDU Type",
		"P1": "RAT Type",
		"Q1": "PDU IPv4 Address",
		"R1": "Network Function IPv4",
		"S1": "PDU IPv6 Address Swith Prefix",
		"T1": "Record Network Function ID",
		"U1": "Record Type",
		"V1": "Record Opening Time",
	}
	// 从第二行开始的数据
	dataCells := make([]map[string]any, 0)

	for i, row := range rows {
		idx := strconv.Itoa(i + 2)
		// 解析 JSON 字符串为 map
		var cdrJSON map[string]interface{}
		err := json.Unmarshal([]byte(row.CDRJSONStr), &cdrJSON)
		if err != nil {
			logger.Warnf("CDRExport Error parsing JSON: %s", err.Error())
			continue
		}
		// 计费ID
		chargingID := ""
		if v, ok := cdrJSON["chargingID"]; ok && v != nil {
			chargingID = fmt.Sprint(parse.Number(v))
		}
		// 订阅 ID 类型
		subscriptionIDType := "-"
		// 订阅 ID 数据
		subscriptionIDData := "-"
		if v, ok := cdrJSON["subscriberIdentifier"]; ok && v != nil {
			if sub, subOk := v.(map[string]any); subOk && sub != nil {
				subscriptionIDType = sub["subscriptionIDType"].(string)
				subscriptionIDData = sub["subscriptionIDData"].(string)
			}
		}

		// 网络功能 IPv4 地址
		networkFunctionIPv4Address := ""
		if v, ok := cdrJSON["nFunctionConsumerInformation"]; ok && v != nil {
			if conInfo, conInfoOk := v.(map[string]any); conInfoOk && conInfo != nil {
				networkFunctionIPv4Address = conInfo["networkFunctionIPv4Address"].(string)
			}
		}

		// 数据量上行链路
		var dataVolumeUplink int64 = 0
		// 数据量下行链路
		var dataVolumeDownlink int64 = 0
		// 数据总量
		var dataTotalVolume int64 = 0
		if v, ok := cdrJSON["listOfMultipleUnitUsage"]; ok && v != nil {
			usageList := v.([]any)
			if len(usageList) > 0 {
				for _, used := range usageList {
					usedUnit := used.(map[string]any)
					usedUnitList := usedUnit["usedUnitContainer"].([]any)
					if len(usedUnitList) > 0 {
						for _, data := range usedUnitList {
							udata := data.(map[string]any)
							if dup, dupOk := udata["dataVolumeUplink"]; dupOk {
								dataVolumeUplink += parse.Number(dup)
							}
							if ddown, ddownOk := udata["dataVolumeDownlink"]; ddownOk {
								dataVolumeDownlink += parse.Number(ddown)
							}
							if dt, dtOk := udata["dataTotalVolume"]; dtOk {
								dataTotalVolume += parse.Number(dt)
							}
						}
					}
				}
			}
		}
		// 时长
		duration := "-"
		if v, ok := cdrJSON["duration"]; ok && v != nil {
			duration = fmt.Sprint(parse.Number(v))
		}
		// 调用时间
		invocationTimestamp := ""
		if v, ok := cdrJSON["invocationTimestamp"]; ok && v != nil {
			invocationTimestamp = v.(string)
		}
		// 记录打开时间
		User_Identifier := ""
		SSC_Mode := ""
		RAT_Type := ""
		DNN_ID := ""
		PDU_Type := ""
		PDU_IPv4 := ""
		PDU_IPv6 := ""
		if v, ok := cdrJSON["pDUSessionChargingInformation"]; ok && v != nil {
			pduInfo := v.(map[string]any)

			if v, ok := pduInfo["userIdentifier"]; ok && v != nil {
				User_Identifier = v.(string)
			}
			if v, ok := pduInfo["sSCMode"]; ok && v != nil {
				SSC_Mode = v.(string)
			}
			if v, ok := pduInfo["rATType"]; ok && v != nil {
				RAT_Type = v.(string)
			}
			if v, ok := pduInfo["dNNID"]; ok && v != nil {
				DNN_ID = v.(string)
			}
			if v, ok := pduInfo["pDUType"]; ok && v != nil {
				PDU_Type = v.(string)
			}
			if v, ok := pduInfo["pDUAddress"]; ok && v != nil {
				pDUAddress := v.(map[string]any)
				if addr, ok := pDUAddress["pDUIPv4Address"]; ok && addr != nil {
					PDU_IPv4 = addr.(string)
				}
				if addr, ok := pDUAddress["pDUIPv6AddresswithPrefix"]; ok && addr != nil {
					PDU_IPv6 = addr.(string)
				}
			}
		}

		// 记录网络参数ID
		recordNFID := ""
		if v, ok := cdrJSON["recordingNetworkFunctionID"]; ok && v != nil {
			recordNFID = v.(string)
		}

		//记录开始时间
		recordOpeningTime := ""
		if v, ok := cdrJSON["recordOpeningTime"]; ok && v != nil {
			recordOpeningTime = v.(string)
		}

		//记录类型
		recordType := ""
		if v, ok := cdrJSON["recordType"]; ok && v != nil {
			recordType = v.(string)
		}

		dataCells = append(dataCells, map[string]any{
			"A" + idx: row.ID,
			"B" + idx: chargingID,
			"C" + idx: row.NeName,
			"D" + idx: row.RmUID,
			"E" + idx: subscriptionIDData,
			"F" + idx: subscriptionIDType,
			"G" + idx: dataVolumeUplink,
			"H" + idx: dataVolumeDownlink,
			"I" + idx: dataTotalVolume,
			"J" + idx: duration,
			"K" + idx: invocationTimestamp,
			"L" + idx: User_Identifier,
			"M" + idx: SSC_Mode,
			"N" + idx: DNN_ID,
			"O" + idx: PDU_Type,
			"P" + idx: RAT_Type,
			"Q" + idx: PDU_IPv4,
			"R" + idx: networkFunctionIPv4Address,
			"S" + idx: PDU_IPv6,
			"T" + idx: recordNFID,
			"U" + idx: recordType,
			"V" + idx: recordOpeningTime,
		})
	}

	// 导出数据表格
	return file.WriteSheet(headerCells, dataCells, fileName, "")
}
