package smsmsg

import (
	"fmt"
	"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
	"git.rosy.net.cn/jx-callback/business/partner"
	aliyunsmsclient "github.com/KenmyZhang/aliyun-communicate"
	dyvmsapiclient "github.com/alibabacloud-go/dyvmsapi-20170525-2.0.2/client"
	"github.com/alibabacloud-go/tea/tea"
	"time"

	"git.rosy.net.cn/baseapi/utils"
	"git.rosy.net.cn/baseapi/utils/errlist"
	"git.rosy.net.cn/jx-callback/business/jxutils"
	"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"
)

var (
	warningMap = map[string]int{
		"isv.AMOUNT_NOT_ENOUGH": 1,
		"isv.ACCOUNT_ABNORMAL":  1,
		"isv.OUT_OF_SERVICE":    1,
		"isv.DAY_LIMIT_CONTROL": 1,
	}
)

func SendSMSMsg(mobileList []string, signName, templateCode string, templateParam map[string]interface{}, order *model.GoodsOrder) (err error) {
	if len(mobileList) > 0 {
		errList := errlist.New()
		mobileList = jxutils.StringMap2List(jxutils.StringList2Map(mobileList))
		for _, mobileNum := range mobileList {
			if mobileNum != "" {
				if true {
					if response, err := api.SMSClient.Execute(globals.AliKey, globals.AliSecret, mobileNum, signName, templateCode, string(utils.MustMarshal(templateParam))); err != nil {
						errList.AddErr(err)
					} else if response.Code != aliyunsmsclient.ResponseCodeOk {
						errMsg := fmt.Sprintf("SendSMSMsg mobileNum:%s failed with response:%s", mobileNum, utils.Format4Output(response, true))
						errList.AddErr(fmt.Errorf(errMsg))
						if warningMap[response.Code] == 1 {
							globals.SugarLogger.Warnf(errMsg)
						} else {
							globals.SugarLogger.Infof(errMsg)
						}
					}
				}
			}
		}
		err = errList.GetErrListAsOne()
	}
	return err
}

func SendVoiceMsg(mobileList []string, templateCode string, templateParam map[string]interface{}) (err error) {
	if len(mobileList) > 0 {
		errList := errlist.New()
		mobileList = jxutils.StringMap2List(jxutils.StringList2Map(mobileList))
		for _, mobileNum := range mobileList {
			if mobileNum != "" {
				request := &dyvmsapiclient.SingleCallByTtsRequest{
					CalledNumber: tea.String(mobileNum),
					TtsCode:      tea.String(templateCode),
					TtsParam:     tea.String(string(utils.MustMarshal(templateParam))),
				}
				res, _err := api.VoiceClient.SingleCallByTts(request)
				if _err != nil {
					errList.AddErr(err)
				}
				if *res.Body.Code != "OK" {
					errList.AddErr(fmt.Errorf(*res.Body.Message))
				} else {
					globals.SugarLogger.Debugf("SendVoiceMsg mobileNum:%s success with response:%s", mobileNum, utils.Format4Output(res, true))
				}
			}
		}
		err = errList.GetErrListAsOne()
	}
	return err
}

func getOrderNotifyPhone(order *model.GoodsOrder) (phoneList []string) {
	return dao.GetOrderNotifyPhones(dao.GetDB(), jxutils.GetSaleStoreIDFromOrder(order))
}

func NotifyNewOrder(order *model.GoodsOrder) (err error) {
	if isPushSMS(order) {
		temp := ""
		var price int64
		store, _ := dao.GetStoreDetail(dao.GetDB(), jxutils.GetSaleStoreIDFromOrder(order), order.VendorID, order.VendorOrgCode)
		if store.VendorPayPercentage < 50 && store.VendorPayPercentage != 0 {
			temp = globals.SMSNewOrderTemplate
			price = order.ActualPayPrice
		} else if store.VendorPayPercentage > 50 {
			temp = globals.SMSNewOrderTemplateQ
			price = order.ShopPrice
		} else if store.VendorPayPercentage == 0 {
			if store.PayPercentage > 50 {
				temp = globals.SMSNewOrderTemplateQ
				price = order.ShopPrice
			} else {
				temp = globals.SMSNewOrderTemplate
				price = order.ActualPayPrice
			}
		}

		err = SendSMSMsg(getOrderNotifyPhone(order), globals.SMSSignName, temp, map[string]interface{}{
			"daySeq":        order.OrderSeq,
			"consigneeName": order.ConsigneeName,
			"payMoney":      jxutils.IntPrice2StandardString(price),
		}, order)
	}
	return err
}

