package controller

import (
	"fmt"

	"be.ems/src/framework/i18n"
	"be.ems/src/framework/reqctx"
	"be.ems/src/framework/resp"
	neFetchlink "be.ems/src/modules/ne/fetch_link"
	neService "be.ems/src/modules/ne/service"

	"github.com/gin-gonic/gin"
)

// 实例化控制层 PCFController 结构体
var NewPCF = &PCFController{
	neInfoService: neService.NewNeInfo,
}

// 网元PCF
//
// PATH /pcf
type PCFController struct {
	neInfoService *neService.NeInfo // 网元信息服务
}

// 策略配置列表
//
// GET /rule/list
//
//	@Tags			ne_data/pcf
//	@Accept			json
//	@Produce		json
//	@Param			neId	query		string	true	"NE ID"	default(001)
//	@Param			imsi		query		string	false	"IMSI"
//	@Param			msisdn		query		string	false	"MSISDN"
//	@Success		200		{object}	object	"Response Results"
//	@Security		TokenAuth
//	@Summary		Policy Configuration List
//	@Description	Policy Configuration List
//	@Router			/neData/pcf/rule/list [get]
func (s PCFController) RuleInfoList(c *gin.Context) {
	language := reqctx.AcceptLanguage(c)
	var query struct {
		NeId   string `form:"neId" binding:"required"`
		IMSI   string `form:"imsi"`
		MSISDN string `form:"msisdn"`
	}
	if err := c.ShouldBindQuery(&query); err != nil {
		errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
		c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
		return
	}

	// 查询网元信息
	neInfo := s.neInfoService.FindByNeTypeAndNeID("PCF", query.NeId)
	if neInfo.NeId != query.NeId || neInfo.IP == "" {
		c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
		return
	}

	// 网元直连
	data, err := neFetchlink.PCFRuleInfo(neInfo, map[string]string{
		"imsi":   query.IMSI,
		"msisdn": query.MSISDN,
	})
	if err != nil {
		c.JSON(200, resp.ErrMsg(err.Error()))
		return
	}

	c.JSON(200, resp.OkData(data))
}

// 策略配置添加
//
// POST /rule
//
//	@Tags			ne_data/pcf
//	@Accept			json
//	@Produce		json
//	@Param			data	body		object	true	"Request Param"
//	@Success		200		{object}	object	"Response Results"
//	@Security		TokenAuth
//	@Summary		Policy Configuration Additions
//	@Description	Policy Configuration Additions
//	@Router			/neData/pcf/rule [post]
func (s PCFController) RuleInfoAdd(c *gin.Context) {
	language := reqctx.AcceptLanguage(c)
	var body struct {
		NeId      string         `json:"neId" binding:"required"`      // 网元ID
		Num       int64          `json:"num"`                          // 批量添加，默认0单条，大于1时imsi/msisdn会累加数值
		ParamData map[string]any `json:"paramData" binding:"required"` // 参数数据
		// Imsi      string         `json:"imsi" binding:"required"`
		// Msisdn    string         `json:"msisdn" binding:"required"`
		// Sar       string         `json:"sar"`       // 根据PCF参数配置Service Area Restriction -> Name
		// PccRules  string         `json:"pccRules"`  // 根据PCF参数配置PCC Rules -> Rule ID
		// QosAudio  string         `json:"qosAudio"`  // 根据PCF参数配置QoS Template -> QoS ID
		// QosVideo  string         `json:"qosVideo"`  // 根据PCF参数配置QoS Template -> QoS ID
		// SessRules string         `json:"sessRules"` // 根据PCF参数配置Session Rules -> Rule ID
		// HdrEnrich string         `json:"hdrEnrich"` // 根据PCF参数配置Header Enrich Template -> Template Name
		// UePolicy  string         `json:"uePolicy"`  // UE策略模板(样例: uep_001)
		// Rfsp      int64          `json:"rfsp"`      // 无线频率选择优先级
	}
	if err := c.ShouldBindBodyWithJSON(&body); err != nil {
		errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
		c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
		return
	}

	// 查询网元信息
	neInfo := s.neInfoService.FindByNeTypeAndNeID("PCF", body.NeId)
	if neInfo.NeId != body.NeId || neInfo.IP == "" {
		c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
		return
	}

	// 网元直连
	var err error
	if body.Num > 0 { // 批量添加
		err = neFetchlink.PCFRuleAddBatch(neInfo, body.ParamData, body.Num)
	} else { // 单条添加
		err = neFetchlink.PCFRuleAdd(neInfo, body.ParamData)
	}
	if err != nil {
		c.JSON(200, resp.ErrMsg(err.Error()))
		return
	}
	c.JSON(200, resp.Ok(nil))
}

