package itao

import (
	"context"
	"github.com/gogf/gf/encoding/gjson"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/util/gconv"
)

type orderItao struct {
}

var Order = orderItao{}

type OrderBeforeReq struct {
	Address OrderAddress `json:"deliveryAddressInfo"`
	List    []OrderItem  `json:"itemRequestList"`
}

type OrderAddress struct {
	AddressDetail string `json:"addressDetail"`
	City          string `json:"city"`
	CityId        int64  `json:"cityId"`
	Area          string `json:"district"`
	AreaId        int64  `json:"districtId"`
	FullName      string `json:"fullName"`
	Mobile        string `json:"mobile"`
	Prov          string `json:"prov"`
	ProvId        int64  `json:"provId"`
	Town          string `json:"town"`
	TownId        int64  `json:"townId"`
}

type OrderItem struct {
	Info struct {
		ItemId int64 `json:"itemId"`
		SkuId  int64 `json:"skuId"`
	} `json:"itemInfo"`
	Quantity uint `json:"quantity"`
}

type OrderBeforeRes struct {
	Result struct {
		Result struct {
			ExtensionResp struct {
				TradeId string `json:"tradeId"`
			} `json:"extensionResp"`
			InvalidOrderGroups []struct { //不可售商品
				Image            string `json:"image"`
				OrderLineRenders []struct {
					ErrorMessage struct {
						ErrorCode string `json:"errorCode"`
						ErrorMsg  string `json:"errorMsg"`
					} `json:"errorMessage"`
					ItemInfo struct {
						ItemId string `json:"itemId"`
						SkuId  string `json:"skuId"`
					} `json:"itemInfo"`
					ItemPayPrice uint  `json:"itemPayPrice"`
					OrderLineId  int64 `json:"orderLineId"`
					Quantity     uint  `json:"quantity"`
				} `json:"orderLineRenders"`
				OrderPayPrice int    `json:"orderPayPrice"`
				Quantity      uint   `json:"quantity"`
				SellerToken   string `json:"sellerToken"`
				Title         string `json:"title"`
			} `json:"invalidOrderGroups"`
			OriginPriceFee    uint           `json:"originPriceFee"`
			PriceFee          uint           `json:"priceFee"` //单位分
			PromotionResp     OrderPromotion `json:"promotionResp"`
			Quantity          uint           `json:"quantity"`
			RealPayPrice      uint           `json:"realPayPrice"`
			ReceiveMethodInfo struct {
				DeliveryAddressId int           `json:"deliveryAddressId"`
				Options           []interface{} `json:"options"`
			} `json:"receiveMethodInfo"`
			ValidOrderGroups []struct { //可售商品
				DeliveryMethodInfo struct {
					DeliveryMethodOptionList []struct {
						FareCent    uint   `json:"fareCent"` //运费 单位分
						Id          string `json:"id"`
						ServiceType int    `json:"serviceType"`
					} `json:"deliveryMethodOptionList"`
					SelectedId string `json:"selectedId"`
				} `json:"deliveryMethodInfo"`
				Image            string `json:"image"`
				OrderLineRenders []struct {
					ErrorMessage struct {
						ErrorCode string `json:"errorCode"`
						ErrorMsg  string `json:"errorMsg"`
					}
					ItemInfo struct {
						ItemId string `json:"itemId"`
						SkuId  string `json:"skuId"`
					} `json:"itemInfo"`
					ItemPayPrice uint  `json:"itemPayPrice"`
					OrderLineId  int64 `json:"orderLineId"`
					Quantity     uint  `json:"quantity"`
				} `json:"orderLineRenders"`
				OrderPayPrice uint   `json:"orderPayPrice"`
				Quantity      uint   `json:"quantity"`
				SellerToken   string `json:"sellerToken"`
				Title         string `json:"title"`
			} `json:"validOrderGroups"`
		} `json:"result"`
		Success bool   `json:"success"`
		ErrMsg  string `json:"errMsg"`
		ErrCode string `json:"errCode"`
	} `json:"result"`
}

type OrderPromotion struct {
	CrossShopPromotions []struct {
		Discount     int      `json:"discount"`
		IdValues     []string `json:"idValues"`
		PromotionKey string   `json:"promotionKey"`
	} `json:"crossShopPromotions"`
	InvalidPromotions []interface {
	} `json:"invalidPromotions"`
	ItemPromotions []struct {
		HasPromotion bool `json:"hasPromotion"`
		IdValues     []interface {
		} `json:"idValues"`
		OrderLineId       int64 `json:"orderLineId"`
		PromotionPriceMap struct {
			LtaoMonthPkCard int `json:"ltaoMonthPkCard"`
		} `json:"promotionPriceMap"`
	} `json:"itemPromotions"`
	ShopPromotions []struct {
		Discount             int  `json:"discount"`
		GoldStandardDiscount int  `json:"goldStandardDiscount"`
		HasShopPromotion     bool `json:"hasShopPromotion"`
		IdValues             []interface {
		} `json:"idValues"`
		OutId       string `json:"outId"`
		SellerToken string `json:"sellerToken"`
	} `json:"shopPromotions"`
}

