package repository

import (
	"fmt"
	"sort"
	"strings"
	"time"

	"be.ems/src/framework/database/db"
	"be.ems/src/framework/logger"
	"be.ems/src/modules/ne_data/model"
)

// 实例化数据层 CDREvent 结构体
var NewCDREvent = &CDREvent{}

// CDREvent CDR会话事件 数据层处理
type CDREvent struct{}

// SelectByPage 分页查询集合
func (r CDREvent) SelectByPage(neType string, query map[string]string) ([]model.CDREvent, int64) {
	// 表名
	tableName := fmt.Sprintf("cdr_event_%s", strings.ToLower(neType))
	tx := db.DB("").Table(tableName).Model(&model.CDREvent{})
	// 查询条件拼接
	if v, ok := query["rmUID"]; ok && v != "" {
		tx = tx.Where("rm_uid = ?", v)
	}
	if v, ok := query["beginTime"]; ok && v != "" {
		if len(v) == 10 {
			v = v + "000"
		}
		tx = tx.Where("created_at >= ?", v)
	}
	if v, ok := query["endTime"]; ok && v != "" {
		if len(v) == 10 {
			v = v + "000"
		}
		tx = tx.Where("created_at <= ?", v)
	}

	// 各个网元特殊查询条件
	switch neType {
	case "SMSC":
		if v, ok := query["callerParty"]; ok && v != "" {
			tx = tx.Where("JSON_EXTRACT(cdr_json, '$.callerParty') like ?", fmt.Sprintf("%%%s%%", v))
		}
		if v, ok := query["calledParty"]; ok && v != "" {
			tx = tx.Where("JSON_EXTRACT(cdr_json, '$.calledParty') like ?", fmt.Sprintf("%%%s%%", v))
		}
		if v, ok := query["recordType"]; ok && v != "" {
			recordTypes := strings.Split(v, ",")
			var querytrArr []string
			for _, recordType := range recordTypes {
				querytrArr = append(querytrArr, fmt.Sprintf("JSON_EXTRACT(cdr_json, '$.recordType') = '%s'", recordType))
			}
			tx = tx.Where(fmt.Sprintf("( %s )", strings.Join(querytrArr, " OR ")))
		}
	case "SMF":
		if v, ok := query["recordType"]; ok && v != "" {
			tx = tx.Where("JSON_EXTRACT(cdr_json, '$.recordType') = ?", v)
		}
		if v, ok := query["subscriberID"]; ok && v != "" {
			tx = tx.Where("JSON_EXTRACT(cdr_json, '$.subscriberIdentifier.subscriptionIDData') like ?", fmt.Sprintf("%%%s%%", v))
		}
		if v, ok := query["dnn"]; ok && v != "" {
			tx = tx.Where("JSON_EXTRACT(cdr_json, '$.pDUSessionChargingInformation.dNNID') = ?", v)
		}
	case "SGWC":
		if v, ok := query["imsi"]; ok && v != "" {
			tx = tx.Where("JSON_EXTRACT(cdr_json, '$.servedIMSI') like ?", fmt.Sprintf("%%%s%%", v))
		}
		if v, ok := query["msisdn"]; ok && v != "" {
			tx = tx.Where("JSON_EXTRACT(cdr_json, '$.servedMSISDN') like ?", fmt.Sprintf("%%%s%%", v))
		}
	case "IMS":
		if v, ok := query["recordType"]; ok && v != "" {
			tx = tx.Where("JSON_EXTRACT(cdr_json, '$.recordType') = ?", fmt.Sprintf("'%s'", v))
		}
		if v, ok := query["callerParty"]; ok && v != "" {
			tx = tx.Where("JSON_EXTRACT(cdr_json, '$.callerParty') like ?", fmt.Sprintf("%%%s%%", v))
		}
		if v, ok := query["calledParty"]; ok && v != "" {
			tx = tx.Where("JSON_EXTRACT(cdr_json, '$.calledParty') like ?", fmt.Sprintf("%%%s%%", v))
		}
	}

	var total int64 = 0
	rows := []model.CDREvent{}

	// 查询数量 长度为0直接返回
	if err := tx.Count(&total).Error; err != nil || total <= 0 {
		return rows, total
	}

	// 分页
	if query["pageNum"] != "" && query["pageSize"] != "" {
		pageNum, pageSize := db.PageNumSize(query["pageNum"], query["pageSize"])
		tx = tx.Offset(int(pageNum * pageSize)).Limit(int(pageSize))
	}

	// 查询数据
	if err := tx.Find(&rows).Error; err != nil {
		logger.Errorf("query err => %v", err)
	}

	// 排序
	if v, ok := query["sortField"]; ok && v != "" {
		sortField := v
		sortOrder := "asc"
		if o, ok := query["sortOrder"]; ok && o != "" {
			if o == "desc" {
				sortOrder = "desc"
			} else {
				sortOrder = "asc"
			}
		}
		sort.SliceStable(rows, func(i, j int) bool {
			// 支持的排序字段映射
			fieldGetters := map[string]func(*model.CDREvent) any{
				"id":        func(row *model.CDREvent) any { return row.ID },
				"timestamp": func(row *model.CDREvent) any { return row.Timestamp },
				// 可添加更多支持的字段
			}

			// 获取字段 getter 函数
			getter, ok := fieldGetters[sortField]
			if !ok {
				// 非法字段，使用默认排序（id升序）
				return rows[i].ID < rows[j].ID
			}

			// 获取比较值
			valI, valJ := getter(&rows[i]), getter(&rows[j])

			// 根据字段类型进行比较
			switch v := valI.(type) {
			case int64:
				if sortOrder == "desc" {
					return v > valJ.(int64)
				}
				return v < valJ.(int64)
			case string:
				if sortOrder == "desc" {
					return v > valJ.(string)
				}
				return v < valJ.(string)
			default:
				// 不支持的字段类型，使用默认排序
				return rows[i].ID < rows[j].ID
			}
		})
	}

	return rows, total
}

