package jdshop

import (
	"bytes"
	"encoding/base64"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"math"
	"strings"
	"time"

	"git.rosy.net.cn/baseapi/platformapi/dingdingapi"
	"git.rosy.net.cn/baseapi/platformapi/jcqapi"
	"git.rosy.net.cn/baseapi/platformapi/jdshopapi"
	"git.rosy.net.cn/baseapi/utils"
	"git.rosy.net.cn/jx-callback/business/authz/autils"
	"git.rosy.net.cn/jx-callback/business/jxutils"
	"git.rosy.net.cn/jx-callback/business/jxutils/ddmsg"
	"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
	"git.rosy.net.cn/jx-callback/business/model"
	"git.rosy.net.cn/jx-callback/business/model/dao"
	"git.rosy.net.cn/jx-callback/business/partner"
	"git.rosy.net.cn/jx-callback/globals"
	"git.rosy.net.cn/jx-callback/globals/api"
	"git.rosy.net.cn/jx-callback/globals/api2"
)

//TODO 以下是京东商城云顶推送消息使用的代码，现在都是以网页爬取的形式拿订单了，下面的都不用了
//TODO 位置在 orderman/order.go 的 SaveJdsOrders
func OnCallbackMsg(msg *jdshopapi.CallBackResult) (err error) {
	msgType := msg.MsgType
	switch msgType {
	case jcqapi.TopicOrderPay:
		utils.CallFuncAsync(func() {
			SaveJdsOrders(msg)
		})
	case jcqapi.TopicOrderCancel:
		utils.CallFuncAsync(func() {
			order := getRealOrderID(msg.OrderID)
			if order != nil {
				if order.Status != model.OrderStatusCanceled {
					CurPurchaseHandler.CancelOrder(jxcontext.AdminCtx, order, "系统取消")
				}
			}
		})
	case jcqapi.TopicOrderOut:
		utils.CallFuncAsync(func() {
			orders := getAllRealOrderID(msg.OrderID)
			if len(orders) > 0 {
				for _, order := range orders {
					if order.ActualPayPrice == 0 {
						if jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment)) == 0 {
							order.ActualPayPrice = jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderTotalPrice) + utils.Str2Float64(msg.FreightPrice) - utils.Str2Float64(msg.SellerDiscount))
						} else {
							order.ActualPayPrice = jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment))
						}
						order.TotalShopMoney = utils.Float64TwoInt64(float64(order.ActualPayPrice) * jdshopapi.JdsPayPercentage)
						partner.CurOrderManager.UpdateOrderFields(order, []string{"ActualPayPrice", "TotalShopMoney"})
					}
				}
			}
		})
	default:
		return fmt.Errorf("暂不支持的topic类型！topic: %v", msgType)
	}
	return err
}

func SaveJdsOrders(msg *jdshopapi.CallBackResult) (err error) {
	if msg.OrderState == "TRADE_CANCELED" {
		return nil
	} //清洗脏数据 部分数据按照
	order, err := result2Orders(msg)
	if err != nil && order == nil {
		return err
	}
	partner.CurOrderManager.OnOrderNew(order, model.Order2Status(order))
	noticeMsg := fmt.Sprintf("京东商城新订单，订单号：[%v] ,将要发到的门店id：[%v] , 门店名：[%v]", order.VendorOrderID, order.StoreID, order.StoreName)
	if order.OrderType == model.OrderTypeAddressErr {
		noticeMsg += " 此订单地址有问题，需要矫正坐标！"
	}
	var role = autils.NewRole("jdshop", 0)
	userIDList, err := api2.RoleMan.GetRoleUserList(role)
	for _, v := range userIDList {
		ddmsg.SendUserMessage(dingdingapi.MsgTyeText, v, "京东商城来新订单了！", noticeMsg)
	}
	// ddmsg.SendUserMessage(dingdingapi.MsgTyeText, "1439B3E07D3911EA881A525400E86DC0", "京东商城来新订单了！", noticeMsg)
	return err
}

