package fnpsapi

import (
	"encoding/json"
	"errors"
	"fmt"
	"git.rosy.net.cn/baseapi/utils"
	"net/http"
	"time"
)

const (
	OrderCancelReson0  = 0  // 0:其它（必填原因）必须填写原因
	OrderCancelReson1  = 1  // 1:物流原因：订单长时间未分配骑手
	OrderCancelReson4  = 4  // 4:商品缺货/无法出货/已售完,
	OrderCancelReson6  = 6  // 6:商户发错单,
	OrderCancelReson7  = 7  // 7:商户/顾客自身定位错误,
	OrderCancelReson8  = 8  // 8:商户改其他第三方配送,
	OrderCancelReson9  = 9  // 9:顾客下错单/临时不想要了,
	OrderCancelReson10 = 10 // 10:顾客自取/不在家/要求另改时间配送）（0类型已下线）
	OrderCancelReson32 = 32 // 32:订单信息填写错误
	OrderCancelReson36 = 36 // 36:重复下单了
	OrderCancelReson2  = 2  // 2:物流原因：分配骑手后，骑手长时间未取件(类型已下线)
	OrderCancelReson3  = 3  // 3:物流原因：骑手告知不配送，让取消订单(类型已下线)
	OrderCancelReson5  = 5  // 5:商户联系不上门店/门店关门了(类型已下线)

	OrderStatusAcceptCreate = 0  //订单生成
	OrderStatusAcceptCacle  = 4  //订单取消
	OrderStatusAccept       = 1  //系统已接单
	OrderStatusAssigned     = 20 //已分配骑手
	OrderStatusArrived      = 80 //已到店
	OrderStatusDelivering   = 2  //配送中
	OrderStatusDelivered    = 3  //已送达
	OrderStatusException    = 5  //异常

	WayBillPressureOrderTime  = 1200000 // 蜂鸟分配骑手超过二十分钟不扣款
	WayBillPressureOrderTime2 = 60000   // 蜂鸟分配骑手超过不足一分钟不扣款
)

// 蜂鸟预下单
func (a *API) PreCreateByShopFn(basicParams *PreCreateOrder) (deliveryFee, baseDeliveryFee int64, err error) {
	preOrder := a.MakeFnRequestHead()
	bytes, err := json.Marshal(basicParams)
	if err != nil {
		return 0, 0, err
	}
	preOrder["business_data"] = string(bytes)
	result, err := a.AccessAPI(ApiURL, "preCreateOrder", http.MethodPost, preOrder)
	if err != nil {
		return 0, 0, err
	}

	preOrderResult := PreCreateOrderResp{}
	if err := json.Unmarshal([]byte(result["business_data"].(string)), &preOrderResult); err != nil {
		return 0, 0, err
	}

	// 返回所有可选的商品列表，每项包含当前使用该商品下单时对应的价格等信息，(其中不可用的商品会返回不可用原因) 可挑选其中一个可用的商品进行正式下单。
	var deliveryFeeFn int64
	var baseDeliveryFeeFn int64
	for _, v := range preOrderResult.GoodsInfos {
		if v.IsValid != 1 {
			continue
		}
		deliveryFeeFn = v.TotalDeliveryAmountCent     // 优惠后 actual_delivery_amount_cent
		baseDeliveryFeeFn = v.TotalDeliveryAmountCent // 原始配送费
	}

	// 异常检测
	if deliveryFeeFn == 0 && baseDeliveryFeeFn == 0 {
		return 0, 0, errors.New(preOrderResult.GoodsInfos[0].DisableReason)
	}
	return deliveryFeeFn, baseDeliveryFeeFn, nil
}