//Before 前置校验
func (s orderItao) Before(ctx context.Context, req OrderBeforeReq) (res *OrderBeforeRes, err error) {
	method := "com.alibaba.c2m/ltao.trade.renderOrder"

	result, err := server.Post(ctx, method, g.Map{
		"request": req,
	})
	_ = gjson.NewWithOptions(result, gjson.Options{
		StrNumber: true,
	}).Scan(&res)
	return
}

type OrderCreateReq struct {
	Address       OrderAddress      `json:"deliveryAddressInfo"`
	List          []OrderCreateItem `json:"orderDTOs"`
	PromotionResp OrderPromotion    `json:"promotionResp"`
}
type OrderCreateItem struct {
	DTO     []OrderCreateDto `json:"orderLineDTOs"`
	OrderSn string           `json:"outId"`
	Token   string           `json:"sellerToken"`
}

type OrderCreateDto struct {
	GoodsID  int64 `json:"itemId"`
	SkuId    int64 `json:"skuId"`
	Quantity uint  `json:"buyQuantity"`
	LineId   int64 `json:"orderLineId"`
}

type OrderCreateRes struct {
	Result struct {
		Result struct {
			AlipaySuccess        bool `json:"alipaySuccess"`
			EnablingOrdersResult struct {
				Model struct {
					AlipayTradeIds []string `json:"alipayTradeIds"`
					OrderIds       []string `json:"orderIds"`
					RedirectUrl    string   `json:"redirectUrl"`
				} `json:"model"`
			} `json:"enablingOrdersResult"`
			ExtensionResult struct {
				TraceId string `json:"traceId"`
			} `json:"extensionResult"`
			PartSuccess bool `json:"partSuccess"`
			Success     bool `json:"success"`
		} `json:"result"`
		Success bool   `json:"success"`
		ErrMsg  string `json:"errMsg"`
		ErrCode string `json:"errCode"`
	} `json:"result"`
}

//Create 下单
func (s orderItao) Create(ctx context.Context, req OrderCreateReq) (res *OrderCreateRes, err error) {
	method := "com.alibaba.c2m/ltao.trade.createAndEnableOrder"

	result, err := server.Post(ctx, method, g.Map{
		"request": req,
	})
	_ = gjson.NewWithOptions(result, gjson.Options{
		StrNumber: true,
	}).Scan(&res)
	return
}

type OrderDetailRes struct {
	Result struct {
		Result struct {
			BizOrderId      int64  `json:"bizOrderId"`
			BuyAmount       int    `json:"buyAmount"`
			BuyerToken      string `json:"buyerToken"`
			Detail          int    `json:"detail"`
			DetailOrderList []struct {
				BizOrderId string `json:"bizOrderId"`
				BuyAmount  int    `json:"buyAmount"`
				BuyerToken string `json:"buyerToken"`
				Detail     int    `json:"detail"`
				EndTime    string `json:"endTime"`
				GmtCreate  string `json:"gmtCreate"`
				ItemInfo   struct {
					ItemId      string `json:"itemId"`
					Pic         string `json:"pic"`
					Price       uint   `json:"price"`
					SkuId       string `json:"skuId"`
					SkuInfoList []struct {
						Name  string `json:"name"`
						Value string `json:"value"`
					} `json:"skuInfoList"`
					Title string `json:"title"`
				} `json:"itemInfo"`
				LogisticsOrderId int64  `json:"logisticsOrderId"`
				LogisticsStatus  int    `json:"logisticsStatus"`
				Main             int    `json:"main"`
				ParentId         int64  `json:"parentId"`
				PayFee           uint   `json:"payFee"`
				PayOrderId       int64  `json:"payOrderId"`
				PayStatus        int    `json:"payStatus"`
				PayTime          string `json:"payTime"`
				PostFee          uint   `json:"postFee"`
				RefundStatus     int    `json:"refundStatus"`
				SellerToken      string `json:"sellerToken"`
				Status           int    `json:"status"`
			} `json:"detailOrderList"`
			EndTime   string `json:"endTime"`
			GmtCreate string `json:"gmtCreate"`
			ItemInfo  struct {
				ItemId      string `json:"itemId"`
				Pic         string `json:"pic"`
				Price       uint   `json:"price"`
				SkuId       string `json:"skuId"`
				SkuInfoList []struct {
					Name  string `json:"name"`
					Value string `json:"value"`
				} `json:"skuInfoList"`
				Title string `json:"title"`
			} `json:"itemInfo"`
			LogisticsOrderId int64 `json:"logisticsOrderId"`
			LogisticsStatus  int   `json:"logisticsStatus"`
			//1 - 未发货 -> 等待卖家发货
			//2 - 已发货 -> 等待买家确认收货
			//3 - 已收货 -> 交易成功
			//4 - 已经退货 -> 交易失败
			//5 - 部分收货 -> 交易成功
			//6 - 部分发货中
			//8 - 还未创建物流订单
			Main       int   `json:"main"`
			ParentId   int64 `json:"parentId"`
			PayFee     uint  `json:"payFee"`
			PayOrderId int64 `json:"payOrderId"`
			PayStatus  int   `json:"payStatus"`
			//1 - 未冻结/未付款 -> 等待买家付款
			//2 - 已冻结/已付款 -> 等待卖家发货
			//4 - 已退款 -> 交易关闭
			//6 - 已转交易 -> 交易成功
			//7 - 没有创建外部交易
			//8 - 交易被关闭
			//9 - 不可付款
			PayTime      string `json:"payTime"`
			PostFee      uint   `json:"postFee"`
			RefundStatus int    `json:"refundStatus"`
			SellerToken  string `json:"sellerToken"`
			Status       int    `json:"status"`
		} `json:"result"`
		Success bool   `json:"success"`
		ErrMsg  string `json:"errMsg"`
		ErrCode string `json:"errCode"`
	} `json:"result"`
}

