package jingdong

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

type goodsJD struct {
}

var Goods = goodsJD{}

type CheckSaleRes struct {
	*CommonRes
	Result []struct {
		SkuId       int    `json:"skuid"`       //商品编号
		Name        string `json:"name"`        //商品名称
		SaleState   int    `json:"saleState"`   //是否可售 1:是,0:否
		IsCanVAT    int    `json:"isCanVAT"`    //是否可开增票,1:支持,0:不支持
		Is7ToReturn int    `json:"is7ToReturn"` //是否支持7天退货,1:是,0:不支持
	} `json:"result"`
}

type CheckOnSaleRes struct {
	*CommonRes
	Result []struct {
		Sku   int `json:"sku"`   //商品编号
		State int `json:"state"` //1:上架,0:下架
	} `json:"result"`
}
type GetStockMidRes struct {
	*CommonRes
	Result string `json:"result"`
}

type GetStockRes struct {
	*CommonRes
	Result []struct {
		SkuID          int    `json:"skuId"`          //商品编号
		AreaID         string `json:"areaId"`         //入参时传入的区域码area。因京东目前是3、4级地址均支持,存在areaId在传入的3级地址后填充4级地址“_0“后返回的情况。
		StockStateID   int    `json:"stockStateId"`   //存状态编号。 参考枚举值: 33,39,40,36,34,99
		StockStateDesc string `json:"StockStateDesc"` /*库存状态描述。以下为stockStateId不同时,此字段不同的返回值:
		33 有货 现货-下单立即发货
		39 有货 在途-正在内部配货,预计2~6天到达本仓库
		40 有货 可配货-下单后从有货仓库配货
		36 预订
		34 无货
		99 无货开预定*/
	} `json:"result"`
}

type CheckAreaMidRes struct {
	*CommonRes
	Result string `json:"result"`
}

type CheckAreaLimitRes struct {
	*CommonRes
	Result []struct {
		SkuID          int  `json:"skuId"`          //商品编码
		IsAreaRestrict bool `json:"isAreaRestrict"` //true 代表区域受限 false 区域不受限
	} `json:"result"`
}

type GetProductsPriceRes struct {
	*CommonRes
	Result []struct {
		SkuID       int     `json:"skuId"`       //商品编码
		Price       float64 `json:"price"`       //京东销售价
		JdPrice     float64 `json:"jdPrice"`     //京东价
		MarketPrice float64 `json:"marketPrice"` //京东的前台划线价
	} `json:"result"`
}

type GetDetailRes struct {
	*CommonRes
	Result struct {
		SaleUnit       string      `json:"saleUnit"`       //售卖单位
		Weight         string      `json:"weight"`         //重量
		ProductArea    string      `json:"productArea"`    //产地
		WareQD         string      `json:"wareQD"`         //包装清单
		ImagePath      string      `json:"imagePath"`      //主图
		State          int         `json:"state"`          //状态
		Sku            int         `json:"sku"`            //商品编号
		BrandName      string      `json:"brandName"`      //品牌名称
		Category       string      `json:"category"`       //分类		示例"670;729;4837"
		Name           string      `json:"name"`           //商品名称
		Introduction   string      `json:"introduction"`   //商品详情页大字段
		IsFactoryShip  string      `json:"isFactoryShip"`  //1 厂商直送;0 非厂商直送
		IsSelf         int         `json:"isSelf"`         //是否自营
		LowestBuy      interface{} `json:"LowestBuy"`      //商品最低起购量
		Wxintroduction string      `json:"wxintroduction"` //微信小程序商品详情大字段,仅提供图片地址
	} `json:"result"`
}

type GetCategoryRes struct {
	*CommonRes //异常代码(3422:获取分类列表信息失败;3423:分类列表不存在;1003:参数值不正确;5001:服务异常,请稍后重试;)
	Result     struct {
		TotalRows int `json:"totalRows"`
		PageNo    int `json:"pageNo"`
		PageSize  int `json:"pageSize"`
		Categorys []struct {
			CatId    int    `json:"catId"`    //分类ID
			ParentId int    `json:"parentId"` //父分类ID
			Name     string `json:"name"`     //分类名称
			CatClass int    `json:"catClass"` //0:一级分类;1:二级分类;2:三级分类;
			State    int    `json:"state"`
		} `json:"categorys"`
	} `json:"result"`
}