func NotifyPickOrder(order *model.GoodsOrder) (err error) {
	//if isPushSMS(order) {
	store, _ := dao.GetStoreDetail(dao.GetDB(), jxutils.GetSaleStoreIDFromOrder(order), order.VendorID, order.VendorOrgCode)
	mobileList := []string{}
	if store.Tel1 != "" {
		mobileList = append(mobileList, store.Tel1)
	}
	if store.Tel2 != "" {
		mobileList = append(mobileList, store.Tel2)
	}
	updateSth := func(order *model.GoodsOrder, store *dao.StoreDetail, feeType int) (err error) {
		order.NotifyType = int(store.SMSNotify)
		partner.CurOrderManager.UpdateOrderFields(order, []string{"NotifyType"})
		//品牌余额, 一条5分
		//if order.CreateDeliveryType == model.YES { // 门店发单
		noticeType := 0
		switch feeType {
		case model.BrandBillFeeTypeSms:
			noticeType = partner.StoreAcctTypeExpendTextMessageNotify
		case model.BrandBillFeeTypeVoice:
			noticeType = partner.StoreAcctTypeExpendVoiceMessageNotify
		}
		err = partner.CurStoreAcctManager.InsertStoreAcctExpendAndUpdateStoreAcctBalance(jxcontext.AdminCtx, store.ID, 5, noticeType, order.VendorOrderID, "", 0)
		/*} else if order.CreateDeliveryType == model.NO { // 品牌发单
			err = partner.CurStoreAcctManager.InsertBrandBill(jxcontext.AdminCtx, store.BrandID, 5, model.BrandBillTypeExpend, feeType, order.VendorOrderID, "")
		}*/
		return err
	}
	balance, _ := partner.CurStoreAcctManager.GetBrandBalance(store.BrandID)
	if order.NotifyType == 0 && store.SMSNotify != 0 && store.IsOrder == model.NO && store.ID != model.MatterStoreID && store.ID != model.JdShopMainStoreID && len(mobileList) > 0 {
		switch store.SMSNotify {
		case model.NotifyTypeSMS:
			if store.BrandIsOpen&model.BrandOpenSMS != 0 && balance >= model.BrandBalanceLimit {
				if err = SendSMSMsg(mobileList, globals.SMSSignName, globals.SMSPickOrderTemplate, nil, order); err == nil {
					err = updateSth(order, store, model.BrandBillFeeTypeSms)
				}
			} else {
				globals.SugarLogger.Debugf("NotifyPickOrder sms brand is close , orderID: %s ,isOpen： %d", order.VendorOrderID, store.BrandIsOpen)
			}
		case model.NotifyTypeVoice:
			if store.MarketManPhone == "" {
				store.MarketManPhone = "18048531223"
			}
			if store.BrandIsOpen&model.BrandOpenVoice != 0 && balance >= model.BrandBalanceLimit {
				if store.Status < model.StoreStatusOpened { // 门店休息，发短信不打电话
					if err = SendSMSMsg(mobileList, globals.SMSSignName, globals.SMSPickOrderTemplate, nil, order); err == nil {
						err = updateSth(order, store, model.BrandBillFeeTypeSms)
					}
				} else {
					if err = SendVoiceMsg(mobileList, globals.SMSVoicePickOrderTemplate, map[string]interface{}{
						"tel": store.MarketManPhone,
					}); err == nil {
						err = updateSth(order, store, model.BrandBillFeeTypeVoice)
					}
				}
			} else {
				globals.SugarLogger.Debugf("NotifyPickOrder voice brand is close , orderID: %s ,isOpen： %d", order.VendorOrderID, store.BrandIsOpen)
			}
		}
	}
	//}
	return err
}

func NotifyO2019110769024042(order *model.GoodsOrder) (err error) {
	err = SendSMSMsg(getOrderNotifyPhone(order), globals.SMSSignName, globals.SMSOrderCanceledTemplate, map[string]interface{}{
		"vendorName": model.VendorChineseNames[order.VendorID],
		"seq":        order.OrderSeq,
		"orderID":    order.VendorOrderID,
	}, order)
	return err
}

func isPushSMS(order *model.GoodsOrder) bool {
	storeID := 0
	if order.StoreID == 0 {
		storeID = order.JxStoreID
	} else {
		storeID = order.StoreID
	}
	stores, _ := dao.GetStoresMapList(dao.GetDB(), []int{order.VendorID}, []int{storeID}, nil, model.StoreStatusAll, model.StoreIsSyncAll, "", "", "")
	if len(stores) > 0 {
		if stores[0].IsOrder == model.NO {
			if storeID == model.MatterStoreID || storeID == model.JdShopMainStoreID {
				return false
			} else {
				return true
			}
		} else {
			return false
		}
	} else {
		return false
	}
}

func updateStoreSMSNotifyMark(order *model.GoodsOrder) (err error) {
	var db = dao.GetDB()
	stores, _ := dao.GetStoreList(db, []int{order.StoreID}, nil, nil, nil, nil, "")
	if len(stores) > 0 {
		stores[0].SMSNotifyMark = model.YES
		_, err = dao.UpdateEntity(db, stores[0], "SMSNotifyMark")
	}
	return err
}