func result2Orders(msg *jdshopapi.CallBackResult) (order *model.GoodsOrder, err error) {
	var (
		db = dao.GetDB()
	)
	//有可能是库里已经有这个订单了
	orderE, err := partner.CurOrderManager.LoadOrder(msg.OrderID+"00000001", model.VendorIDJDShop)
	if orderE != nil {
		return order, fmt.Errorf("已经存在此订单！")
	}
	order = &model.GoodsOrder{
		VendorOrderID2:   msg.OrderID,
		VendorOrderID:    msg.OrderID + "00000001",
		VendorID:         model.VendorIDJDShop,
		BaseFreightMoney: jxutils.StandardPrice2Int(utils.Str2Float64(msg.FreightPrice)),
		VendorStatus:     msg.OrderState,
		VendorUserID:     msg.Pin,
		BuyerComment:     msg.OrderRemark,
		PickDeadline:     utils.DefaultTimeValue,
		OriginalData:     string(utils.MustMarshal(msg)),
		OrderCreatedAt:   utils.Str2Time(msg.OrderStartTime),
		ConsigneeAddress: Decrypt(msg.ConsigneeInfo.FullAddress, msg.VendorOrgCode),
		ConsigneeName:    Decrypt(msg.ConsigneeInfo.Fullname, msg.VendorOrgCode),
		// ConsigneeMobile:  Decrypt(msg.ConsigneeInfo.Mobile),
		// ConsigneeMobile2: Decrypt(msg.ConsigneeInfo.Telephone),
		ActualPayPrice: jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment)),
		Status:         model.OrderStatusNew,
		TotalShopMoney: utils.Float64TwoInt64(math.Round(float64(jxutils.StandardPrice2Int(utils.Str2Float64(msg.OrderPayment))) * jdshopapi.JdsPayPercentage)),
		DeliveryType:   model.OrderDeliveryTypeStoreSelf,
		StatusTime:     utils.Str2Time(msg.OrderStartTime),
		OrderSeq:       0,
		VendorOrgCode:  msg.VendorOrgCode,
	}
	if utils.Str2Float64(msg.BalanceUsed) != 0 {
		order.ActualPayPrice += jxutils.StandardPrice2Int(utils.Str2Float64(msg.BalanceUsed))
		order.TotalShopMoney += utils.Float64TwoInt64(math.Round(float64(jxutils.StandardPrice2Int(utils.Str2Float64(msg.BalanceUsed))) * jdshopapi.JdsPayPercentage))
	}
	if len(msg.ConsigneeInfo.Mobile) != 11 {
		order.ConsigneeMobile = Decrypt(msg.ConsigneeInfo.Mobile, msg.VendorOrgCode)
	} else {
		order.ConsigneeMobile = msg.ConsigneeInfo.Mobile
	}
	if len(msg.ConsigneeInfo.Telephone) != 11 {
		order.ConsigneeMobile2 = Decrypt(msg.ConsigneeInfo.Telephone, msg.VendorOrgCode)
	} else {
		order.ConsigneeMobile2 = msg.ConsigneeInfo.Telephone
	}
	if order.TotalShopMoney < 100 {
		order.TotalShopMoney = 100
	}
	if order.ConsigneeAddress != "" {
		var cityCode int
		place, err := dao.GetPlaceByJdsCode(db, utils.Str2Int(msg.ConsigneeInfo.CityID))
		if place == nil {
			cityCode = 510100
		} else {
			if place.Level == 3 {
				cityCode = place.ParentCode
			} else if place.Level == 2 {
				cityCode = place.Code
			}
		}
		lng, lat, _, _, err := api.TencentMapAPI.GetCoordinateFromAddress(order.ConsigneeAddress, utils.Int2Str(cityCode))
		if err != nil {
			globals.SugarLogger.Infof("腾讯地图 GetCoordinateFromAddress err: %v", err)
		}
		//lng2, lat2, _, err := api.TencentMapAPI.GetCoordinateFromAddress(order.ConsigneeAddress, "")
		//distance := jxutils.EarthDistance(lng, lat, lng2, lat2)
		//if distance > 1 {
		//	order.OrderType = model.OrderTypeAddressErr
		//}
		if err == nil && lng != 0 && lat != 0 {
			order.ConsigneeLng = jxutils.StandardCoordinate2Int(lng)
			order.ConsigneeLat = jxutils.StandardCoordinate2Int(lat)
		} /*else {
			order.ConsigneeLng = jxutils.StandardCoordinate2Int(lng2)
			order.ConsigneeLat = jxutils.StandardCoordinate2Int(lat2)
		}*/
		order.CoordinateType = model.CoordinateTypeMars
	}
	// storeList, err := common.GetStoreListByLocation(jxcontext.AdminCtx, jxutils.IntCoordinate2Standard(order.ConsigneeLng), jxutils.IntCoordinate2Standard(order.ConsigneeLat), 3000, false, true, 0)
	// if err != nil {
	// 	return order, err
	// }
	// if len(storeList) > 0 {
	// 	for _, store := range storeList {
	for _, v := range msg.ItemInfoList {
		sku := &model.OrderSku{
			VendorID:      model.VendorIDJDShop,
			VendorOrderID: order.VendorOrderID,
			Count:         utils.Str2Int(v.ItemTotal),
			VendorSkuID:   v.SkuID,
			SkuName:       v.SkuName,
			VendorPrice:   jxutils.StandardPrice2Int(utils.Str2Float64(v.JdPrice)),
			SalePrice:     jxutils.StandardPrice2Int(utils.Str2Float64(v.JdPrice)),
			// SkuID:         utils.Str2Int(v.OuterSkuID),
		}
		if v.OuterSkuID != "" {
			sku.SkuID = utils.Str2Int(v.OuterSkuID)
		}
		_, _, _, specUnit, _, specQuality := jxutils.SplitSkuName(v.SkuName)
		sku.Weight = jxutils.FormatSkuWeight(specQuality, specUnit)
		order.Skus = append(order.Skus, sku)
	}
	if order.ActualPayPrice > 100000 {
		buildOrderTo102919(order)
	}
	var store *dao.StoreDetail
	if msg.OrderExt != "" {
		orderExt := &jdshopapi.OrderExt{}
		if err = json.Unmarshal([]byte(msg.OrderExt), &orderExt); err == nil {
			order.VendorStoreID = orderExt.SiteID
			if store, err = dao.GetStoreDetailByVendorStoreID(db, order.VendorStoreID, model.VendorIDJDShop, ""); store != nil && err == nil {
				order.StoreID = store.ID
				order.JxStoreID = store.ID
				order.StoreName = store.Name
				//结算类型
				if store.PayPercentage < 50 {
					order.EarningType = model.EarningTypePoints
				} else {
					order.EarningType = model.EarningTypeQuote
				}
				var (
					shopPriceSum int
					// saleNormalSum int
				)
				for _, sku := range order.Skus {
					storeSkuList, _ := dao.GetStoresSkusInfo(db, []int{order.StoreID}, []int{sku.SkuID})
					if len(storeSkuList) > 0 {
						// if storeSkuList[0].Status == model.StoreSkuBindStatusNormal {
						// 	saleNormalSum += 1
						// }
						shopPriceSum += storeSkuList[0].Price * sku.Count
						sku.ShopPrice = int64(storeSkuList[0].Price)
					} else {
						shopPriceSum += int(sku.SalePrice) * 70 / 100
					}
				}
				//可售数小于一半就不行
				// if math.Mod(float64(len(order.Skus)), float64(2)) == 0 {
				// 	if saleNormalSum < len(order.Skus)/2 {
				// 		buildOrderTo102919(order)
				// 	} else {
				if order.EarningType == model.EarningTypeQuote && shopPriceSum+700 > int(order.TotalShopMoney) {
					buildOrderTo102919(order)
				}
				// 	}
				// } else {
				// 	if saleNormalSum <= len(order.Skus)/2 {
				// 		buildOrderTo102919(order)
				// 	} else {
				// 		if order.EarningType == model.EarningTypeQuote && shopPriceSum+700 > int(order.TotalShopMoney) {
				// 			buildOrderTo102919(order)
				// 		}
				// 	}
				// }
			} else {
				buildOrderTo102919(order)
			}
		} else {
			buildOrderTo102919(order)
		}
	} else {
		buildOrderTo102919(order)
	}
	// 如果是暂停，表示是预订单g
	if msg.OrderState == jdshopapi.OrderStatusPause || msg.OrderState == jdshopapi.OrderStatusPopPause {
		order.BusinessType = model.BusinessTypeDingshida
		if time2, err := getAPI(msg.VendorOrgCode).GetOrderExtInfoByOrderId(order.VendorOrderID2); err == nil {
			if time2 == "" {
				order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
			} else {
				order.ExpectedDeliveredTime = utils.Str2Time(time2)
			}
		} else {
			order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
			err = nil
		}
		order.PickDeadline = order.ExpectedDeliveredTime.Add(-time.Hour)
	} else if msg.OrderState == jdshopapi.OrderStatusWait || msg.OrderState == "WAIT_GOODS_RECEIVE_CONFIRM" || msg.OrderState == "FINISHED_L" {
		order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
		order.BusinessType = model.BusinessTypeImmediate
	} else if msg.OrderState == "UN_KNOWN" {
		order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
		order.BusinessType = model.BusinessTypeImmediate
	} else {
		return nil, err
	}

	if msg.IDSopShipmenttype == jdshopapi.IdSopShipmenttypeTC {
		if msg.VendorOrgCode == "1" {
			if time2, err := getAPI(msg.VendorOrgCode).GetOrderExtInfoByOrderId(order.VendorOrderID2); err == nil {
				order.BusinessType = model.BusinessTypeDingshida
				if time2 == "" {
					order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
				} else {
					order.ExpectedDeliveredTime = utils.Str2Time(time2)
				}
			}
		} else {
			order.BusinessType = model.BusinessTypeImmediate
			if time2, err := getAPI(msg.VendorOrgCode).GetOrderExtInfoByOrderId(order.VendorOrderID2); err == nil {
				if time2 == "" {
					order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
				} else {
					order.ExpectedDeliveredTime = utils.Str2Time(time2)
				}
			} else {
				order.ExpectedDeliveredTime = order.OrderCreatedAt.Add(time.Hour)
			}
		}
	}
	setJdsOrderSeq(order)
	if order.OrderType == model.OrderTypeAddressErr {
		buildOrderTo102919(order)
	}

	if store != nil {
		distance := jxutils.EarthDistance(jxutils.IntCoordinate2Standard(order.ConsigneeLng), jxutils.IntCoordinate2Standard(order.ConsigneeLat), jxutils.IntCoordinate2Standard(store.Lng), jxutils.IntCoordinate2Standard(store.Lat))
		if distance > 4 {
			buildOrderTo102919(order)
		}
	}
	if order.ExpectedDeliveredTime.Sub(order.OrderCreatedAt) <= time.Hour+time.Minute {
		order.BusinessType = model.BusinessTypeImmediate
	}
	order.PackagePrice = store.PackageSetting
	return order, err
}