type GetSkuImageRes struct {
	*CommonRes //异常代码(0010:返回数据为空;1001:参数为空;1003:参数值不正确/sku数量过多,目前最大支持100个商品)
	Result     map[string][]struct {
		Id    int    `json:"id"`    //编号
		SkuId int    `json:"skuId"` //商品编号
		Path  string `json:"path"`  //图片路径
	} `json:"result"`
}

type GetSimilarSkuRes struct {
	*CommonRes
	Result []struct {
		Dim          int        `json:"dim"`      //维度
		SaleName     string     `json:"saleName"` //销售名称
		SaleAttrList []struct { //商品销售标签  销售属性下可能只有一个标签,此种场景可以选择显示销售名称和标签,也可以不显示
			ImagePath string `json:"imagePath"` //标签图片地址
			SaleValue string `json:"saleValue"` //标签名称
			SkuIds    []int  `json:"skuIds"`    //当前标签下的同类商品skuId

		} `json:"saleAttrList"` //

	} `json:"result"`
}

// CheckSale 商品可售验证接口
func (*goodsJD) CheckSale(ctx context.Context, req *garray.Array) (res *CheckSaleRes, err error) {
	method := "product/check"
	param := g.Map{
		"skuIds": req.Join(","),
	}
	result, err := server.requestApi(ctx, method, param)
	if err != nil {
		return
	}

	err = gjson.New(result).Scan(&res)
	return
}

// CheckOnSale 查询商品上下架状态
func (*goodsJD) CheckOnSale(ctx context.Context, req *garray.Array) (res *CheckOnSaleRes, err error) {
	method := "product/skuState"
	param := g.Map{
		"sku": req.Join(","),
	}
	result, err := server.requestApi(ctx, method, param)
	if err != nil {
		return
	}
	err = gjson.New(result).Scan(&res)
	return
}

//GetStock  查询商品库存
func (*goodsJD) GetStock(ctx context.Context, req []*SkuNums, area string) (res *GetStockRes, err error) {
	method := "stock/getNewStockById"
	param := g.Map{
		"skuNums": gjson.New(req).MustToJsonString(),
		"area":    area,
	}
	result, err := server.requestApi(ctx, method, param)
	if err != nil {
		return
	}
	var middle *GetStockMidRes
	err = gjson.New(result).Scan(&middle)
	if err != nil {
		return
	}
	err = gjson.New(middle.CommonRes).Scan(&res)
	if err != nil {
		return
	}

	err = gjson.New(middle.Result).Scan(&res.Result)
	return
}

// CheckAreaLimit 查询商品区域购买限制
func (*goodsJD) CheckAreaLimit(ctx context.Context, skuIds *garray.Array, provinceID, cityID, countyID, townID interface{}) (res *CheckAreaLimitRes, err error) {
	method := "product/checkAreaLimit"
	param := g.Map{
		"skuIds":   skuIds.Join(","),
		"province": gconv.String(provinceID),
		"city":     gconv.String(cityID),
		"county":   gconv.String(countyID),
		"town":     gconv.String(townID),
	}
	result, err := server.requestApi(ctx, method, param)
	if err != nil {
		return
	}
	var middle *CheckAreaMidRes
	err = gjson.New(result).Scan(&middle)
	if err != nil {
		return
	}
	err = gjson.New(middle.CommonRes).Scan(&res)
	if err != nil {
		return
	}
	err = gjson.New(middle.Result).Scan(&res.Result)
	return
}

//GetProductsPrice 查询商品价格
func (*goodsJD) GetProductsPrice(ctx context.Context, skus *garray.Array) (res *GetProductsPriceRes, err error) {
	method := "price/getSellPrice"
	param := g.Map{
		"sku":       skus.Join(","),
		"queryExts": "marketPrice",
	}
	result, err := server.requestApi(ctx, method, param)
	if err != nil {
		return
	}
	err = gjson.New(result).Scan(&res)
	return
}

//GetDetail 查询商品详情
func (*goodsJD) GetDetail(ctx context.Context, skus interface{}) (res *GetDetailRes, err error) {
	method := "product/getDetail"
	param := g.Map{
		"sku":       gconv.String(skus),
		"queryExts": "spuId,pName,isFactoryShip,isSelf,LowestBuy,wxintroduction",
	}
	result, err := server.requestApi(ctx, method, param)
	if err != nil {
		return
	}
	err = gjson.New(result).Scan(&res)
	return
}