//每月向用户发送
func NotifyNewUserOrder(order *model.GoodsOrder) (err error) {
	var (
		db       = dao.GetDB()
		storeTel string
		storeID  int
		mobile   string
	)
	if order.StoreID == 0 {
		storeID = order.JxStoreID
	} else {
		storeID = order.StoreID
	}
	if order.ConsigneeMobile2 != "" {
		mobile = order.ConsigneeMobile2
		uoSMS, err := dao.GetUserOrderSMS(db, mobile, "")
		stores, _ := dao.GetStoreList(db, []int{storeID}, nil, nil, nil, nil, "")
		if len(stores) > 0 {
			if stores[0].Tel1 == "" {
				storeTel = stores[0].Tel2
			} else {
				storeTel = stores[0].Tel1
			}
		}
		if uoSMS == nil {
			uoSMSc := &model.UserOrderSms{
				Mobile:       mobile,
				Name:         order.ConsigneeName,
				VendorUserID: order.VendorUserID,
				TotalCount:   0,
				SMSMark:      model.NO,
			}
			err = dao.CreateEntity(db, uoSMSc)
			err = SendSMSMsg([]string{uoSMSc.Mobile}, globals.SMSSignName, globals.SMSNewUserOrderTemplate, map[string]interface{}{
				"tel": storeTel,
			}, nil)
			if err == nil {
				uoSMS2, _ := dao.GetUserOrderSMS(db, mobile, "")
				uoSMS2.SMSMark = model.YES
				uoSMS2.TotalCount++
				_, err = dao.UpdateEntity(db, uoSMS2, "SMSMark", "TotalCount")
			}
		} else {
			if uoSMS.SMSMark != model.YES {
				err = SendSMSMsg([]string{uoSMS.Mobile}, globals.SMSSignName, globals.SMSNewUserOrderTemplate, map[string]interface{}{
					"tel": storeTel,
				}, nil)
				if err == nil {
					uoSMS.SMSMark = model.YES
					uoSMS.TotalCount++
					_, err = dao.UpdateEntity(db, uoSMS, "SMSMark", "TotalCount")
				}
			}
		}
	}
	return err
}

//给配送员发短信
func NotifyNewCourierOrder(bill *model.Waybill) (err error) {
	var (
		db       = dao.GetDB()
		storeTel string
		storeID  int
	)
	order := &model.GoodsOrder{}
	order.VendorOrderID = bill.VendorOrderID
	err = dao.GetEntity(db, order, "VendorOrderID")
	if order.StoreID == 0 {
		storeID = order.JxStoreID
	} else {
		storeID = order.StoreID
	}
	stores, _ := dao.GetStoreList(db, []int{storeID}, nil, nil, nil, nil, "")
	if len(stores) > 0 {
		if stores[0].Tel1 == "" {
			storeTel = stores[0].Tel2
		} else {
			storeTel = stores[0].Tel1
		}
	}
	err = SendSMSMsg([]string{bill.CourierMobile}, globals.SMSSignName, globals.SMSNewOrderTemplate, map[string]interface{}{
		"tel": storeTel,
	}, nil)
	return err
}

//京西订单配送员取货后，给用户发短信提醒
func NotifyJxOrder(order *model.GoodsOrder, bill *model.Waybill) (err error) {
	err = SendSMSMsg([]string{order.ConsigneeMobile}, globals.SMSSignName, globals.SMSJxOrderDelivering, map[string]interface{}{
		"phone": bill.CourierMobile,
	}, order)
	return err
}

//品牌余额不足发送
func NotifyBrandBalance(brandID int) (err error) {
	var (
		db = dao.GetDB()
	)
	bindUsers, err := dao.GetBrandUser(db, brandID, "")
	if err != nil {
		return err
	}
	list := errlist.New()
	count := 0
	for _, v := range bindUsers {
		if user, err := dao.GetUserByID(db, "user_id", v.UserID); err == nil && user != nil {
			if err = SendVoiceMsg([]string{*user.Mobile}, globals.SMSVoiceBrandBalanceTemplate, map[string]interface{}{
				"money": model.BrandBalanceLimit,
			}); err != nil {
				list.AddErr(err)
			} else {
				count++
			}
			if err = SendSMSMsg([]string{*user.Mobile}, globals.SMSSignName, globals.SMSBrandBalanceTemplate, map[string]interface{}{
				"money": model.BrandBalanceLimit,
			}, nil); err != nil {
				list.AddErr(err)
			} else {
				count++
			}
		}
	}
	err = list.GetErrListAsOne()
	if err == nil {
		//每个品牌每天通知一次，用redis吧
		if mark := api.Cacher.Get("brandID" + utils.Int2Str(brandID)); mark == nil {
			err = api.Cacher.Set("brandID"+utils.Int2Str(brandID), 1, utils.Str2Time(time.Now().AddDate(0, 0, 1).Format("2006-01-02")+"00:00:00").Sub(time.Now()))
		}
		if count > 0 {
			partner.CurStoreAcctManager.InsertBrandBill(jxcontext.AdminCtx, brandID, 5*count, model.BrandBillTypeExpend, model.BrandBillFeeTypeSys, "", "")
		}
	}
	return err
}