// 策略配置更新
//
// PUT /rule
//
//	@Tags			ne_data/pcf
//	@Accept			json
//	@Produce		json
//	@Param			data	body		object	true	"Request Param"
//	@Success		200		{object}	object	"Response Results"
//	@Security		TokenAuth
//	@Summary		Policy Configuration Updates
//	@Description	Policy Configuration Updates
//	@Router			/neData/pcf/rule [put]
func (s PCFController) RuleInfoEdit(c *gin.Context) {
	language := reqctx.AcceptLanguage(c)
	var body struct {
		NeId      string         `json:"neId" binding:"required"`      // 网元ID
		Num       int64          `json:"num"`                          // 更新数量
		ParamData map[string]any `json:"paramData" binding:"required"` // 参数数据
		// Imsi      string         `json:"imsi" binding:"required"`
		// Msisdn    string         `json:"msisdn" binding:"required"`
		// Sar       string         `json:"sar"`       // 根据PCF参数配置Service Area Restriction -> Name
		// PccRules  string         `json:"pccRules"`  // 根据PCF参数配置PCC Rules -> Rule ID
		// QosAudio  string         `json:"qosAudio"`  // 根据PCF参数配置QoS Template -> QoS ID
		// QosVideo  string         `json:"qosVideo"`  // 根据PCF参数配置QoS Template -> QoS ID
		// SessRules string         `json:"sessRules"` // 根据PCF参数配置Session Rules -> Rule ID
		// HdrEnrich string         `json:"hdrEnrich"` // 根据PCF参数配置Header Enrich Template -> Template Name
		// UePolicy  string         `json:"uePolicy"`  // UE策略模板(样例: uep_001)
		// Rfsp      int64          `json:"rfsp"`      // 无线频率选择优先级
	}
	if err := c.ShouldBindBodyWithJSON(&body); err != nil {
		errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
		c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
		return
	}

	// 查询网元信息
	neInfo := s.neInfoService.FindByNeTypeAndNeID("PCF", body.NeId)
	if neInfo.NeId != body.NeId || neInfo.IP == "" {
		c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
		return
	}

	// 网元直连
	var err error
	if body.Num > 0 { // 批量更新
		err = neFetchlink.PCFRuleUpdateBatch(neInfo, body.ParamData, body.Num)
	} else { // 单条更新
		err = neFetchlink.PCFRuleUpdate(neInfo, body.ParamData)
	}
	if err != nil {
		c.JSON(200, resp.ErrMsg(err.Error()))
		return
	}
	c.JSON(200, resp.Ok(nil))
}

// 策略配置删除
//
// DELETE /rule
//
//	@Tags			ne_data/pcf
//	@Accept			json
//	@Produce		json
//	@Param			neId		query		string	true	"NE ID"		default(001)
//	@Param			imsi	query		string	true	"IMSi, batch deletion with quantity"
//	@Param			num	query		number	false	"Number of deletions"
//	@Success		200			{object}	object	"Response Results"
//	@Security		TokenAuth
//	@Summary		Policy Configuration Deletion
//	@Description	Policy Configuration Deletion
//	@Router			/neData/pcf/rule [delete]
func (s PCFController) RuleInfoRemove(c *gin.Context) {
	language := reqctx.AcceptLanguage(c)
	var query struct {
		NeId string `form:"neId" binding:"required"` // 网元ID
		IMSI string `form:"imsi" binding:"required"` // IMSi, 带数量时为批量删除
		Num  int64  `form:"num"`                     // 删除数量
	}
	if err := c.ShouldBindQuery(&query); err != nil {
		errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
		c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
		return
	}

	// 查询网元信息
	neInfo := s.neInfoService.FindByNeTypeAndNeID("PCF", query.NeId)
	if neInfo.NeId != query.NeId || neInfo.IP == "" {
		c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
		return
	}

	// 网元直连
	var err error
	if query.Num > 0 { // 批量删除
		err = neFetchlink.PCFRuleDeleteBatch(neInfo, query.IMSI, query.Num)
	} else { // 单条删除
		err = neFetchlink.PCFRuleDelete(neInfo, query.IMSI)
	}
	if err != nil {
		c.JSON(200, resp.ErrMsg(err.Error()))
		return
	}
	c.JSON(200, resp.Ok(nil))
}

