package elm

import (
	"errors"
	"fmt"
	"math"
	"strings"
	"time"

	"git.rosy.net.cn/jx-callback/globals"
	"git.rosy.net.cn/jx-callback/globals/api"

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

const (
	acceptOrderDelay = 270 * time.Second
	fakePickedUp     = "fakefinishedpickup"
)

var (
	VendorStatus2StatusMap = map[string]int{
		elmapi.OrderStatusUnprocessed: model.OrderStatusNew,
		elmapi.OrderStatusValid:       model.OrderStatusAccepted,
		elmapi.OrderStatusPending:     model.OrderStatusNew,
		// elmapi.OrderStatusRefunding:   model.OrderStatusApplyRefund,
		elmapi.OrderStatusInvalid: model.OrderStatusCanceled,
		elmapi.OrderStatusSettled: model.OrderStatusFinished,
	}
)

func (c *PurchaseHandler) OnOrderStatusMsg(msg *elmapi.CallbackOrderStatusMsg) (retVal *elmapi.CallbackResponse) {
	jxutils.CallMsgHandler(func() {
		retVal = c.onOrderStatusMsg(msg)
	}, jxutils.ComposeUniversalOrderID(msg.OrderID, model.VendorIDELM))
	return retVal
}

func (c *PurchaseHandler) OnOrderNewMsg(msg map[string]interface{}) (retVal *elmapi.CallbackResponse) {
	jxutils.CallMsgHandler(func() {
		retVal = c.onOrderNew(msg)
	}, jxutils.ComposeUniversalOrderID(msg["orderId"].(string), model.VendorIDELM))
	return retVal
}

func (c *PurchaseHandler) OnOrderCancelRefundMsg(msg *elmapi.CallbackOrderCancelRefundMsg) (retVal *elmapi.CallbackResponse) {
	jxutils.CallMsgHandler(func() {
		retVal = c.onOrderCancelRefundMsg(msg)
	}, jxutils.ComposeUniversalOrderID(msg.OrderID, model.VendorIDELM))
	return retVal
}

func (c *PurchaseHandler) orderStatusMsg2Status(msg *elmapi.CallbackOrderStatusMsg) *model.OrderStatus {
	orderStatus := &model.OrderStatus{
		VendorOrderID:    msg.OrderID,
		VendorID:         model.VendorIDELM,
		OrderType:        model.OrderTypeOrder,
		RefVendorOrderID: msg.OrderID,
		RefVendorID:      model.VendorIDELM,
		VendorStatus:     c.stateAndType2Str(msg.State, msg.MsgType),
		StatusTime:       utils.Timestamp2Time(msg.UpdateTime),
	}
	return orderStatus
}

func (c *PurchaseHandler) cancelRefundMsg2Status(msg *elmapi.CallbackOrderCancelRefundMsg) *model.OrderStatus {
	orderStatus := &model.OrderStatus{
		VendorOrderID:    msg.OrderID,
		VendorID:         model.VendorIDELM,
		OrderType:        model.OrderTypeOrder,
		RefVendorOrderID: msg.OrderID,
		RefVendorID:      model.VendorIDELM,
		VendorStatus:     c.stateAndType2Str(msg.RefundStatus, msg.MsgType),
		StatusTime:       utils.Timestamp2Time(msg.UpdateTime),
	}
	return orderStatus
}

func (c *PurchaseHandler) onOrderStatusMsg(msg *elmapi.CallbackOrderStatusMsg) (retVal *elmapi.CallbackResponse) {
	status := c.orderStatusMsg2Status(msg)
	switch msg.MsgType {
	case elmapi.MsgTypeOrderAccepted:
		status.Status = model.OrderStatusAccepted
	case elmapi.MsgTypeOrderCanceled, elmapi.MsgTypeOrderInvalid, elmapi.MsgTypeOrderForceInvalid:
		status.Status = model.OrderStatusCanceled
	case elmapi.MsgTypeOrderFinished:
		status.Status = model.OrderStatusFinished
	default:
		return elmapi.SuccessResponse
	}
	err := partner.CurOrderManager.OnOrderStatusChanged("", status)

	// 直接跳到拣货完成
	if msg.MsgType == elmapi.MsgTypeOrderAccepted {
		status.Status = model.OrderStatusFinishedPickup
		status.VendorStatus = fakePickedUp
		err = partner.CurOrderManager.OnOrderStatusChanged("", status)
	}
	// if globals.HandleLegacyJxOrder && err == nil {
	// 	c.legacyElmOrderStatusChanged(status)
	// }
	return elmapi.Err2CallbackResponse(err, status.VendorStatus)
}

func (c *PurchaseHandler) onOrderCancelRefundMsg(msg *elmapi.CallbackOrderCancelRefundMsg) (retVal *elmapi.CallbackResponse) {
	status := c.cancelRefundMsg2Status(msg)
	switch msg.MsgType {
	case elmapi.MsgTypeUserApplyCancel:
		status.Status = model.OrderStatusApplyCancel
	case elmapi.MsgTypeUserApplyRefund:
		// status.Status = model.OrderStatusApplyRefund
	default:
		status.Status = model.OrderStatusUnknown
	}
	return elmapi.Err2CallbackResponse(partner.CurOrderManager.OnOrderStatusChanged("", status), status.VendorStatus)
}

func (c *PurchaseHandler) GetOrder(vendorOrgCode, orderID string) (order *model.GoodsOrder, err error) {
	result, err := api.ElmAPI.GetOrder(orderID)
	if err == nil {
		order = c.Map2Order(result)
	}
	return order, err
}

func (c *PurchaseHandler) Map2Order(orderData map[string]interface{}) (order *model.GoodsOrder) {
	result := orderData
	orderID := result["id"].(string)
	phoneList := result["phoneList"].([]interface{})
	consigneeMobile := ""
	if len(phoneList) > 0 {
		consigneeMobile = utils.Interface2String(phoneList[0])
	}

	order = &model.GoodsOrder{
		VendorOrderID:         orderID,
		VendorID:              model.VendorIDELM,
		VendorStoreID:         utils.Int64ToStr(utils.MustInterface2Int64(result["shopId"])),
		StoreID:               int(utils.Str2Int64WithDefault(utils.Interface2String(result["openId"]), 0)),
		StoreName:             result["shopName"].(string),
		ConsigneeName:         result["consignee"].(string),
		ConsigneeMobile:       jxutils.FormalizeMobile(consigneeMobile),
		ConsigneeAddress:      result["address"].(string),
		BuyerComment:          utils.TrimBlankChar(utils.Interface2String(result["description"])),
		ExpectedDeliveredTime: utils.Str2TimeWithDefault(utils.Interface2String(result["deliverTime"]), utils.DefaultTimeValue),
		PickDeadline:          utils.DefaultTimeValue,
		VendorStatus:          utils.Interface2String(result["status"]), // 取订单的原始status，不合并消息类型（因为当前消息类型没有意义）
		OrderSeq:              int(utils.MustInterface2Int64(result["daySn"])),
		StatusTime:            utils.Str2Time(result["activeAt"].(string)),
		OriginalData:          string(utils.MustMarshal(result)),
		ActualPayPrice:        jxutils.StandardPrice2Int(utils.MustInterface2Float64(result["totalPrice"])),
		Skus:                  []*model.OrderSku{},
	}
	order.Status = c.getStatusFromVendorStatus(order.VendorStatus)
	if result["book"].(bool) {
		order.BusinessType = model.BusinessTypeDingshida
	} else {
		order.BusinessType = model.BusinessTypeImmediate
	}
	deliveryGeo := strings.Split(utils.Interface2String(result["deliveryGeo"]), ",")
	if len(deliveryGeo) == 2 {
		order.CoordinateType = model.CoordinateTypeMars
		order.ConsigneeLng = jxutils.StandardCoordinate2Int(utils.Str2Float64(deliveryGeo[0]))
		order.ConsigneeLat = jxutils.StandardCoordinate2Int(utils.Str2Float64(deliveryGeo[1]))
	}

	for _, group2 := range result["groups"].([]interface{}) {
		group := group2.(map[string]interface{})
		for _, product2 := range group["items"].([]interface{}) {
			product := product2.(map[string]interface{})
			sku := &model.OrderSku{
				VendorOrderID: orderID,
				VendorID:      model.VendorIDELM,
				Count:         int(utils.MustInterface2Int64(product["quantity"])),
				SkuID:         int(utils.Str2Int64WithDefault(utils.Interface2String(product["extendCode"]), 0)),
				VendorSkuID:   utils.Int64ToStr(utils.Interface2Int64WithDefault(product["vfoodId"], 0)),
				SkuName:       product["name"].(string),
				SalePrice:     jxutils.StandardPrice2Int(utils.MustInterface2Float64(product["price"])),
				Weight:        int(math.Round(utils.Interface2Float64WithDefault(product["weight"], 0.0))),
			}
			if dao.IsVendorThingIDEmpty(sku.VendorSkuID) {
				sku.VendorSkuID = utils.Int64ToStr(utils.MustInterface2Int64(product["id"])) // 2018-09-28日，饿了么迁移到饿百后，这个字段发生了变化
			}
			order.Skus = append(order.Skus, sku)
		}
	}
	jxutils.RefreshOrderSkuRelated(order)
	return order
}

//
func (c *PurchaseHandler) onOrderNew(msg map[string]interface{}) (response *elmapi.CallbackResponse) {
	// todo 这里应该可以直接用msg里的内容，而不用再次去查
	order, err := c.GetOrder("", msg["orderId"].(string))
	if err == nil {
		order.VendorStatus = c.stateAndType2Str(order.VendorStatus, elmapi.MsgTypeOrderValid)
		err = partner.CurOrderManager.OnOrderNew(order, nil)
		// if globals.HandleLegacyJxOrder && err == nil {
		// 	c.legacyWriteElmOrder(order)
		// }
	}
	return elmapi.Err2CallbackResponse(err, "elm onOrderNew")
}

func (c *PurchaseHandler) onOrderUserUrgeOrder(msg *elmapi.CallbackOrderUrgeMsg) *elmapi.CallbackResponse {
	status := &model.OrderStatus{
		VendorOrderID:    msg.OrderID,
		VendorID:         model.VendorIDELM,
		OrderType:        model.OrderTypeOrder,
		RefVendorOrderID: msg.OrderID,
		RefVendorID:      model.VendorIDELM,
		Status:           model.OrderStatusApplyUrgeOrder,
		VendorStatus:     utils.Int2Str(msg.MsgType),
		StatusTime:       utils.Timestamp2Time(msg.UpdateTime),
	}
	c.ClientUrgeOrder(msg.OrderID)
	return elmapi.Err2CallbackResponse(partner.CurOrderManager.OnOrderStatusChanged("", status), status.VendorStatus)
}

func (c *PurchaseHandler) stateAndType2Str(state string, msgType int) string {
	return fmt.Sprintf("%s-%d", state, msgType)
}

func (c *PurchaseHandler) spliltCompositeState(compositeState string) (state string, msgType int) {
	index := strings.Index(compositeState, "-")
	if index >= 0 {
		msgType = int(utils.Str2Int64(compositeState[index+1:]))
		if msgType == 0 {
			globals.SugarLogger.Debug(compositeState)
		}
		return compositeState[:index], msgType
	}
	return compositeState, 0
}

// IPurchasePlatformHandler
func (c *PurchaseHandler) getStatusFromVendorStatus(vendorStatus string) int {
	state, _ := c.spliltCompositeState(vendorStatus)
	if status, ok := VendorStatus2StatusMap[state]; ok {
		return status
	}
	return model.OrderStatusUnknown
}

func (c *PurchaseHandler) AcceptOrRefuseOrder(order *model.GoodsOrder, isAcceptIt bool, userName string) (err error) {
	// if globals.EnableElmStoreWrite {
	// 	if isAcceptIt {
	// 		err = api.ElmAPI.ConfirmOrder(order.VendorOrderID)
	// 	} else {
	// 		err = api.ElmAPI.CancelOrder(order.VendorOrderID, elmapi.CancelOrderTypeOthers, "")
	// 	}
	// }
	return err
}

// 饿了么没有拣货这个状态，直接返回成功
// 真实流程中也不会调用这个方法，因为接收订单后状态会直接转移到已拣货
func (c *PurchaseHandler) PickupGoods(order *model.GoodsOrder, isSelfDelivery bool, userName string) (err error) {
	return nil
}

func (p *PurchaseHandler) AcceptOrRefuseFailedGetOrder(ctx *jxcontext.Context, order *model.GoodsOrder, isAcceptIt bool) (err error) {
	return err
}

func (p *PurchaseHandler) CallCourier(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 拣货失败后再次招唤平台配送
	return err
}

func (p *PurchaseHandler) ConfirmReceiveGoods(ctx *jxcontext.Context, order *model.GoodsOrder) (err error) { // 投递失败后确认收到退货
	return err
}

func (c *PurchaseHandler) Swtich2SelfDeliver(order *model.GoodsOrder, userName string) (err error) {
	// if globals.EnableElmStoreWrite {
	// 	err = api.ElmAPI.DeliveryBySelfLite(order.VendorOrderID)
	// }
	return err
}

// 饿了么转商家自送后，没有确认送达的概念，空操作
func (c *PurchaseHandler) Swtich2SelfDelivered(order *model.GoodsOrder, userName string) (err error) {
	return nil
}

func (c *PurchaseHandler) SelfDeliverDelivering(order *model.GoodsOrder, userName string) (err error) {
	// if globals.EnableElmStoreWrite {
	// 	err = api.ElmAPI.StartDeliveryBySelf(order.VendorOrderID, order.ConsigneeMobile)
	// }
	return err
}

func (c *PurchaseHandler) SelfDeliverDelivered(order *model.GoodsOrder, userName string) (err error) {
	// if globals.EnableElmStoreWrite {
	// 	err = api.ElmAPI.CompleteDeliveryBySelf(order.VendorOrderID, order.ConsigneeMobile)
	// }
	return err
}

func (c *PurchaseHandler) GetStatusActionTimeout(order *model.GoodsOrder, statusType, status int) (params *partner.StatusActionParams) {
	if statusType == scheduler.TimerStatusTypeOrder && status == model.OrderStatusNew {
		params = &partner.StatusActionParams{ // 饿了么开了专送店的订单没有拣货状态，接单后就为拣货完成，所以要延迟接单，否则门店来不及备货
			Timeout: acceptOrderDelay,
		}
	}
	return params
}

func (c *PurchaseHandler) GetOrderRealMobile(ctx *jxcontext.Context, order *model.GoodsOrder) (mobile string, err error) {
	err = errors.New("饿了么还未实现GetOrderRealMobile")
	return mobile, err
}

func (c *PurchaseHandler) AgreeOrRefuseCancel(ctx *jxcontext.Context, order *model.GoodsOrder, isAgree bool, reason string, refundParam interface{}) (err error) {
	return err
}

func (c *PurchaseHandler) CancelOrder(ctx *jxcontext.Context, order *model.GoodsOrder, reason string) (err error) {
	return err
}

func (c *PurchaseHandler) AdjustOrder(ctx *jxcontext.Context, order *model.GoodsOrder, removedSkuList []*model.OrderSku, reason string) (err error) {
	return err
}

// 转自配送时取消非专送混合送门店取消理由
func (c *PurchaseHandler) GetCancelDeliveryReason(order *model.GoodsOrder) (string, error) {
	return "", nil
}

// 取消美团外卖理由转使用三方配送
func (c *PurchaseHandler) CancelLogisticsByWmOrderId(order *model.GoodsOrder, reasonCode, detailContent, appPoiCode, orderId string) error {
	return nil
}

// 获取订单配送状态
func (c *PurchaseHandler) OrderLogisticsStatus(orderId string) (*utils.RiderInfo, error) {
	return nil, nil
}

// GetOrderSettleAccounts 获取订单结算信息
func (c *PurchaseHandler) GetOrderSettleAccounts(order *model.GoodsOrder) (int64, error) {
	return 0, nil
}

// ApplyCompensationOrder 订单索赔
func (c *PurchaseHandler) ApplyCompensationOrder(order *model.GoodsOrder) (string, error) {
	return "", nil
}

// UploadInvoice 回复用户发票申请
func (c *PurchaseHandler) UploadInvoice(param *model.InvoiceMsg) ([]string, []string, error) {
	return nil, nil, nil
}

// UploadPickingImg  上传拣货图片
func (c *PurchaseHandler) UploadPickingImg(order *model.GoodsOrder, imgList interface{}) error {
	return nil
}