// 蜂鸟正式下单
func (a *API) CreateOrder(createOrderParam *CreateOrderReqParam) (result string, err error) {
	orderHead := a.MakeFnRequestHead()
	bytes, err := json.Marshal(createOrderParam)
	if err != nil {
		return "", err
	}
	orderHead["business_data"] = string(bytes)
	resultData, err := a.AccessAPI(ApiURL, "createOrder", http.MethodPost, orderHead)
	if err != nil {
		return "", err
	}

	if utils.Interface2String(resultData["code"]) != "200" {
		return "", fmt.Errorf(fmt.Sprintf("其他异常错误信息:%s", utils.Interface2String(resultData["apiCode"])))
	}
	if orderId, ok := resultData["business_data"]; ok {
		res := &CreateOrderRes{}
		if err := json.Unmarshal([]byte(utils.Interface2String(orderId)), res); err != nil {
			return "", err
		}
		return utils.Int64ToStr(res.OrderId), nil
	}
	return "", err
}

// addTip 加小费接口
func (a *API) AddTip(req *AddTipRes) (err error) {
	if req.PartnerOrderCode == "" && req.OrderId == "" {
		return errors.New("内部订单号或者外部订单号比填写一个")
	}

	orderHead := a.MakeFnRequestHead()
	addTipString, err := json.Marshal(req)
	if err != nil {
		return err
	}

	orderHead["businessData"] = string(addTipString)
	if _, err = a.AccessAPI(ApiURL, "addTip", http.MethodPost, orderHead); err != nil {
		return err
	}
	return nil
}

// getCancelReasonList 获取可用取消原因列表(暂油前端写死)
func (a *API) GetCancelReasonList(req *GetOrderDetailReq) (result *GetCancelReasonListRes, err error) {
	if req.PartnerOrderCode == "" && req.OrderId == "" {
		return nil, errors.New("内部订单号或者外部订单号比填写一个")
	}

	a.timestamp = time.Now().Unix() * 1000
	orderHead := a.MakeFnRequestHead()
	business, err := json.Marshal(req)
	if err != nil {
		return nil, err
	}
	orderHead["businessData"] = string(business)
	data, err := a.AccessAPI(ApiURL, "getCancelReasonList", http.MethodPost, orderHead)
	if err != nil {
		return nil, err
	}

	cancel := make(map[string]*GetCancelReasonListRes, 0)
	if k, ok := data["business_data"]; ok {
		if err := json.Unmarshal([]byte(utils.Interface2String(k)), cancel); err != nil {
			return nil, err
		}
	}
	return cancel["cancel_reason_list"], nil
}

// preCancelOrder 预取消订单接口,获取取消订单需要扣除的金额
func (a *API) PreCancelOrder(req *PreCancelOrderReq) (actualCancelCostCent int64, err error) {
	if req.PartnerOrderCode == "" && req.OrderId == "" {
		return 0, errors.New("内部订单号或者外部订单号比填写一个")
	}
	orderHead := a.MakeFnRequestHead()
	business, err := json.Marshal(req)
	if err != nil {
		return 0, err
	}
	orderHead["businessData"] = string(business)

	data, err := a.AccessAPI(ApiURL, "preCancelOrder", http.MethodPost, orderHead)
	if err != nil {
		return 0, err
	}

	if k, ok := data["businessData"]; ok {
		return utils.MustInterface2Int64(k), nil
	}
	return
}

// CancelOrder  取消订单
func (a *API) CancelOrder(req *CancelOrderReq) (err error) {
	if req.PartnerOrderCode == "" && req.OrderId == "" {
		return errors.New("内部订单号或者外部订单号比填写一个")
	}
	req.OrderCancelOtherReason = "暂时不想要了"

	orderHead := a.MakeFnRequestHead()
	business, err := json.Marshal(req)
	if err != nil {
		return err
	}
	orderHead["business_data"] = string(business)

	data, err := a.AccessAPI(ApiURL, "cancelOrder", http.MethodPost, orderHead)
	if err != nil {
		return err
	}
	if data["code"].(string) != "200" {
		return errors.New(data["msg"].(string))
	}
	return nil
}