// 策略配置导出
//
// GET /rule/export
//
//	@Tags			ne_data/pcf
//	@Accept			json
//	@Produce		json
//	@Param			neId	query		string	true	"NE ID"	default(001)
//	@Param			fileType		query		string	true	"File Type" default(txt)
//	@Success		200		{object}	object	"Response Results"
//	@Security		TokenAuth
//	@Summary		Policy Configuration Export
//	@Description	Policy Configuration Export
//	@Router			/neData/pcf/rule/export [get]
func (s PCFController) RuleInfoExport(c *gin.Context) {
	language := reqctx.AcceptLanguage(c)
	var query struct {
		NeId     string `form:"neId" binding:"required"`
		FileType string `form:"fileType"  binding:"required,oneof=txt"` // 文件类型
	}
	if err := c.ShouldBindQuery(&query); err != nil {
		errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
		c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
		return
	}

	// 查询网元信息
	neInfo := s.neInfoService.FindByNeTypeAndNeID("PCF", query.NeId)
	if neInfo.NeId != query.NeId || neInfo.IP == "" {
		c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
		return
	}

	// 网元直连
	data, err := neFetchlink.PCFRuleExport(neInfo, map[string]string{
		"fileType": query.FileType,
	})
	if err != nil {
		c.JSON(200, resp.ErrMsg(err.Error()))
		return
	}
	c.Writer.Header().Set("Content-Disposition", `attachment; filename="pcf_rule_export.txt"`)
	c.Data(200, "application/octet-stream", data)
}

// 策略配置导入
//
// PUT /rule/import
//
//	@Tags			ne_data/pcf
//	@Accept			json
//	@Produce		json
//	@Param			neId	query		string	true	"NE ID"	default(001)
//	@Param			fileType		query		string	true	"File Type" default(txt)
//	@Param			filePath		query		string	true	"File Path" default(/tmp/pcfuser.txt)
//	@Success		200		{object}	object	"Response Results"
//	@Security		TokenAuth
//	@Summary		Policy Configuration Import
//	@Description	Policy Configuration Import
//	@Router			/neData/pcf/rule/import [put]
func (s PCFController) RuleInfoImport(c *gin.Context) {
	language := reqctx.AcceptLanguage(c)
	var body struct {
		NeId     string `json:"neId" binding:"required"`
		FileType string `json:"fileType"  binding:"required,oneof=txt"` // 文件类型
		FilePath string `json:"filePath"  binding:"required"`           // 网元端文件所在绝对路径
	}
	if err := c.ShouldBindBodyWithJSON(&body); err != nil {
		errMsgs := fmt.Sprintf("bind err: %s", resp.FormatBindError(err))
		c.JSON(422, resp.CodeMsg(resp.CODE_PARAM_PARSER, errMsgs))
		return
	}

	// 查询网元信息
	neInfo := s.neInfoService.FindByNeTypeAndNeID("PCF", body.NeId)
	if neInfo.NeId != body.NeId || neInfo.IP == "" {
		c.JSON(200, resp.ErrMsg(i18n.TKey(language, "app.common.noNEInfo")))
		return
	}

	// 网元直连
	output, err := neFetchlink.PCFRuleImport(neInfo, map[string]any{
		"type":     body.FileType,
		"filePath": body.FilePath,
	})
	if err != nil {
		c.JSON(200, resp.ErrMsg(err.Error()))
		return
	}
	c.JSON(200, resp.OkMsg(output))
}
