package push

import (
	"encoding/json"
	"errors"
	"fmt"
	"log"
	"time"

	"git.rosy.net.cn/jx-callback/business/authz/autils"
	"git.rosy.net.cn/jx-callback/globals/api2"

	"git.rosy.net.cn/baseapi/utils"
	"git.rosy.net.cn/jx-callback/business/model"
	"git.rosy.net.cn/jx-callback/business/model/dao"
	"git.rosy.net.cn/jx-callback/globals"
	"git.rosy.net.cn/jx-callback/globals/api"
)

const (
	SoundsFileNewOrder       = "newOrder.caf"
	SoundsFileNewAfsOrder    = "afsOrder.caf"
	SoundsFileNewCancelOrder = "cancelOrder.caf"
	SoundsFileNewImMsg       = "newMsg.caf"

	FlagOrder = 1 //订单渠道
	FlagIm    = 2 //消息类型
)

// NotifyNewOrder 推送新订单
func NotifyNewOrder(order *model.GoodsOrder) {
	storeId := order.StoreID
	if storeId <= model.NO {
		storeId = order.JxStoreID
	}
	msg := MsgContext{}

	storeDetail, err := dao.GetStoreDetail(dao.GetDB(), storeId, 0, "")
	if err != nil || storeDetail == nil {
		return
	}

	cid, err := GetStoreBoosCID(storeId)
	if err != nil {
		globals.SugarLogger.Errorf("新订单推送,获取门店老板CID错误:%v", err)
		return
	}

	msg.MsgType = "newOrder"
	msg.VendorName = model.VendorChineseNames[order.VendorID]
	msg.OrderSqs = utils.Int2Str(order.OrderSeq)
	msg.StoreTitle = storeDetail.Name
	msg.Context = "老板,你有新的订单了!"
	msg.VendorOrderId = order.VendorOrderID
	msg.StoreId = storeId
	msg.BusinessType = order.BusinessType
	context, _ := json.Marshal(msg)
	body := msg.Context + fmt.Sprintf("门店ID:%d(%s)", storeId, model.VendorChineseNames[order.VendorID]+"#"+msg.OrderSqs+"号订单")
	pushMsgByUniApp(storeDetail.ID, storeDetail.Name, cid, string(context), body, SoundsFileNewOrder, FlagOrder)
}

// NotifyAdjustOrder 推送调整订单
func NotifyAdjustOrder(order *model.GoodsOrder) {
	storeId := order.StoreID
	if storeId <= model.NO {
		storeId = order.JxStoreID
	}
	msg := MsgContext{}

	storeDetail, err := dao.GetStoreDetail(dao.GetDB(), storeId, 0, "")
	if err != nil || storeDetail == nil {
		return
	}

	cid, err := GetStoreBoosCID(storeId)
	if err != nil {
		globals.SugarLogger.Errorf("新订单推送,获取门店老板CID错误:%v", err)
		return
	}

	msg.MsgType = "newOrder"
	msg.VendorName = model.VendorChineseNames[order.VendorID]
	msg.OrderSqs = utils.Int2Str(order.OrderSeq)
	msg.StoreTitle = storeDetail.Name
	msg.Context = "老板,用户修改订单信息!"
	msg.VendorOrderId = order.VendorOrderID
	msg.StoreId = storeId
	context, _ := json.Marshal(msg)
	body := "用户调整了:" + msg.Context + fmt.Sprintf("(%s)", model.VendorChineseNames[order.VendorID]+"#"+msg.OrderSqs+"号订单,请注意拣货")
	pushMsgByUniApp(storeDetail.ID, storeDetail.Name, cid, string(context), body, SoundsFileNewOrder, FlagOrder)
}