// 查询订单详情接口
func (a *API) QueryOrder(partnerOrderCode string) (result *GetOrderDetailRes, err error) {
	orderHead := a.MakeFnRequestHead()
	bytes, err := json.Marshal(&GetOrderDetailReq{PartnerOrderCode: partnerOrderCode})
	if err != nil {
		return nil, err
	}

	orderHead["business_data"] = string(bytes)
	data, err := a.AccessAPI(ApiURL, "getOrderDetail", http.MethodPost, orderHead)
	if err != nil {
		return nil, err
	}

	fnResult := &GetOrderDetailRes{}
	if err := json.Unmarshal([]byte(data["business_data"].(string)), &fnResult); err != nil {
		return nil, err
	}
	fnResult.OrderTotalAmountCent += (int64(utils.WayBillDeliveryMarkUp) * 2) // 系统加价
	return fnResult, nil
}

// 查询骑手信息
func (a *API) GetKnightInfo(req *GetOrderDetailReq) (result *GetKnightInfoRes, err error) {
	if req.PartnerOrderCode == "" && req.OrderId == "" {
		return nil, errors.New("内部订单号或者外部订单号比填写一个")
	}

	orderHead := a.MakeFnRequestHead()
	bytes, err := json.Marshal(req)
	if err != nil {
		return nil, err
	}
	orderHead["business_data"] = string(bytes)

	data, err := a.AccessAPI(ApiURL, "getKnightInfo", http.MethodPost, orderHead)
	if err != nil {
		return nil, err
	}

	fnResult := &GetKnightInfoRes{}
	if err := json.Unmarshal([]byte(utils.Interface2String(data["business_data"])), &fnResult); err != nil {
		return nil, err
	}
	return fnResult, nil
}

// 余额查询
func (a *API) GetAmount() (outAmount map[string]interface{}, err error) {
	orderHead := a.MakeFnRequestHead()
	result, err := a.AccessAPI(ApiURL, "getAmount", http.MethodPost, orderHead)
	if err != nil {
		return nil, err
	}
	return result, err
}

//order_cancel_reason_code 订单取消原因代码(1:用户取消,2:商家取消)
// order_cancel_code	订单取消编码（
// 1:物流原因：订单长时间未分配骑手,
// 2:物流原因：分配骑手后，骑手长时间未取件 ,
// 3:物流原因：骑手告知不配送，让取消订单,
// 4:商品缺货/无法出货/已售完, 5:商户联系不上门店/门店关门了, 6:商户发错单,
// 7:商户/顾客自身定位错误, 8:商户改其他第三方配送, 9:顾客下错单/临时不想要了,
// 10:顾客自取/不在家/要求另改时间配送）（0类型已下线）
func (a *API) ComplaintOrder(req *ComplaintOrderReq) (err error) {
	if req.PartnerOrderCode == "" && req.OrderId == "" {
		return errors.New("内部订单号或者外部订单号比填写一个")
	}
	orderHead := a.MakeFnRequestHead()
	bytes, err := json.Marshal(req)
	if err != nil {
		return err
	}
	orderHead["businessData"] = string(bytes)
	_, err = a.AccessAPI(ApiURL, "cancelOrder", http.MethodPost, orderHead)
	return err
}

func (a *API) ComplaintRider(partnerOrderCode string, orderId string, orderComplaintCode int, resonDes string) (err error) {
	orderHead := a.MakeFnRequestHead()

	bytes, err := json.Marshal(map[string]interface{}{
		"order_id":             orderId,
		"order_complaint_code": orderComplaintCode,
		"order_complaint_desc": resonDes,
		//"partner_order_code":   partnerOrderCode,
	})
	if err != nil {
		return err
	}
	orderHead["business_data"] = string(bytes)
	_, err = a.AccessAPI(ApiURL, "complaintOrder", http.MethodPost, orderHead)
	return err
}
