package jdshopapi

import (
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"strings"
	"time"

	"git.rosy.net.cn/baseapi/utils"
)

const (
	OrderStatusPopPause = "POP_ORDER_PAUSE"
	OrderStatusPause    = "PAUSE"
	OrderStatusWait     = "WAIT_SELLER_STOCK_OUT"
	OrderStatusCancel   = "TRADE_CANCELED"

	IdSopShipmenttypeTC = "71" //同城配送，需要调其他接口获取期望送货时间
)

//订单出库
//https://open.jd.com/home/home#/doc/api?apiCateId=55&apiId=1948&apiName=jingdong.pop.order.shipment
func (a *API) OrderShipment(orderID int64, logiCoprId, logiNo string) (err error) {
	result, err := a.AccessAPI("jingdong.pop.order.shipment", prodURL, map[string]interface{}{
		"orderId":    orderID,
		"logiCoprId": logiCoprId,
		"logiNo":     logiNo,
	})
	if err == nil {
		if !result["jingdong_pop_order_shipment_responce"].(map[string]interface{})["sopjosshipment_result"].(map[string]interface{})["success"].(bool) {
			return fmt.Errorf("OrderShipment error: %v", result["jingdong_pop_order_shipment_responce"].(map[string]interface{})["sopjosshipment_result"].(map[string]interface{})["chineseErrCode"])
		}
	}
	return err
}

//获取商家物流公司
//https://open.jd.com/home/home#/doc/api?apiCateId=75&apiId=582&apiName=360buy.get.vender.all.delivery.company
func (a *API) GetDeliveryCompany() (result interface{}, err error) {
	var params = map[string]interface{}{
		"fields": "id,name",
	}
	data, _ := json.Marshal(params)
	result, err = a.AccessAPI("360buy.get.vender.all.delivery.company", prodURL, map[string]interface{}{
		"360buy_param_json": string(data),
	})
	if err == nil {

	}
	return result, err
}

type GetOrderResult struct {
	OrderStateRemark string `json:"orderStateRemark"`
	OrderRemark      string `json:"orderRemark"`
	OrderSellerPrice string `json:"orderSellerPrice"`
	OrderState       string `json:"orderState"`
	OrderType        string `json:"orderType"`
	ConsigneeInfo    struct {
		ProvinceID  string `json:"provinceId"`
		FullAddress string `json:"fullAddress"`
		CityID      string `json:"cityId"`
		TownID      string `json:"townId"`
		City        string `json:"city"`
		County      string `json:"county"`
		Province    string `json:"province"`
		Town        string `json:"town"`
		Telephone   string `json:"telephone"`
		Fullname    string `json:"fullname"`
		CountyID    string `json:"countyId"`
		Mobile      string `json:"mobile"`
	} `json:"consigneeInfo"`
	OrderPayment string `json:"orderPayment"`
	PayType      string `json:"payType"`
	ItemInfoList []struct {
		ProductNo        string `json:"productNo"`
		ItemTotal        string `json:"itemTotal"`
		JdPrice          string `json:"jdPrice"`
		SkuName          string `json:"skuName"`
		InvoiceContentID string `json:"invoiceContentId"`
		// ItemExt          string `json:"itemExt"`
		NewStoreID string `json:"newStoreId"`
		OuterSkuID string `json:"outerSkuId"`
		SkuID      string `json:"skuId"`
		WareID     string `json:"wareId"`
		GiftPoint  string `json:"giftPoint"`
	} `json:"itemInfoList"`
	StoreID           string `json:"storeId"`
	OrderTotalPrice   string `json:"orderTotalPrice"`
	OrderExt          string `json:"orderExt"`
	StoreOrder        string `json:"storeOrder"`
	OrderStartTime    string `json:"orderStartTime"`
	OrderID           string `json:"orderId"`
	OrderSource       string `json:"orderSource"`
	FreightPrice      string `json:"freightPrice"`
	Pin               string `json:"pin"`
	IDSopShipmenttype string `json:"idSopShipmenttype"`
	ScDT              string `json:"scDT"`
	SellerDiscount    string `json:"sellerDiscount"`
	MenDianID         string `json:"menDianId"`
	BalanceUsed       string `json:"balanceUsed"`
}