func buildOrderTo102919(order *model.GoodsOrder) {
	order.StoreID = model.JdShopMainStoreID
	order.JxStoreID = model.JdShopMainStoreID
	order.StoreName = "商城模板店2"
	order.VendorStoreID = model.JdShopMainVendorStoreID
	// }
	order.DeliveryFlag = model.OrderDeliveryFlagMaskScheduleDisabled
}

func setJdsOrderSeq(order *model.GoodsOrder) (err error) {
	type tCount struct {
		Count int `json:"count"`
	}
	var count = &tCount{}
	sql := `
		SELECT count(*) count FROM goods_order WHERE store_id = ? AND order_create_at >= ? AND order_create_at <= ? AND vendor_id = ?
	`
	sqlParams := []interface{}{
		order.StoreID, utils.Time2Date(time.Now()), utils.Time2Date(time.Now().AddDate(0, 0, 1)), order.VendorID,
	}
	err = dao.GetRow(dao.GetDB(), &count, sql, sqlParams)
	order.OrderSeq = count.Count + 1
	return err
}

func Decrypt(p, vendorOrgCode string) (result string) {
	if p == "" {
		return ""
	}
	data, _ := base64.StdEncoding.DecodeString(strings.ReplaceAll(p, " ", "+"))
	key := GetKey(hex.EncodeToString(data)[4:36], vendorOrgCode)
	data2, _ := base64.StdEncoding.DecodeString(key)
	b := bytes.NewBuffer(data)
	b.Next(18)
	iv := make([]byte, 16)
	b.Read(iv)
	main := make([]byte, len(data)-18-16)
	b.Read(main)
	decryptedData, _ := utils.AESCBCDecpryt(main, data2[:16], iv)
	return string(decryptedData)
}