//Detail 详情
func (s orderItao) Detail(ctx context.Context, req interface{}) (res *OrderDetailRes, err error) {
	method := "com.alibaba.c2m/ltao.trade.queryOrder"

	result, err := server.Post(ctx, method, g.Map{
		"request": g.Map{
			"bizOrderId": gconv.Int64(req),
		},
	})
	_ = gjson.NewWithOptions(result, gjson.Options{
		StrNumber: true,
	}).Scan(&res)
	return
}

type OrderReflectRes struct {
	Result struct {
		Result struct {
			BizOrderId      string `json:"bizOrderId"`
			BuyAmount       uint   `json:"buyAmount"`
			BuyerToken      string `json:"buyerToken"`
			Detail          int    `json:"detail"`
			DetailOrderList []struct {
				BizOrderId string `json:"bizOrderId"`
				BuyAmount  uint   `json:"buyAmount"`
				BuyerToken string `json:"buyerToken"`
				Detail     int    `json:"detail"`
				GmtCreate  string `json:"gmtCreate"`
				ItemInfo   struct {
					ItemId      string        `json:"itemId"`
					Pic         string        `json:"pic"`
					Price       uint          `json:"price"`
					SkuId       string        `json:"skuId"`
					SkuInfoList []interface{} `json:"skuInfoList"`
					Title       string        `json:"title"`
				} `json:"itemInfo"`
				LogisticsOrderId int64  `json:"logisticsOrderId"`
				LogisticsStatus  int    `json:"logisticsStatus"`
				Main             int    `json:"main"`
				ParentId         int64  `json:"parentId"`
				PayFee           uint   `json:"payFee"`
				PayOrderId       int64  `json:"payOrderId"`
				PayStatus        int    `json:"payStatus"`
				PostFee          uint   `json:"postFee"`
				RefundStatus     int    `json:"refundStatus"`
				SellerToken      string `json:"sellerToken"`
				Status           int    `json:"status"`
			} `json:"detailOrderList"`
			GmtCreate string `json:"gmtCreate"`
			ItemInfo  struct {
				ItemId      string        `json:"itemId"`
				Pic         string        `json:"pic"`
				Price       uint          `json:"price"`
				SkuId       string        `json:"skuId"`
				SkuInfoList []interface{} `json:"skuInfoList"`
				Title       string        `json:"title"`
			} `json:"itemInfo"`
			LogisticsOrderId int64  `json:"logisticsOrderId"`
			LogisticsStatus  int    `json:"logisticsStatus"`
			Main             int    `json:"main"`
			ParentId         string `json:"parentId"`
			PayFee           uint   `json:"payFee"`
			PayOrderId       string `json:"payOrderId"`
			PayStatus        int    `json:"payStatus"`
			PostFee          uint   `json:"postFee"`
			RefundStatus     int    `json:"refundStatus"`
			SellerToken      string `json:"sellerToken"`
			Status           int    `json:"status"`
		} `json:"result"`
		Success bool   `json:"success"`
		ErrMsg  string `json:"errMsg"`
		ErrCode string `json:"errCode"`
	} `json:"result"`
}

//Reflect 详情[反查]
func (s orderItao) Reflect(ctx context.Context, req string) (res *OrderReflectRes, err error) {
	method := "com.alibaba.c2m/ltao.trade.queryOrderByOutId"

	result, err := server.Post(ctx, method, g.Map{
		"request": g.Map{
			"outOrderId": req,
		},
	})
	_ = gjson.NewWithOptions(result, gjson.Options{
		StrNumber: true,
	}).Scan(&res)
	return
}

type OrderPayRes struct {
	Result struct {
		ErrCode string `json:"errCode"`
		ErrMsg  string `json:"errMsg"`
		Success bool   `json:"success"`
	} `json:"result"`
}

func (s orderItao) Pay(ctx context.Context, req string) (res *OrderPayRes, err error) {
	method := "com.alibaba.c2m/ltao.pay.agreementPay"

	result, err := server.Post(ctx, method, g.Map{
		"request": g.Map{
			"bizOrderId": req,
		},
	})
	_ = gjson.NewWithOptions(result, gjson.Options{
		StrNumber: true,
	}).Scan(&res)
	return
}