package service

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

	"be.ems/src/framework/i18n"
	"be.ems/src/framework/logger"
	"be.ems/src/framework/utils/date"
	"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"
	sysService "be.ems/src/modules/system/service"
)

// 实例化数据层 CDREventIMS 结构体
var NewCDREventIMS = &CDREventIMS{
	cdrEventIMSRepository: repository.NewCDREventIMS,
}

// CDREventImpl CDR会话事件IMS 服务层处理
type CDREventIMS struct {
	cdrEventIMSRepository *repository.CDREventIMS // CDR会话事件数据信息
}

// SelectPage 根据条件分页查询
func (r *CDREventIMS) SelectPageMT(querys model.CDREventIMSQuery) map[string]any {
	return r.cdrEventIMSRepository.SelectPage(querys)
}

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

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

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

// ExportXlsx 导出数据到 xlsx 文件
func (r CDREventIMS) ExportXlsx(rows []model.CDREventIMS, fileName, language string) (string, error) {
	// 第一行表头标题
	headerCells := map[string]string{
		"A1": "ID",
		"B1": "Record Behavior",
		"C1": "Type",
		"D1": "Caller",
		"E1": "Called",
		"F1": "Duration",
		"G1": "Result Code",
		"H1": "Result Cause",
		"I1": "Call Start Time",
		"J1": "Hangup Time",
	}
	// 读取字典数据 CDR SIP响应代码类别类型
	dictCDRSipCode := sysService.NewSysDictData.SelectDictDataByType("cdr_sip_code")
	dictCDRSipCodeCause := sysService.NewSysDictData.SelectDictDataByType("cdr_sip_code_cause")
	// 读取字典数据 CDR 呼叫类型
	dictCDRCallType := sysService.NewSysDictData.SelectDictDataByType("cdr_call_type")
	// 从第二行开始的数据
	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
		}
		// 记录类型
		recordType := ""
		if v, ok := cdrJSON["recordType"]; ok && v != nil {
			recordType = v.(string)
		}
		// 呼叫类型
		callType := "sms"
		callTypeLable := "SMS"
		if v, ok := cdrJSON["callType"]; ok && v != nil {
			callType = v.(string)
			for _, v := range dictCDRCallType {
				if callType == v.DictValue {
					callTypeLable = i18n.TKey(language, v.DictLabel)
					break
				}
			}
		}
		// 被叫
		called := ""
		if v, ok := cdrJSON["calledParty"]; ok && v != nil {
			called = v.(string)
		}
		// 主叫
		caller := ""
		if v, ok := cdrJSON["callerParty"]; ok && v != nil {
			caller = v.(string)
		}
		// 时长
		duration := "-"
		if v, ok := cdrJSON["callDuration"]; ok && v != nil && callType != "sms" {
			duration = fmt.Sprintf("%ds", parse.Number(v))
		}
		// 呼叫结果 非短信都有code作为结果 sms短信都ok
		// 呼叫结果 非短信都有code作为结果 sms短信都ok
		callResult := "Other"
		callCause := "Call failure for other reason"
		if callType == "sms" {
			callResult = "Success"
			callCause = "Normal Send"
		} else {
			if v, ok := cdrJSON["cause"]; ok && v != nil {
				cause := fmt.Sprint(v)
				for _, v := range dictCDRSipCode {
					if cause == v.DictValue {
						callResult = i18n.TKey(language, v.DictLabel)
						break
					}
				}
				for _, v := range dictCDRSipCodeCause {
					if cause == v.DictValue {
						callCause = i18n.TKey(language, v.DictLabel)
						break
					}
				}
			}
		}
		// 呼叫时间
		seizureTimeStr := ""
		if v, ok := cdrJSON["seizureTime"]; ok && v != nil {
			if seizureTime := parse.Number(v); seizureTime > 0 {
				seizureTimeStr = date.ParseDateToStr(seizureTime, date.YYYY_MM_DD_HH_MM_SS_GMT_TZ)
			} else {
				seizureTimeStr = v.(string)
			}
		}
		// 挂断时间
		releaseTimeStr := ""
		if v, ok := cdrJSON["releaseTime"]; ok && v != nil {
			if releaseTime := parse.Number(v); releaseTime > 0 {
				releaseTimeStr = date.ParseDateToStr(releaseTime, date.YYYY_MM_DD_HH_MM_SS_GMT_TZ)
			} else {
				releaseTimeStr = v.(string)
			}
		}

		dataCells = append(dataCells, map[string]any{
			"A" + idx: row.ID,
			"B" + idx: recordType,
			"C" + idx: callTypeLable,
			"D" + idx: caller,
			"E" + idx: called,
			"F" + idx: duration,
			"G" + idx: callResult,
			"H" + idx: callCause,
			"I" + idx: seizureTimeStr,
			"J" + idx: releaseTimeStr,
		})
	}

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