type OrderExt struct {
	AerfaTimeIDSopShipmentType string `json:"aerfaTime.idSopShipmentType"`
	PromiseMsg                 string `json:"promiseMsg"`
	Road                       string `json:"road"`
	Contact                    string `json:"contact"`
	O2ODeliveryTime            string `json:"o2oDeliveryTime"`
	SiteID                     string `json:"siteId"`
	StoreName                  string `json:"storeName"`
}

//查询单个订单
//https://open.jd.com/home/home#/doc/api?apiCateId=55&apiId=4247&apiName=jingdong.pop.order.get
func (a *API) GetOrder(orderID int64, isStatus bool) (getOrderResult *GetOrderResult, err error) {
	params := make(map[string]interface{})
	params["order_id"] = orderID
	params["optional_fields"] = `orderType,payType,orderTotalPrice,orderSellerPrice,
	orderPayment,freightPrice,orderState,orderStateRemark,
	orderStartTime,orderEndTime,orderRemark,consigneeInfo,
	itemInfoList,pauseBizInfo,pin,idSopShipmenttype,scDT,sellerDiscount,menDianId,storeId,balanceUsed,orderExt`
	if isStatus {
		params["order_state"] = "WAIT_SELLER_STOCK_OUT,TRADE_CANCELED,PAUSE,WAIT_GOODS_RECEIVE_CONFIRM,FINISHED_L"
	}

	result, err := a.AccessAPI("jingdong.pop.order.get", prodURL, params)
	if err == nil {
		utils.Map2StructByJson(result["jingdong_pop_order_get_responce"].(map[string]interface{})["orderDetailInfo"].(map[string]interface{})["orderInfo"], &getOrderResult, false)
	}
	return getOrderResult, err
}

type VoucherInfoGetResult struct {
	Sig  string `json:"sig"`
	Data struct {
		Act       string `json:"act"`
		Effective int64  `json:"effective"`
		Expired   int64  `json:"expired"`
		ID        string `json:"id"`
		Key       string `json:"key"`
		Service   string `json:"service"`
		Stype     int    `json:"stype"`
	} `json:"data"`
	ExternalData struct {
		Zone string `json:"zone"`
	} `json:"externalData"`
}

//获取解密凭证
//https://open.jd.com/home/home#/doc/api?apiCateId=243&apiId=3093&apiName=jingdong.jos.voucher.info.get
func (a *API) VoucherInfoGet() (voucherInfoGetResult *VoucherInfoGetResult, err error) {
	result, err := a.AccessAPI("jingdong.jos.voucher.info.get", prodURL, nil)
	if err == nil {
		data, err2 := base64.StdEncoding.DecodeString(result["jingdong_jos_voucher_info_get_responce"].(map[string]interface{})["response"].(map[string]interface{})["data"].(map[string]interface{})["voucher"].(string))
		if err2 == nil {
			json.Unmarshal(data, &voucherInfoGetResult)
		}
		err = err2
	}
	return voucherInfoGetResult, err
}

type KeyGetSign struct {
	SdkVer int    `json:"sdk_ver"`
	Ts     int64  `json:"ts"`
	Tid    string `json:"tid"`
}

