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"
)

// 实例化服务层 UDMVOIPUser 结构体
var NewUDMVOIPUser = &UDMVOIPUser{
	udmVOIPRepository: repository.NewUDMVOIPUser,
}

// UDMVOIP信息 服务层处理
type UDMVOIPUser struct {
	// UDMVOIP信息数据信息
	udmVOIPRepository *repository.UDMVOIPUser
}

// dataByRedis UDMVOIP用户 db:0 中 voip:*
func (r UDMVOIPUser) dataByRedis(username, neId string) []model.UDMVOIPUser {
	arr := []model.UDMVOIPUser{}
	key := fmt.Sprintf("voip:%s", username)
	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)

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

	for k, m := range mkv {
		// 跳过-号数据 voip:360000100000130
		username, hasPrefix := strings.CutPrefix(k, "voip:")
		if strings.Contains(username, "-") || !hasPrefix {
			continue
		}
		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.UDMVOIPUser{
			CreateTime: createTime,
			NeId:       neId,
			UserName:   username,
			Password:   m["password"],
		}
		arr = append(arr, a)
	}
	return arr
}

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

// ParseInfo 解析单个用户userName信息 data从命令MML得到的结果
func (r UDMVOIPUser) ParseInfo(neId string, data map[string]string) model.UDMVOIPUser {
	u := model.UDMVOIPUser{
		NeId:     neId,
		UserName: data["username"],
		Password: data["password"],
	}
	// 赋予ID
	item := r.udmVOIPRepository.SelectByUserNameAndNeID(u.UserName, neId)
	if item.ID != "" {
		u.ID = item.ID
	}
	return u
}

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

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

// Insert 从数据中读取后删除username再存入数据库
func (r UDMVOIPUser) Insert(neId string, username string) int64 {
	uArr := r.dataByRedis(username, neId)
	if len(uArr) > 0 {
		r.udmVOIPRepository.Delete(username, neId)
		return r.udmVOIPRepository.Inserts(uArr)
	}
	return 0
}

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

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

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

// Delete 删除单个不重新加载
func (r UDMVOIPUser) Delete(username, neId string) int64 {
	return r.udmVOIPRepository.Delete(username, neId)
}

// LoadData 重新加载从username开始num的数据
func (r UDMVOIPUser) LoadData(neId, username, num string) {
	startUserName, _ := strconv.ParseInt(username, 10, 64)
	subNum, _ := strconv.ParseInt(num, 10, 64)
	var i int64
	for i = 0; i < subNum; i++ {
		keyUserName := fmt.Sprintf("%d", startUserName+i)
		// 删除原数据
		r.udmVOIPRepository.Delete(keyUserName, neId)
		// 加载数据
		arr := r.dataByRedis(keyUserName, neId)
		if len(arr) < 1 {
			continue
		}
		r.udmVOIPRepository.Inserts(arr)
	}
}
