package fn

import (
	"fmt"
	"git.rosy.net.cn/baseapi/utils"
	"strconv"
	"strings"

	"git.rosy.net.cn/jx-callback/business/jxutils"
	"git.rosy.net.cn/jx-callback/business/partner/delivery"

	"git.rosy.net.cn/jx-callback/business/model/dao"

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

	"git.rosy.net.cn/baseapi/platformapi/fnpsapi"
	"git.rosy.net.cn/jx-callback/business/model"
	"git.rosy.net.cn/jx-callback/business/partner"
	"git.rosy.net.cn/jx-callback/globals/api"
)

const (
	ComplaintReasonsFn150 = 150 //:未保持餐品完整，
	ComplaintReasonsFn220 = 220 //:少餐错餐，
	ComplaintReasonsFn160 = 160 //:服务态度恶劣，
	ComplaintReasonsFn190 = 190 //:额外索取费用，
	ComplaintReasonsFn170 = 170 //:诱导收货人或商户退单，
	ComplaintReasonsFn140 = 140 //:提前点击送达，
	ComplaintReasonsFn210 = 210 //:虚假标记异常，
	ComplaintReasonsFn200 = 200 //:虚假点击配送成功，
	ComplaintReasonsFn130 = 130 //:未进行配送，导致订单失败或取消，
	ComplaintReasonsFn120 = 120 //:配送超时
)

var (
	curDeliveryHandler        *DeliveryHandler
	complaintReson2FnResonMap = map[int]int{
		model.ComplaintReasons1:  ComplaintReasonsFn160,
		model.ComplaintReasons2:  ComplaintReasonsFn130,
		model.ComplaintReasons3:  ComplaintReasonsFn130,
		model.ComplaintReasons4:  ComplaintReasonsFn120,
		model.ComplaintReasons5:  ComplaintReasonsFn130,
		model.ComplaintReasons6:  ComplaintReasonsFn150,
		model.ComplaintReasons7:  ComplaintReasonsFn190,
		model.ComplaintReasons69: ComplaintReasonsFn170,
		model.ComplaintReasons71: ComplaintReasonsFn140,
	}
)

type DeliveryHandler struct {
}

func init() {
	if api.FnAPI != nil {
		curDeliveryHandler = new(DeliveryHandler)
		partner.RegisterDeliveryPlatform(curDeliveryHandler, true)
	}
}

func (c *DeliveryHandler) GetVendorID() int {
	return model.VendorIDFengNiao
}

func (c *DeliveryHandler) CancelWaybill(bill *model.Waybill, cancelReasonID int, cancelReason string) (err error) {
	parameter := &fnpsapi.CancelOrderReq{
		OrderCancelCode: fnpsapi.OrderCancelReson9,
		OrderCancelRole: 2,
	}
	parameter.PartnerOrderCode = bill.VendorOrderID

	if err = api.FnAPI.CancelOrder(parameter); err != nil {
		if strings.Contains(err.Error(), "运单暂未生成") {
			err = nil
		}
	}

	bill.Status = model.WaybillStatusCanceled
	bill.Remark = cancelReason
	partner.CurOrderManager.OnWaybillStatusChanged(bill)
	fmt.Println("fn cancle order ============", err)
	return err
}

func (c *DeliveryHandler) ComplaintRider(bill *model.Waybill, resonID int, resonContent string) (err error) {
	err = api.FnAPI.ComplaintRider(bill.VendorOrderID, complaintReson2FnResonMap[resonID])
	return err
}