type KeyGetResult struct {
	Code     string `json:"code"`
	Response struct {
		StatusCode        int    `json:"status_code"`
		KeyCacheDisabled  int    `json:"key_cache_disabled"`
		KeyBackupDisabled int    `json:"key_backup_disabled"`
		Ts                int64  `json:"ts"`
		EncService        string `json:"enc_service"`
		ErrorMsg          string `json:"errorMsg"`
		Tid               string `json:"tid"`
		ServiceKeyList    []struct {
			CurrentKeyVersion int `json:"current_key_version"`
			Keys              []struct {
				ID           string `json:"id"`
				KeyExp       int64  `json:"key_exp"`
				KeyStatus    int    `json:"key_status"`
				KeyDigest    string `json:"key_digest"`
				KeyType      string `json:"key_type"`
				KeyString    string `json:"key_string"`
				KeyEffective int64  `json:"key_effective"`
				Version      int    `json:"version"`
			} `json:"keys"`
			Service    string `json:"service"`
			GrantUsage string `json:"grant_usage"`
		} `json:"service_key_list"`
	} `json:"response"`
}

//获取解密密钥
//https://open.jd.com/home/home#/doc/api?apiCateId=243&apiId=4262&apiName=jingdong.jos.master.key.get
func (a *API) KeyGet() (keyGetResult *KeyGetResult, err error) {
	voucherInfoGetResult, err := a.VoucherInfoGet()
	if err != nil {
		return keyGetResult, err
	}
	var (
		sdkVer = 2
		ts     = time.Now().Unix()
		tid    = voucherInfoGetResult.Data.ID
	)
	keyGetSign := &KeyGetSign{
		SdkVer: sdkVer,
		Ts:     ts,
		Tid:    tid,
	}
	data, err := json.Marshal(keyGetSign)
	if err != nil {
		return keyGetResult, err
	}
	key, err := base64.StdEncoding.DecodeString(voucherInfoGetResult.Data.Key)
	if err != nil {
		return keyGetResult, err
	}
	h := hmac.New(sha256.New, key)
	h.Write(data)
	result, err := a.AccessAPI("jingdong.jos.master.key.get", prodURL, map[string]interface{}{
		"sig":     base64.StdEncoding.EncodeToString(h.Sum(nil)),
		"sdk_ver": sdkVer,
		"ts":      ts,
		"tid":     tid,
	})
	if err == nil {
		utils.Map2StructByJson(result["jingdong_jos_master_key_get_responce"], &keyGetResult, false)
	}
	return keyGetResult, err
}

type GetOrderExtInfoByOrderIdResult struct {
	IDSopShipmentType   string `json:"idSopShipmentType"`
	OrderCreateDate     string `json:"orderCreateDate"`
	CodDate             string `json:"codDate"`
	SelectedItem        string `json:"selectedItem"`
	Batch               string `json:"batch"`
	DeliveryCodTime     string `json:"deliveryCodTime"`
	Speedhour           string `json:"Speedhour"`
	FinalDelieveredTime string `json:"finalDelieveredTime"`
}

//获取期望送货时间
func (a *API) GetOrderExtInfoByOrderId(orderId string) (time string, err error) {
	getOrderExtInfoByOrderIdResult := &GetOrderExtInfoByOrderIdResult{}
	result, err := a.AccessAPI("jingdong.pop.order.getOrderExtInfoByOrderId", prodURL, map[string]interface{}{
		"orderId":      orderId,
		"searchFileds": "deliveryInfo",
	})
	if err == nil {
		str := strings.ReplaceAll(result["jingdong_pop_order_getOrderExtInfoByOrderId_responce"].(map[string]interface{})["orderExtraInfoResultModel"].(map[string]interface{})["resultMap"].(map[string]interface{})["deliveryInfo"].(string), "\\", "")
		err = json.Unmarshal([]byte(str), &getOrderExtInfoByOrderIdResult)
		exTime := strings.Split(getOrderExtInfoByOrderIdResult.DeliveryCodTime, ",")
		if len(exTime) < 2 {
			time = getOrderExtInfoByOrderIdResult.FinalDelieveredTime
		} else {
			exTime2 := strings.Split(exTime[1], "-")
			time = exTime[0] + " " + exTime2[1] + ":00"
		}
	}
	return time, err
}