func NotifyAfsOrder(afsOrder *model.AfsOrder) (err error) {
	storeId := afsOrder.StoreID
	if storeId <= model.NO {
		storeId = afsOrder.JxStoreID
	}
	msg := MsgContext{}

	storeDetail, err := dao.GetStoreDetail(dao.GetDB(), storeId, 0, "")
	if err != nil || storeDetail == nil {
		return
	}

	cid, err := GetStoreBoosCID(storeId)
	if err != nil {
		globals.SugarLogger.Errorf("售后单,获取门店老板CID错误:%v", err)
		return
	}

	msg.MsgType = "newAfsOrder"
	msg.VendorName = model.VendorChineseNames[afsOrder.VendorID]
	msg.OrderSqs = afsOrder.VendorOrderID
	msg.StoreTitle = storeDetail.Name
	msg.Context = "老板订单申请退款了!"
	msg.StoreId = storeId
	context, _ := json.Marshal(msg)
	body := msg.Context + fmt.Sprintf("(%s)", model.VendorChineseNames[afsOrder.VendorID]+"#"+msg.OrderSqs+"号订单")
	pushMsgByUniApp(storeDetail.ID, storeDetail.Name, cid, string(context), body, SoundsFileNewAfsOrder, FlagOrder)
	return err
}

func NotifyOrderCanceled(order *model.GoodsOrder) (err error) {
	storeId := order.StoreID
	if storeId <= model.NO {
		storeId = order.JxStoreID
	}
	msg := MsgContext{}

	storeDetail, err := dao.GetStoreDetail(dao.GetDB(), storeId, 0, "")
	if err != nil || storeDetail == nil {
		return
	}

	cid, err := GetStoreBoosCID(storeId)
	if err != nil {
		globals.SugarLogger.Errorf("取消单,获取门店老板CID错误:%v", err)
		return
	}

	msg.MsgType = "newCancelOrder"
	msg.VendorName = model.VendorChineseNames[order.VendorID]
	msg.OrderSqs = utils.Int2Str(order.OrderSeq)
	msg.StoreTitle = storeDetail.Name
	msg.Context = "老板订单被取消了!"
	msg.StoreId = storeId
	context, _ := json.Marshal(msg)
	body := msg.Context + fmt.Sprintf("(%s)", model.VendorChineseNames[order.VendorID]+"#"+msg.OrderSqs+"号订单")
	pushMsgByUniApp(storeDetail.ID, storeDetail.Name, cid, string(context), body, SoundsFileNewCancelOrder, FlagOrder)
	return err
}

// NotifyImNewMessage IM 新消息通知
func NotifyImNewMessage(vendorStoreID string, vendorID int, offMsg string) error {
	if len(vendorStoreID) == 0 {
		return nil
	}
	var msg = MsgContext{}

	store, err := dao.GetStoreBaseByVendorStoreID(vendorStoreID, vendorID)
	if err != nil {
		return fmt.Errorf("未查到此门店/门店未与平台正常绑定:%s", vendorStoreID)
	}

	cid, err := GetStoreBoosCID(store.ID)
	if err != nil {
		globals.SugarLogger.Errorf("IM消息推送,获取门店老板CID错误 %v", err)
		return err
	}
	fmt.Print(cid)
	msg.MsgType = "newImMsg"
	msg.VendorName = model.VendorChineseNames[vendorID]
	msg.StoreTitle = store.Name
	msg.Context = offMsg
	msg.StoreId = store.ID
	context, _ := json.Marshal(msg)
	body := "老板,你有新的用户消息,请及时查看!" + fmt.Sprintf("(%s)", model.VendorChineseNames[vendorID])
	pushMsgByUniApp(store.ID, store.Name, cid, string(context), body, SoundsFileNewImMsg, FlagIm)
	return err
}