func getRealOrderID(orderID string) (order *model.GoodsOrder) {
	var (
		db = dao.GetDB()
	)
	sql := `
		SELECT * FROM goods_order WHERE vendor_order_id2 = ? ORDER BY vendor_order_id DESC LIMIT 1
	`
	sqlParams := []interface{}{
		orderID,
	}
	dao.GetRow(db, &order, sql, sqlParams)
	return order
}

func getAllRealOrderID(orderID string) (orders []*model.GoodsOrder) {
	var (
		db = dao.GetDB()
	)
	sql := `
		SELECT * FROM goods_order WHERE vendor_order_id2 = ? 
	`
	sqlParams := []interface{}{
		orderID,
	}
	dao.GetRows(db, &orders, sql, sqlParams)
	return orders
}

//
//func GetDaDaBillParams(db *dao.DaoDB, order *model.GoodsOrder) (billParams *dadaapi.OperateOrderParams, err error) {
//	billParams = &dadaapi.OperateOrderParams{
//		OriginID:        jxutils.ComposeUniversalOrderID(order.VendorOrderID, order.VendorID),
//		CargoPrice:      jxutils.IntPrice2Standard(limitOrderPrice(order.ActualPayPrice)),
//		IsPrepay:        0,
//		ReceiverName:    utils.FilterMb4(order.ConsigneeName),
//		ReceiverAddress: utils.FilterMb4(order.ConsigneeAddress),
//		ReceiverPhone:   order.ConsigneeMobile,
//	}
//	if billParams.ShopNo, err = getDadaShopID(order, db); err == nil {
//		if billParams.CityCode, err = getDataCityCodeFromOrder(order, db); err == nil {
//			// storeTel := ""
//			// storeID := jxutils.GetSaleStoreIDFromOrder(order)
//			// storeDeatail, _ := dao.GetStoreDetail(db, storeID, order.VendorID)
//			// if storeDeatail.Tel2 != "" {
//			// 	storeTel = ",门店电话：" + storeDeatail.Tel2
//			// }
//			billParams.ReceiverLng, billParams.ReceiverLat, _ = jxutils.IntCoordinate2MarsStandard(order.ConsigneeLng, order.ConsigneeLat, order.CoordinateType)
//			billParams.Info = fmt.Sprintf("%s第%d号订单, %s", model.VendorChineseNames[order.VendorID], order.OrderSeq, utils.FilterMb4("客户电话："+order.ConsigneeMobile+","+order.BuyerComment+"配送遇到问题，可联系18048531223取消配送单，禁止未配送直接完成定单！"))
//			billParams.CargoType = dadaapi.CargoTypeFresh
//			billParams.CargoWeight = float64(jxutils.IntWeight2Float(limitOrderWeight(order.Weight)))
//			billParams.CargoNum = order.GoodsCount
//		}
//	}
//	return billParams, err
//}
//
//func limitOrderPrice(price int64) int64 {
//	var maxOrderPrice int64 = 6399
//	if price > maxOrderPrice {
//		return maxOrderPrice
//	}
//	return price
//}
//
//func limitOrderWeight(weight int) int {
//	maxOrderWeight := 5000 // 5公斤
//	if weight > maxOrderWeight {
//		return maxOrderWeight
//	}
//	return weight
//}
//
//func getDadaShopID(order *model.GoodsOrder, db *dao.DaoDB) (retVal string, err error) {
//	saleStoreID := jxutils.GetSaleStoreIDFromOrder(order)
//	storeCourierList, err2 := dao.GetOpenedStoreCouriersByStoreID(db, saleStoreID, model.VendorIDDada)
//	if err = err2; err != nil && !dao.IsNoRowsError(err) {
//		return "", err
//	}
//	if len(storeCourierList) == 0 {
//		return "", partner.ErrStoreHaveNoCourier
//	}
//	retVal = storeCourierList[0].VendorStoreID
//	if beego.BConfig.RunMode == "dev" {
//		retVal = "test_0001"
//	}
//	return retVal, nil
//}
//
//func getDataCityCodeFromOrder(order *model.GoodsOrder, db *dao.DaoDB) (retVal string, err error) {
//	jxStoreID := jxutils.GetSaleStoreIDFromOrder(order)
//	sql := `
//		SELECT t2.tel_code
//		FROM store t1
//		JOIN place t2 on t1.city_code = t2.code
//		WHERE t1.id = ?
//		`
//	codeInfo := &struct {
//		TelCode string
//	}{}
//	if err = dao.GetRow(db, codeInfo, sql, jxStoreID); err != nil {
//		if err == nil {
//			err = errors.New("不能找到美团配送站点配置")
//		}
//		return "", err
//	}
//	return codeInfo.TelCode, nil
//}