//GetCategory 查询分类列表
func (*goodsJD) GetCategory(ctx context.Context, pageNo, pageSize interface{}) (res *GetCategoryRes, err error) {
	method := "product/getCategorys"
	param := g.Map{
		"pageNo":   gconv.String(pageNo),
		"pageSize": gconv.String(pageSize),
	}
	result, err := server.requestApi(ctx, method, param)
	if err != nil {
		return
	}
	err = gjson.New(result).Scan(&res)
	return
}

//GetSkuImage  查询商品图片
func (*goodsJD) GetSkuImage(ctx context.Context, skus *garray.Array) (res *GetSkuImageRes, err error) {
	method := "product/skuImage"
	param := g.Map{
		"sku": skus.Join(","),
	}
	result, err := server.requestApi(ctx, method, param)
	if err != nil {
		return
	}
	err = json.Unmarshal([]byte(result), &res)
	return
}

//GetSimilarSku 查询同类商品
func (*goodsJD) GetSimilarSku(ctx context.Context, skus interface{}) (res *GetSimilarSkuRes, err error) {
	method := "product/getSimilarSku"
	param := g.Map{
		"skuId": skus,
	}
	result, err := server.requestApi(ctx, method, param)
	if err != nil {
		return
	}
	err = gjson.New(result).Scan(&res)
	return
}

type GetPageNumRes struct {
	Success       bool   `json:"success"`
	ResultCode    string `json:"resultCode"`
	ResultMessage string `json:"resultMessage"`
	Result        []struct {
		Name    string `json:"name"`
		PageNum string `json:"page_num"`
	} `json:"result"`
}

//GetPageNum  查询商品池编号
func (*goodsJD) GetPageNum(ctx context.Context) (res *GetPageNumRes, err error) {
	method := "product/getPageNum"
	param := g.Map{}
	result, err := server.requestApi(ctx, method, param)
	if err != nil {
		return
	}
	err = gjson.New(result).Scan(&res)
	return
}

type QueryByPageRes struct {
	Success       bool   `json:"success"`
	ResultMessage string `json:"resultMessage"`
	ResultCode    string `json:"resultCode"`
	Result        struct {
		RemainPage int   `json:"remainPage"`
		Skus       []int `json:"skus"`
		Offset     int   `json:"offset"`
	} `json:"result"`
}

//QueryByPage  查询池内商品编号
func (*goodsJD) QueryByPage(ctx context.Context, pageNum, pageNo, offset interface{}) (res *QueryByPageRes, err error) {
	method := "product/querySkuByPage"
	param := g.Map{
		"pageNum":  pageNum,
		"pageSize": pageNo,
		"offset":   offset,
	}
	result, err := server.requestApi(ctx, method, param)
	if err != nil {
		return
	}
	err = gjson.New(result).Scan(&res)
	return
}

type GoodsSearchReq struct {
	Keyword    string `json:"Keyword,omitempty"`    //搜索关键字,需要编码
	Cid1       string `json:"cid1,omitempty"`       //一级分类
	Cid2       string `json:"cid2,omitempty"`       //二级分类
	CatId      string `json:"catId,omitempty"`      //分类Id,只支持三级类目Id
	PageIndex  int    `json:"pageIndex"`            //当前第几页
	PageSize   int    `json:"pageSize"`             //当前页显示
	Min        string `json:"Min,omitempty"`        //价格区间搜索,低价
	Max        string `json:"Max,omitempty"`        //价格区间搜索,高价
	Brands     string `json:"Brands,omitempty"`     //品牌搜索 多个品牌以逗号分隔,需要编码
	PriceCol   string `json:"priceCol,omitempty"`   //价格汇总 	priceCol=”yes”
	ExtAttrCol string `json:"extAttrCol,omitempty"` //扩展属性汇总	extAttrCol=”yes”
	MergeSku   bool   `json:"mergeSku,omitempty"`   //true:合并同一产品不同规格sku;false:不合并同一产品不同规格sku
	SortType   string `json:"sortType,omitempty"`   //销量降序="sale_desc";	价格升序="price_asc";	价格降序="price_desc";	上架时间降序="winsdate_desc";
	//按销量排序_15天销售额="sort_totalsales15_desc";	按15日销量排序="sort_days_15_qtty_desc";	按30日销量排序="sort_days_30_qtty_desc";
	//按15日销售额排序="sort_days_15_gmv_desc";	按30日销售额排序="sort_days_30_gmv_desc";

}