// GetStoreBoosCID /************************************************************/
func GetStoreBoosCID(storeId int) ([]string, error) {
	// 根据订单获取门店的老板cid
	userIDList, err2 := api2.RoleMan.GetRoleUserList(autils.NewStoreBossRole(storeId))
	if err2 != nil {
		return nil, err2
	}

	userList, _, err := dao.GetUsers(dao.GetDB(), 0, "", userIDList, nil, nil, 0, 100)
	if err != nil || len(userList) <= model.NO {
		return nil, errors.New("门店老板信息获取异常")
	}

	var cId = make([]string, 0, len(userList))
	for _, v := range userList {
		if v.CID != "" {
			cId = append(cId, v.CID)
		}
	}

	if len(cId) <= model.NO {
		return nil, fmt.Errorf("门店[%d],暂无CID,无法使用UniApp推送", storeId)
	}

	return cId, nil
}

type MsgContext struct {
	MsgType       string `json:"msg_type"`        // 订单类型[新订单/售后单/取消单]
	StoreTitle    string `json:"store_title"`     // 门店名称
	StoreId       int    `json:"store_id"`        // 门店ID
	Context       string `json:"context"`         // 消息文本
	VendorName    string `json:"vendor_name"`     // 平台名称
	OrderSqs      string `json:"order_sqs"`       // 订单流水号
	VendorOrderId string `json:"vendor_order_id"` // 订单id
	BusinessType  int    `json:"business_type"`   // 是否为预定单
}

func pushMsgByUniApp(storeId int, storeName string, cID []string, msg string, body string, soundsFileName string, flag int) {
	var (
		errs    []error
		options = make(map[string]interface{}, 0)
	)
	if flag == FlagOrder {
		options = map[string]interface{}{
			"XM": map[string]interface{}{
				"/extra.channel_id": "108892", // 订单类填写：108892，消息通知类填写：108898
			},
			"HW": map[string]interface{}{
				"/message/android/category": "WORK", // 订单类填写：WORK，消息通知类填写：IM
			},
			"OP": map[string]interface{}{
				"/channel_id": "10110", // 订单类填写：10110，消息通知类填写：10111
			},
			"VV": map[string]interface{}{
				"/category": "ORDER", // 订单类填写：ORDER，消息通知类填写：IM
			},
		}
	} else if flag == FlagIm {
		options = map[string]interface{}{
			"XM": map[string]interface{}{
				"/extra.channel_id": "108898", // 订单类填写：108892，消息通知类填写：108898
			},
			"HW": map[string]interface{}{
				"/message/android/category": "IM", // 订单类填写：WORK，消息通知类填写：IM
			},
			"OP": map[string]interface{}{
				"/channel_id": "10111", // 订单类填写：10110，消息通知类填写：10111
			},
			"VV": map[string]interface{}{
				"/category": "IM", // 订单类填写：ORDER，消息通知类填写：IM
			},
		}
	}

	for _, v := range cID {
		param := map[string]interface{}{
			"request_id": utils.Int64ToStr(time.Now().Unix()) + "_" + utils.Int2Str(storeId),
			"settings": map[string]interface{}{
				"ttl": 7200000,
			},
			"audience": map[string]interface{}{
				"cid": []string{v},
			},
			"push_message": map[string]interface{}{
				"transmission": msg,
			},
			"push_channel": map[string]interface{}{
				"android": map[string]interface{}{
					"ups": map[string]interface{}{
						"notification": map[string]interface{}{
							"title":      storeName,
							"body":       body,
							"click_type": "startapp",
							"notify_id":  time.Now().Unix(), // 每次通知需要不一样 范围：0-2147483647
						},
						"options": options,
					},
				},
				"ios": map[string]interface{}{
					"type":    "notify",
					"payload": msg,
					"aps": map[string]interface{}{
						"alert": map[string]interface{}{
							"title": storeName,
							"body":  body,
						},
						"content-available": 0,
						"sound":             soundsFileName,
					},
					"auto_badge": "+1",
				},
			},
		}

		if err := api.UniAppApi.SendMsgByUinApp(param); err != nil {
			errs = append(errs, err)
		}
	}
	if len(errs) != 0 {
		log.Printf("uinapp 消息推送错误:%s", utils.Format4Output(errs, false))
	}
}
