package push

import (
	"fmt"
	"gitlab.fjmaimaimai.com/mmm-go/gocomm/pkg/log"
	protocol "openapi/pkg/domain"
	"openapi/pkg/infrastructure/push"
	getui "openapi/pkg/infrastructure/push/getuiV2"
	"openapi/pkg/infrastructure/repository"
	"openapi/pkg/infrastructure/utils"
)

//推送信息
func Notification(header *protocol.RequestHeader, request *protocol.PushInfoRequest) (rsp *protocol.PushInfoResponse, err error) {
	var (
		repApp, _     = repository.NewAppInfoRepository(nil)
		repDevice, _  = repository.NewPushDeviceRepository(nil)
		repProject, _ = repository.NewProjectRepository()
		appInfo       *protocol.AppInfo
		project       *protocol.Project
		receiverIds   []int64

		requestOriginal *protocol.PushInfoOriginalRequest = &protocol.PushInfoOriginalRequest{
			Type:    request.Type,
			Title:   request.Title,
			Content: request.Content,
			Ext:     request.Ext,
		}
		projectKeys []string = []string{request.ProjectKey}
	)
	if len(request.ProjectKeys) > 0 {
		projectKeys = request.ProjectKeys
	}
	for i := 0; i < len(projectKeys); i++ {
		var receivers []string
		var deviceList []*protocol.Device
		projectKey := projectKeys[i]
		rsp = &protocol.PushInfoResponse{}
		if project, err = repProject.FindOne(map[string]interface{}{"project_slave_key": projectKey}); err != nil {
			log.Error(err)
			err = protocol.NewCustomMessage(1, fmt.Sprintf("project_key:%v not found", projectKey))
			return
		}
		if appInfo, err = repApp.FindOne(map[string]interface{}{"project_id": project.Id}); err != nil {
			log.Error(err)
			err = protocol.NewCustomMessage(1, fmt.Sprintf("project_key:%v not found", projectKey))
			return
		}
		if deviceList, err = repDevice.Find(
			map[string]interface{}{
				"receivers": request.Receivers, "project_master_key": project.ProjectMasterKey},
		); err != nil {
			log.Error(err)
			err = nil
			return
		}
		if extInfo, ok := appInfo.GetExtInfo(); ok {
			if len(extInfo.Intent) > 0 {
				requestOriginal.Ext["intent"] = extInfo.Intent
			}
			if len(extInfo.Sound) > 0 {
				requestOriginal.SetExt(push.Sound, extInfo.Sound, false)
			}
			if len(extInfo.HWSound) > 0 {
				requestOriginal.SetExt(push.SoundHW, extInfo.HWSound, false)
			}
			if len(extInfo.XMSound) > 0 {
				requestOriginal.SetExt(push.SoundXM, extInfo.XMSound, false)
			}
		}
		if len(deviceList) == 0 {
			//e := protocol.NewSuccessWithMessage(fmt.Sprintf("Project:%v 接收人:%v 未查询到注册的设备信息!",projectKey, request.Receivers))
			log.Error(fmt.Sprintf("【个推】 Project:%v 接收人:%v 未查询到注册的设备信息!", projectKey, request.Receivers))
			continue
		}
		for i := range deviceList {
			receivers = append(receivers, deviceList[i].ClientId)
			receiverIds = append(receiverIds, deviceList[i].Uid)
		}
		request.ActualReceivers = receiverIds
		requestOriginal.AppKey = appInfo.AppKey
		requestOriginal.AppId = appInfo.AppId
		requestOriginal.Secret = appInfo.AppMasterSecret
		requestOriginal.ClientIdList = receivers
		rsp, err = NotificationOriginal(header, requestOriginal)
		repDevice.SaveLog(request, rsp.ExtData, err)
		if err != nil {
			err = protocol.NewCustomMessage(1, err.Error())
		}
	}
	return
}

func NotificationOriginal(header *protocol.RequestHeader, request *protocol.PushInfoOriginalRequest) (rsp *protocol.PushInfoResponse, err error) {
	var (
		sendData  = make(map[string]interface{})
		clientIds []string
		options   []push.Option = []push.Option{
			push.DebugModule(true),
			push.AppId(request.AppId),
			push.AppKey(request.AppKey),
			push.AppMasterSecret(request.Secret),
			push.MsgType(request.Type),

			push.Title(request.Title),
			push.Content(request.Content),
			push.Extra(request.Ext),
		}
	)
	rsp = &protocol.PushInfoResponse{}
	if v, ok := request.Ext["transData"]; ok {
		options = append(options, push.TransmissionContent(utils.JsonAssertString(v)))
	}
	if v, ok := request.Ext["intent"]; ok {
		options = append(options, push.Intent(v.(string)))
	}
	clientIds = request.ClientIdList
	switch len(clientIds) {
	case 0:
		err = protocol.NewCustomMessage(2, "clientId/deviceToken 不能同时为空.")
		return
	case 1:
		options = append(options,
			push.PushType(push.PushToSingle),
			push.ClientId(clientIds[0]),
		)
		break
	default:
		options = append(options,
			push.PushType(push.PushToList),
			push.ClientIds(clientIds),
		)
		break
	}

	var pushService push.INotification = &getui.GetuiNotification{}
	err = pushService.Init(options...)
	if err != nil {
		log.Error(err)
		return
	}
	if rsp.ExtData, err = pushService.Send(sendData); err != nil {
		log.Error(err)
		return
	}
	return
}

//更新设备信息
func UpdateDevice(header *protocol.RequestHeader, request *protocol.UpdateDeviceRequest) (rsp *protocol.UpdateDeviceResponse, err error) {
	var (
		//device *protocol.Device
		project       *protocol.Project
		repProject, _ = repository.NewProjectRepository()
		rep, _        = repository.NewPushDeviceRepository(nil)
	)
	rsp = &protocol.UpdateDeviceResponse{}
	if project, err = repProject.FindOne(map[string]interface{}{"project_master_key": request.ProjectMasterKey}); err != nil {
		log.Error(err)
		err = protocol.NewCustomMessage(1, fmt.Sprintf("project_key:%v not found", request.ProjectMasterKey))
		return
	}
	if _, err = rep.FindOne(map[string]interface{}{
		"uid":                request.Muid,
		"project_master_key": request.ProjectMasterKey,
	}); err != nil {
		if err == protocol.ERR_DB_NOT_FOUND {
			request.Project = project.Project
			err = rep.Save(request)
			if err != nil {
				log.Error(err)
			}
			return
		}
		log.Error(err)
		return
	}
	if err = rep.UpdateDevice(request.Muid, request.ClientId, request.DeviceToken, request.ProjectMasterKey, request.Phone, request.Project); err != nil {
		log.Error(err)
	}
	err = protocol.NewSuccessWithMessage("更新成功")
	return
}