// SelectByIds 通过ID查询
func (r CDREvent) SelectByIds(neType string, ids []int64) []model.CDREvent {
	rows := []model.CDREvent{}
	if len(ids) <= 0 {
		return rows
	}
	// 表名
	tableName := fmt.Sprintf("cdr_event_%s", strings.ToLower(neType))
	tx := db.DB("").Table(tableName).Model(&model.CDREvent{})
	// 构建查询条件
	tx = tx.Where("id in ?", ids)
	// 查询数据
	if err := tx.Find(&rows).Error; err != nil {
		logger.Errorf("query find err => %v", err.Error())
		return rows
	}
	return rows
}

// DeleteByIds 批量删除信息
func (r CDREvent) DeleteByIds(neType string, ids []int64) int64 {
	if len(ids) <= 0 {
		return 0
	}
	// 表名
	tableName := fmt.Sprintf("cdr_event_%s", strings.ToLower(neType))
	tx := db.DB("").Table(tableName).Where("id in ?", ids)
	if err := tx.Delete(&model.CDREvent{}).Error; err != nil {
		logger.Errorf("delete err => %v", err.Error())
		return 0
	}
	return tx.RowsAffected
}

// Insert 新增信息 返回新增数据ID
func (r CDREvent) Insert(param model.CDREvent) int64 {
	if param.NeType == "" {
		return 0
	}
	if param.CreatedAt == 0 {
		param.CreatedAt = time.Now().UnixMilli()
	}
	// 表名
	tableName := fmt.Sprintf("cdr_event_%s", strings.ToLower(param.NeType))
	// 执行插入
	if err := db.DB("").Table(tableName).Create(&param).Error; err != nil {
		logger.Errorf("insert err => %v", err.Error())
		return 0
	}
	return param.ID
}
