package service

import (
	"fmt"
	"strconv"
	"strings"
	"time"

	"be.ems/src/framework/database/redis"
	"be.ems/src/framework/utils/date"
	neService "be.ems/src/modules/ne/service"
	"be.ems/src/modules/ne_data/model"
	"be.ems/src/modules/ne_data/repository"
)

// 实例化服务层 UDMVolteIMSUser 结构体
var NewUDMVolteIMSUser = &UDMVolteIMSUser{
	udmVolteIMSRepository: repository.NewUDMVolteIMSUser,
}

// UDMVolteIMS信息 服务层处理
type UDMVolteIMSUser struct {
	// UDMVolteIMS信息数据信息
	udmVolteIMSRepository *repository.UDMVolteIMSUser
}

// dataByRedis UDMVolteIMS用户 db:0 中 volte:*
func (r UDMVolteIMSUser) dataByRedis(imsi, neId string) []model.UDMVolteIMSUser {
	arr := []model.UDMVolteIMSUser{}
	key := fmt.Sprintf("volte:%s", imsi)
	source := fmt.Sprintf("UDM_%s", neId)

	// 网元主机的Redis客户端
	redisClient, err := neService.NewNeInfo.NeRunRedisClient("UDM", neId)
	if err != nil {
		return arr
	}
	defer func() {
		redisClient.Close()
		redis.ConnectPush(source, nil)
	}()
	redis.ConnectPush(source, redisClient.Client)

	volteArr, err := redis.GetKeys(source, key)
	if err != nil {
		return arr
	}
	mkv, err := redis.GetHashBatch(source, volteArr)
	if err != nil {
		return arr
	}

	for k, m := range mkv {
		// volte:360000100000130:8612300000130
		keys := strings.Split(k, ":")
		if len(keys) != 3 {
			continue
		}

		// "110011200004217@ims.mnc001.mcc110.3gppnetwork.org"
		vni := ""
		impiParts := strings.Split(m["impi"], "@")
		if len(impiParts) > 1 {
			vni = impiParts[1]
		}
		var createTime int64 = 0
		if v, ok := m["create_time"]; ok {
			t := date.ParseStrToDate(v, date.YYYY_MM_DDTHH_MM_SSZ)
			createTime = t.UnixMilli()
		} else {
			createTime = time.Now().UnixMilli()
		}

		a := model.UDMVolteIMSUser{
			CreateTime: createTime,
			NeId:       neId,
			IMSI:       keys[1],
			MSISDN:     keys[2],
			Tag:        m["tag"], // volte = tag
			VNI:        vni,
		}
		arr = append(arr, a)
	}
	return arr
}

// ResetData 重置VolteIMS用户数据，清空数据库重新同步Redis数据
func (r UDMVolteIMSUser) ResetData(neId string) int64 {
	authArr := r.dataByRedis("*", neId)
	// 数据清空后添加
	go r.udmVolteIMSRepository.ClearAndInsert(neId, authArr)
	return int64(len(authArr))
}

// ParseInfo 解析单个用户imsi信息 data从命令MML得到的结果
func (r UDMVolteIMSUser) ParseInfo(neId string, data map[string]string) model.UDMVolteIMSUser {
	// "110011200004217@ims.mnc001.mcc110.3gppnetwork.org"
	vni := ""
	impiParts := strings.Split(data["impi"], "@")
	if len(impiParts) > 1 {
		vni = impiParts[1]
	}
	if vni == "" {
		return model.UDMVolteIMSUser{}
	}

	u := model.UDMVolteIMSUser{
		NeId:   neId,
		IMSI:   data["imsi"],
		MSISDN: data["msisdn"],
		Tag:    data["volte_tag"],
		VNI:    vni,
	}
	// 赋予ID
	item := r.udmVolteIMSRepository.SelectByIMSIAndMSISDNAndNeID(u.IMSI, u.MSISDN, neId)
	if item.ID != "" {
		u.ID = item.ID
	}
	return u
}

// FindByPage 分页查询数据库
func (r UDMVolteIMSUser) FindByPage(query map[string]string) ([]model.UDMVolteIMSUser, int64) {
	return r.udmVolteIMSRepository.SelectPage(query)
}

// Find 查询数据库
func (r UDMVolteIMSUser) Find(u model.UDMVolteIMSUser) []model.UDMVolteIMSUser {
	return r.udmVolteIMSRepository.SelectList(u)
}

// InsertByIMSI 从数据中读取后删除imsi再存入数据库
// imsi长度15
func (r UDMVolteIMSUser) InsertByIMSI(imsi, neId string) int64 {
	uArr := r.dataByRedis(imsi+":*", neId)
	if len(uArr) > 0 {
		r.udmVolteIMSRepository.Delete(imsi, neId)
		return r.udmVolteIMSRepository.Inserts(uArr)
	}
	return 0
}

// InsertData 导入文件数据 dataType目前两种：txt/csv
func (r UDMVolteIMSUser) InsertData(neId, dataType string, data any) int64 {
	// imsi截取前缀,重新获取部分数据
	prefixes := make(map[string]struct{})

	if dataType == "csv" {
		for _, v := range data.([]map[string]string) {
			imsi := v["imsi"]
			if len(imsi) < 6 {
				continue
			}
			prefix := imsi[:len(imsi)-4]
			prefixes[prefix] = struct{}{}
		}
	}
	if dataType == "txt" {
		for _, v := range data.([][]string) {
			imsi := v[0]
			if len(imsi) < 6 {
				continue
			}
			prefix := imsi[:len(imsi)-4]
			prefixes[prefix] = struct{}{}
		}
	}

	// 根据前缀重新加载插入
	var num int64 = 0
	for prefix := range prefixes {
		// 直接删除前缀的记录
		r.udmVolteIMSRepository.DeletePrefixByIMSI(prefix, neId)
		// keys voip:4600001000004*
		arr := r.dataByRedis(prefix+"*", neId)
		if len(arr) > 0 {
			num += r.udmVolteIMSRepository.Inserts(arr)
		}
	}
	return num
}

// Delete 删除单个不重新加载
func (r UDMVolteIMSUser) Delete(imsi, neId string) int64 {
	return r.udmVolteIMSRepository.Delete(imsi, neId)
}

// LoadData 重新加载从imsi开始num的数据
func (r UDMVolteIMSUser) LoadData(neId, imsiOrMsisdn, num string) {
	startIMSIOrMsisdn, _ := strconv.ParseInt(imsiOrMsisdn, 10, 64)
	subNum, _ := strconv.ParseInt(num, 10, 64)
	var i int64
	for i = 0; i < subNum; i++ {
		keyIMSI := fmt.Sprintf("%015d", startIMSIOrMsisdn+i)
		if !strings.HasPrefix(imsiOrMsisdn, "0") {
			keyIMSI = fmt.Sprintf("%d", startIMSIOrMsisdn+i)
		}
		// 删除原数据
		r.udmVolteIMSRepository.Delete(keyIMSI, neId)
		// 加载数据
		arr := r.dataByRedis(keyIMSI+":*", neId)
		if len(arr) < 1 {
			continue
		}
		r.udmVolteIMSRepository.Inserts(arr)
	}
}