type GoodsSearchRes struct {
	CommonRes
	Result struct {
		ResultCount    int `json:"resultCount"`
		PageSize       int `json:"pageSize"`
		PageIndex      int `json:"pageIndex"`
		PageCount      int `json:"pageCount"`
		BrandAggregate struct {
			PinyinAggr []string `json:"pinyinAggr"`
			BrandList  []struct {
				Id     string `json:"id"`
				Pinyin string `json:"pinyin"`
				Name   string `json:"name"`
			} `json:"brandList"`
		} `json:"brandAggregate"`
		PriceIntervalAggregate []struct {
			Min int `json:"min"`
			Max int `json:"max"`
		} `json:"priceIntervalAggregate"`
		CategoryAggregate struct {
			FirstCategory []struct {
				CatId    int    `json:"catId"`
				Count    int    `json:"count"`
				ParentId int    `json:"parentId"`
				Field    string `json:"field"`
				Name     string `json:"name"`
				Weight   int    `json:"weight"`
			} `json:"firstCategory"`
			SecondCategory []struct {
				CatId    int    `json:"catId"`
				Count    int    `json:"count"`
				ParentId int    `json:"parentId"`
				Field    string `json:"field"`
				Name     string `json:"name"`
				Weight   int    `json:"weight"`
			} `json:"secondCategory"`
			ThridCategory []struct {
				CatId    int    `json:"catId"`
				Count    int    `json:"count"`
				ParentId int    `json:"parentId"`
				Field    string `json:"field"`
				Name     string `json:"name"`
				Weight   int    `json:"weight"`
			} `json:"thridCategory"`
		} `json:"categoryAggregate"`
		ExpandAttrAggregate interface{} `json:"expandAttrAggregate"`
		HitResult           []struct {
			WareId   string      `json:"wareId"`
			WarePId  string      `json:"warePId"`
			BrandId  string      `json:"brandId"`
			Brand    string      `json:"brand"`
			WareName string      `json:"wareName"`
			CatName  interface{} `json:"catName"`
			ImageUrl string      `json:"imageUrl"`
			CatId    string      `json:"catId"`
			Cid1     string      `json:"cid1"`
			Cid2     string      `json:"cid2"`
			Cid1Name interface{} `json:"cid1Name"`
			Cid2Name interface{} `json:"cid2Name"`
			Wstate   string      `json:"wstate"`
			Wyn      string      `json:"wyn"`
			Synonyms interface{} `json:"synonyms"`
		} `json:"hitResult"`
	} `json:"result"`
}

//Search  搜索商品
func (*goodsJD) Search(ctx context.Context, req GoodsSearchReq) (res *GoodsSearchRes, err error) {
	method := "/search/search"
	result, err := server.requestApi(ctx, method, gconv.Map(req))
	if err != nil {
		return
	}
	err = gjson.New(result).Scan(&res)
	return
}

type GoodsBeforeReq struct {
	SkuId int     `json:"skuId"`
	Num   int     `json:"num"`
	Price float64 `json:"price"`
}

type GoodsBeforeBase struct {
	CommonRes
	Result string `json:"result"`
}

type GoodsBeforeRes struct {
	CommonRes
	Result []struct {
		SkuID       string
		CanPurchase bool
		MessageList []string
	}
}

// Before 下单前商品校验
func (*goodsJD) Before(ctx context.Context, req []GoodsBeforeReq, address *garray.StrArray) (res *GoodsBeforeRes, err error) {
	method := "/stock/checkSkuSaleStateAndStock"
	var request = g.Map{
		"skuNums": gjson.New(req).MustToJsonString(),
		"area":    address.Join("_"),
	}
	result, err := server.requestApi(ctx, method, request)
	if err != nil {
		return
	}
	var base *GoodsBeforeBase
	_ = gjson.New(result).Scan(&base)
	res = &GoodsBeforeRes{}
	res.CommonRes = base.CommonRes
	_ = gjson.New(base.Result).Scan(&res.Result)
	return
}