// 创建蜂鸟配送订单
func (c *DeliveryHandler) CreateWaybill(order *model.GoodsOrder, maxDeliveryFee int64) (bill *model.Waybill, err error) {
	db := dao.GetDB()
	// 检查配送平台是否被禁用
	vendorOrgCode, err := dao.GetVendorOrgCode(db, model.VendorIDFengNiao, "", model.VendorOrgTypeDelivery)
	if err != nil {
		return nil, err
	}
	if len(vendorOrgCode) > 0 && vendorOrgCode[0].IsOpen == model.YES {
		return nil, fmt.Errorf("此平台配送已被系统关闭，暂不发配送 [%v]", vendorOrgCode[0].Comment)
	}

	// 蜂鸟入参结构体
	parameter := &fnpsapi.CreateOrderReqParam{
		PartnerOrderCode:      order.VendorOrderID,
		OrderType:             1,
		PositionSource:        3,
		ReceiverAddress:       order.ConsigneeAddress,
		ReceiverLongitude:     utils.Int2Float64(order.ConsigneeLng) / 1000000,
		ReceiverLatitude:      utils.Int2Float64(order.ConsigneeLat) / 1000000,
		GoodsTotalAmountCent:  order.SalePrice,
		GoodsActualAmountCent: order.ActualPayPrice,
		GoodsWeight:           utils.Int2Float64(order.Weight) / 1000,
		GoodsCount:            order.GoodsCount,
		GoodsItemList:         nil,
		ReceiverName:          order.ConsigneeName,
		ReceiverPrimaryPhone:  order.ConsigneeName,
		OutShopCode:           utils.Int2Str(order.JxStoreID),
		ChainStoreId:          "",
	}
	// 重量超标减少配送费
	weight := 4.9500
	if utils.Int2Float64(order.Weight)/1000 >= weight {
		parameter.GoodsWeight = weight
	}

	var goodsList []*fnpsapi.GoodsItemsList
	for _, v := range order.Skus {
		goodsList = append(goodsList, &fnpsapi.GoodsItemsList{
			ItemName:             v.SkuName,
			ItemQuantity:         v.Count,
			ItemAmountCent:       v.SalePrice,
			ItemActualAmountCent: v.SalePrice,
			ItemId:               utils.Int2Str(v.SkuID),
		})
	}
	parameter.GoodsItemList = goodsList

	//要求饿百的订单要传来源
	if order.VendorID == model.VendorIDEBAI {
		parameter.OrderSource = "109"
	}

	// 创建蜂鸟订单
	if err = api.FnAPI.CreateOrder(parameter); err != nil {
		globals.SugarLogger.Debugf("CreateWaybill failed, orderID:%s, billParams:%v, error:%v", order.VendorOrderID, parameter, err)
		return nil, err
	}

	// 查询订单获取配送费
	bill = &model.Waybill{
		VendorOrderID:    order.VendorOrderID,
		OrderVendorID:    order.VendorID,
		VendorWaybillID:  "",
		VendorWaybillID2: "",
		WaybillVendorID:  model.VendorIDFengNiao,
		DesiredFee:       GetDesiredFee(order.VendorOrderID),
	}
	delivery.OnWaybillCreated(bill)
	return bill, err
}

// 预下单获取配送费
func (c *DeliveryHandler) GetWaybillFee(order *model.GoodsOrder) (deliveryFeeInfo *partner.WaybillFeeInfo, err error) {
	preCreateOrder := &fnpsapi.PreCreateOrder{
		PartnerOrderCode:      order.VendorOrderID,
		OrderType:             1,
		PositionSource:        3,
		ReceiverAddress:       order.ConsigneeAddress,
		ReceiverLongitude:     utils.Int2Float64(order.ConsigneeLng) / 1000000,
		ReceiverLatitude:      utils.Int2Float64(order.ConsigneeLat) / 1000000,
		GoodsTotalAmountCent:  order.SalePrice,
		GoodsActualAmountCent: order.ActualPayPrice,
		GoodsWeight:           utils.Int2Float64(order.Weight) / 1000,
		GoodsCount:            order.GoodsCount,
		GoodsItemList:         nil,
		OutShopCode:           utils.Int2Str(order.JxStoreID),
	}
	// 重量超标减少配送费
	weight := 4.9500
	if utils.Int2Float64(order.Weight)/1000 >= weight {
		preCreateOrder.GoodsWeight = weight
	}

	var goodsList []*fnpsapi.GoodsItemsList
	for _, v := range order.Skus {
		goodsList = append(goodsList, &fnpsapi.GoodsItemsList{
			ItemName:             v.SkuName,
			ItemQuantity:         v.Count,
			ItemAmountCent:       v.SalePrice,
			ItemActualAmountCent: v.SalePrice,
			ItemId:               utils.Int2Str(v.SkuID),
		})
	}
	preCreateOrder.GoodsItemList = goodsList

	deliveryFeeInfo = &partner.WaybillFeeInfo{}
	deliveryFeeInfo.RefDeliveryFee, deliveryFeeInfo.RefAddFee, err = api.FnAPI.PreCreateByShopFn(preCreateOrder)
	deliveryFeeInfo.DeliveryFee = deliveryFeeInfo.RefDeliveryFee
	return deliveryFeeInfo, err
}

// 订单状态
func OnWaybillMsg(msg *fnpsapi.OrderStatusNottify) (resp *fnpsapi.CallbackResponse) {
	cc := &fnpsapi.OrderCallbackParam{}
	if err := utils.Map2StructByJson(msg.Param, cc, true); err != nil {
		globals.SugarLogger.Debugf("FNPS  strconv.Atoi fail :[%s]", err)
		return fnpsapi.Err2CallbackResponse(err, "")
	}

	order := &model.Waybill{
		VendorWaybillID:  cc.PartnerOrderCode,
		VendorWaybillID2: utils.Int64ToStr(cc.OrderId),
		WaybillVendorID:  model.VendorIDFengNiao,
		CourierName:      cc.CarrierDriverName,
		CourierMobile:    cc.CarrierDriverPhone,
		VendorStatus:     utils.Int2Str(cc.OrderStatus),
		StatusTime:       utils.Timestamp2Time(cc.PushTime),
		Remark:           cc.Description,
	}
	order.VendorOrderID, order.OrderVendorID = jxutils.SplitUniversalOrderID(cc.PartnerOrderCode)
	orderStatus, err := strconv.Atoi(order.VendorStatus)
	if err != nil {
		globals.SugarLogger.Debugf("FNPS  strconv.Atoi fail :[%s]", err)
		return fnpsapi.Err2CallbackResponse(err, "")
	}
	switch orderStatus {
	case fnpsapi.OrderStatusAcceptCreate: // 0 创建订单
		order.DesiredFee = GetDesiredFee(order.VendorOrderID)
		order.Status = model.WaybillStatusNew //5 带调度
	case fnpsapi.OrderStatusAccept: // 1 新运单
		order.DesiredFee = GetDesiredFee(order.VendorOrderID)
		order.Status = model.WaybillStatusNew //5 带调度
	case fnpsapi.OrderStatusAssigned: //20分配骑手
		order.DesiredFee = GetDesiredFee(order.VendorOrderID)
		order.Status = model.WaybillStatusAccepted //10
		order.Remark = order.CourierName + "，" + order.CourierMobile
	case fnpsapi.OrderStatusArrived: // 80 到店
		order.DesiredFee = GetDesiredFee(order.VendorOrderID)
		order.Status = model.WaybillStatusCourierArrived
	case fnpsapi.OrderStatusDelivering: // 2 配送中
		order.Status = model.WaybillStatusDelivering
	case fnpsapi.OrderStatusDelivered: // 3 已经送达
		order.Status = model.WaybillStatusDelivered
	case fnpsapi.OrderStatusAcceptCacle: // 4取消订单
		order.Status = model.WaybillStatusAcceptCanceled
	case fnpsapi.OrderStatusException: // 5 异常
		order.Status = model.WaybillStatusDeliverFailed // 22
	default:
		globals.SugarLogger.Warnf("onWaybillMsg unknown msg:%v", msg)
	}
	if err := partner.CurOrderManager.OnWaybillStatusChanged(order); err != nil {
		globals.SugarLogger.Debugf("FNPS partner.CurOrderManager.OnWaybillStatusChanged fail :[%s]", err)
		return fnpsapi.Err2CallbackResponse(err, "")
	}
	return fnpsapi.Err2CallbackResponse(nil, "")
}

// 异常报备
func OnWaybillExceptFn(msg *fnpsapi.AbnormalReportNotify) (retVal *fnpsapi.CallbackResponse) {
	return curDeliveryHandler.OnWaybillExcept(msg)
}

func (c *DeliveryHandler) OnWaybillExcept(msg *fnpsapi.AbnormalReportNotify) (retVal *fnpsapi.CallbackResponse) {
	jxutils.CallMsgHandler(func() {
		order := &model.Waybill{
			VendorWaybillID:  msg.PartnerOrderCode,
			VendorWaybillID2: utils.Int64ToStr(msg.OrderId),
			WaybillVendorID:  model.VendorIDFengNiao,
			CourierName:      string(msg.CarrierDriverId),
			CourierMobile:    "",
			Status:           model.WaybillStatusUnknown, // todo 这里要再确定一下是否只要收到订单异常消息就只简单当成一个消息
			VendorStatus:     msg.AbnormalCode,
			StatusTime:       utils.Timestamp2Time(msg.AbnormalReportTime),
		}
		order.VendorOrderID, order.OrderVendorID = jxutils.SplitUniversalOrderID(msg.PartnerOrderCode)
		retVal = fnpsapi.Err2CallbackResponse(partner.CurOrderManager.OnWaybillStatusChanged(order), "fn OnWaybillExcept")
	}, jxutils.ComposeUniversalOrderID(msg.PartnerOrderCode, model.VendorIDFengNiao))
	return retVal
}

// 查询订单配送费
func GetDesiredFee(vendorOrderID string) (desiredFee int64) {
	if result, err := api.FnAPI.QueryOrder(vendorOrderID); err == nil {
		return result.OrderActualAmountCent
	}
	return desiredFee
}
