package elmapi

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

const (
	CategoryTypeNormal      = "NORMAL"
	CategoryTypeRequired    = "REQUIRED"
	CategoryTypeIndependent = "INDEPENDENT"
)

const (
	MaxPageSize = 300
)

// 这个类型商家店内分类与饿了么分类共用，
type CategoryInfo struct {
	Id           int64           `json:"id"`
	Name         string          `json:"name"`
	Description  string          `json:"description"` // 店内分类独有
	IsValid      bool            `json:"isValid"`     // 店内分类独有
	ParentId     int64           `json:"parentId"`
	CategoryType string          `json:"categoryType"` // 店内分类独有
	Level        int             `json:"level"`        // 饿了么分类独有
	IsLeaf       bool            `json:"isLeaf"`       // 饿了么分类独有
	Children     []*CategoryInfo `json:"children"`
}

type CategorySortInfo struct {
	ParentId    int64 `json:"parentId"`
	ChildrenIDs []int `json:"childrenIds"`
}

type OItemIdWithSpecIds struct {
	ItemId      int64   `json:"itemId"`
	ItemSpecIds []int64 `json:"itemSpecIds"`
}

type OBatchModifiedFailure struct {
	Id          int64  `json:"id"`
	Code        string `json:"code"`
	Description string `json:"description"`
}

const (
	IdTypeItem     = "ITEM_ID"
	IdTypeSpec     = "SPEC_ID"
	IdTypeCategory = "CATEGORY_ID"
)

type OBatchModifiedResult struct {
	Type          string                   `json:"type"`
	Modifications []int64                  `json:"modifications"`
	Failures      []*OBatchModifiedFailure `json:"failures"`
}

type OItemIdWithSpecPrice struct {
	ItemId   int64              `json:"itemId"`
	PriceMap map[string]float64 `json:"priceMap"`
}

// 查询店铺商品分类，包含二级分类
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-category-getShopCategoriesWithChildren
func (a *API) GetShopCategoriesWithChildren(shopId int) ([]*CategoryInfo, error) {
	result, err := a.AccessAPI("eleme.product.category.getShopCategoriesWithChildren", utils.Params2Map(KeyShopID, shopId))
	if err == nil {
		return interface2CatList(result.Result, 1, nil), nil
	}
	return nil, err
}

// 查询商品分类详情，包含二级分类
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-category-getCategoryWithChildren
func (a *API) GetCategoryWithChildren(categoryId int64) (*CategoryInfo, error) {
	result, err := a.AccessAPI("eleme.product.category.getCategoryWithChildren", utils.Params2Map("categoryId", categoryId))
	if err == nil {
		return interface2Cat(result.Result, 1), nil
	}
	return nil, err
}

// 添加商品分类，支持二级分类
// parentID小于0表示忽略?
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-category-createCategoryWithChildren
func (a *API) CreateCategoryWithChildren(shopId int, parentId int64, name, description string) (*CategoryInfo, error) {
	params := map[string]interface{}{
		KeyShopID: shopId,
		"name":    name,
	}
	if parentId >= 0 {
		params["parentId"] = parentId
	}
	if description != "" {
		params["description"] = description
	}
	result, err := a.AccessAPI("eleme.product.category.createCategoryWithChildren", params)
	if err == nil {
		return interface2Cat(result.Result, 1), nil
	}
	return nil, err
}

// 更新商品分类，包含二级分类
// parentID小于0表示忽略?
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-category-updateCategoryWithChildren
func (a *API) UpdateCategory(shopId int, parentId int64, name, description string) (*CategoryInfo, error) {
	params := map[string]interface{}{
		KeyShopID: shopId,
		"name":    name,
	}
	if parentId >= 0 {
		params["parentId"] = parentId
	}
	if description != "" {
		params["description"] = description
	}
	result, err := a.AccessAPI("eleme.product.category.updateCategory", params)
	if err == nil {
		return interface2Cat(result.Result, 1), nil
	}
	return nil, err
}

// 删除商品分类(新版)
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-category-invalidCategory
func (a *API) InvalidCategory(categoryId int64) error {
	_, err := a.AccessAPI("eleme.product.category.invalidCategory", utils.Params2Map("categoryId", categoryId))
	return err
}

// 设置二级分类排序
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-category-setCategoryPositionsWithChildren
func (a *API) setCategoryPositionsWithChildren(shopId int, categoryWithChildrenIds []*CategorySortInfo) error {
	_, err := a.AccessAPI("eleme.product.category.setCategoryPositionsWithChildren", utils.Params2Map(KeyShopID, shopId, "categoryWithChildrenIds", categoryWithChildrenIds))
	return err
}

// 设置分类排序(新版)
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-category-setCategorySequence
func (a *API) setCategorySequence(shopId int, categoryIds []int64) error {
	_, err := a.AccessAPI("eleme.product.category.setCategorySequence", utils.Params2Map(KeyShopID, shopId, "categoryIds", categoryIds))
	return err
}

// 查询商品后台类目
// 注意，这个是饿了么的商品分类，不是商家商品分类
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-category-getBackCategory
func (a *API) GetBackCategory(shopId int) ([]*CategoryInfo, error) {
	result, err := a.AccessAPI("eleme.product.category.getBackCategory", utils.Params2Map(KeyShopID, shopId))
	if err == nil {
		return interface2CatList(result.Result, 1, func(data interface{}, level int) (cat *CategoryInfo) {
			mapData, ok := data.(map[string]interface{})
			if ok {
				cat = &CategoryInfo{
					Id:       utils.MustInterface2Int64(mapData["id"]),
					Name:     utils.Interface2String(mapData["name"]),
					ParentId: utils.MustInterface2Int64(mapData["parentId"]),
					Level:    int(utils.MustInterface2Int64(mapData["lev"])),
					IsLeaf:   mapData["leaf"].(bool),
				}
			}
			return cat
		}), nil
	}
	return nil, err
}

// 设置分类类型
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-category-setCategoryType
func (a *API) setCategoryType(shopId int, categoryId int64, categoryType string) error {
	params := map[string]interface{}{
		KeyShopID:      shopId,
		"categoryId":   categoryId,
		"categoryType": categoryType,
	}
	_, err := a.AccessAPI("eleme.product.category.setCategoryType", params)
	return err
}

// 获取一个分类下的所有商品
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-item-getItemsByCategoryId
func (a *API) GetItemsByCategoryId(categoryId int64) ([]map[string]interface{}, error) {
	result, err := a.AccessAPI("eleme.product.item.getItemsByCategoryId", utils.Params2Map("categoryId", categoryId))
	if err == nil {
		return utils.MapKV2List(result.Result.(map[string]interface{})), nil
	}
	return nil, err
}

// 查询商品详情
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-item-getItem
func (a *API) GetItem(itemId int64) (map[string]interface{}, error) {
	result, err := a.AccessAPI("eleme.product.item.getItem", utils.Params2Map("itemId", itemId))
	if err == nil {
		return result.Result.(map[string]interface{}), nil
	}
	return nil, err
}

// 批量查询商品详情
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-item-batchGetItems
func (a *API) BatchGetItems(itemIds []int64) ([]map[string]interface{}, error) {
	result, err := a.AccessAPI("eleme.product.item.batchGetItems", utils.Params2Map("itemIds", itemIds))
	if err == nil {
		return utils.MapKV2List(result.Result.(map[string]interface{})), nil
	}
	return nil, err
}

// 添加商品
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-item-createItem
func (a *API) CreateItem(categoryId int64, properties map[string]interface{}) (map[string]interface{}, error) {
	result, err := a.AccessAPI("eleme.product.item.createItem", utils.Params2Map("categoryId", categoryId, "properties", properties))
	if err == nil {
		return result.Result.(map[string]interface{}), nil
	}
	return nil, err
}

// 批量添加商品
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-item-batchCreateItems
func (a *API) BatchCreateItems(categoryId int64, items []map[string]interface{}) ([]map[string]interface{}, error) {
	result, err := a.AccessAPI("eleme.product.item.batchCreateItems", utils.Params2Map("categoryId", categoryId, "items", items))
	if err == nil {
		return utils.Slice2MapSlice(result.Result.([]interface{})), nil
	}
	return nil, err
}

// 更新商品
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-item-updateItem
func (a *API) UpdateItem(itemId, categoryId int64, properties map[string]interface{}) (map[string]interface{}, error) {
	result, err := a.AccessAPI("eleme.product.item.updateItem", utils.Params2Map("itemId", itemId, "categoryId", categoryId, "properties", properties))
	if err == nil {
		return result.Result.(map[string]interface{}), nil
	}
	return nil, err
}

// 批量置满库存
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-item-batchFillStock
func (a *API) BatchFillStock(specIds []*OItemIdWithSpecIds) error {
	_, err := a.AccessAPI("eleme.product.item.batchFillStock", utils.Params2Map("specIds", specIds))
	return err
}

// 批量沽清库存
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-item-batchClearStock
func (a *API) BatchClearStock(specIds []*OItemIdWithSpecIds) error {
	_, err := a.AccessAPI("eleme.product.item.batchClearStock", utils.Params2Map("specIds", specIds))
	return err
}

// 批量上架商品(新版)
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-item-batchListItems
func (a *API) BatchListItems(itemIds []int64) (retVal *OBatchModifiedResult, err error) {
	result, err := a.AccessAPI("eleme.product.item.batchListItems", utils.Params2Map("itemIds", itemIds))
	if err == nil {
		return interface2OBatchModifiedResult(result.Result), nil
	}
	return nil, err
}

// 批量下架商品(新版)
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-item-batchDelistItems
func (a *API) BatchDelistItems(itemIds []int64) (retVal *OBatchModifiedResult, err error) {
	result, err := a.AccessAPI("eleme.product.item.batchDelistItems", utils.Params2Map("itemIds", itemIds))
	if err == nil {
		return interface2OBatchModifiedResult(result.Result), nil
	}
	return nil, err
}

// 删除商品(新版)
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-item-invalidItem
func (a *API) InvalidItem(itemId int64) error {
	_, err := a.AccessAPI("eleme.product.item.invalidItem", utils.Params2Map("itemId", itemId))
	return err
}

// 批量删除商品
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-item-batchRemoveItems
func (a *API) BatchRemoveItems(itemIds []int64) (retVal []map[string]interface{}, err error) {
	result, err := a.AccessAPI("eleme.product.item.batchRemoveItems", utils.Params2Map("itemIds", itemIds))
	if err == nil {
		return utils.MapKV2List(result.Result.(map[string]interface{})), nil
	}
	return nil, err
}

// 批量更新商品库存(新版)
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-item-batchUpdateStock
func (a *API) BatchUpdateStock(itemIds []int64) (retVal *OBatchModifiedResult, err error) {
	result, err := a.AccessAPI("eleme.product.item.batchUpdateStock", utils.Params2Map("itemIds", itemIds))
	if err == nil {
		return interface2OBatchModifiedResult(result.Result), nil
	}
	return nil, err
}

// 设置商品排序
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-item-setItemPositions
func (a *API) SetItemPositions(categoryId int64, itemIds []int64) error {
	_, err := a.AccessAPI("eleme.product.item.setItemPositions", utils.Params2Map("categoryId", categoryId, "itemIds", itemIds))
	return err
}

// 根据商品扩展码获取商品
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-item-getItemByShopIdAndExtendCode
func (a *API) GetItemByShopIdAndExtendCode(shopId int, extendCode string) (retVal map[string]interface{}, err error) {
	result, err := a.AccessAPI("eleme.product.item.getItemByShopIdAndExtendCode", utils.Params2Map("shopId", shopId, "extendCode", extendCode))
	if err == nil {
		return result.Result.(map[string]interface{}), nil
	}
	return nil, err
}

// 批量修改商品价格
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-item-batchUpdatePrices
func (a *API) BatchUpdatePrices(shopId int, specPrices []*OItemIdWithSpecPrice) error {
	_, err := a.AccessAPI("eleme.product.item.batchUpdatePrices", utils.Params2Map("shopId", shopId, "specPrices", specPrices))
	return err
}

// 查询店铺活动商品(新版)
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-item-getShopSalesItems
func (a *API) GetShopSalesItems(shopId int) (retVal []int64, err error) {
	result, err := a.AccessAPI("eleme.product.item.getShopSalesItems", utils.Params2Map("shopId", shopId))
	if err == nil {
		ls := result.Result.([]interface{})
		retVal := make([]int64, len(ls))
		for index, v := range ls {
			retVal[index] = utils.MustInterface2Int64(v)
		}
		return retVal, nil
	}
	return nil, err
}

// 分页获取店铺下的商品
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-product-item-queryItemByPage
func (a *API) QueryItemByPage(shopId, offset, limit int) (retVal []map[string]interface{}, err error) {
	if offset < 0 {
		offset = 0
	}
	if limit > MaxPageSize {
		limit = MaxPageSize
	}
	result, err := a.AccessAPI("eleme.product.item.queryItemByPage", utils.Params2Map("queryPage", map[string]interface{}{
		"shopId": shopId,
		"offset": offset,
		"limit":  limit,
	}))
	if err == nil {
		return utils.Slice2MapSlice(result.Result.([]interface{})), nil
	}
	return nil, err
}

// 上传图片，返回图片的hash值
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-file-uploadImage
func (a *API) UploadImage(base64Content string) (hashCode string, err error) {
	result, err := a.AccessAPI("eleme.file.uploadImage", utils.Params2Map("image", base64Content))
	if err == nil {
		return result.Result.(string), nil
	}
	return "", err
}

// 通过远程URL上传图片，返回图片的hash值
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-file-uploadImageWithRemoteUrl
func (a *API) UploadImageWithRemoteUrl(imgURL string) (hashCode string, err error) {
	result, err := a.AccessAPI("eleme.file.uploadImageWithRemoteUrl", utils.Params2Map("url", imgURL))
	if err == nil {
		return result.Result.(string), nil
	}
	return "", err
}

// 获取上传图片的url地址(新版)
// https://open.shop.ele.me/openapi/apilist/eleme-product/eleme-file-getImageUrl
func (a *API) GetImageUrl(hashCode string) (imgURL string, err error) {
	result, err := a.AccessAPI("eleme.file.getImageUrl", utils.Params2Map("hash", hashCode))
	if err == nil {
		return result.Result.(string), nil
	}
	return "", err
}

///////////////////////////
// 私有辅助函数
func interface2Cat(data interface{}, level int) (cat *CategoryInfo) {
	mapData, ok := data.(map[string]interface{})
	if ok {
		cat = &CategoryInfo{
			Id:           utils.MustInterface2Int64(mapData["id"]),
			Name:         utils.Interface2String(mapData["name"]),
			Description:  utils.Interface2String(mapData["description"]),
			ParentId:     utils.MustInterface2Int64(mapData["parentId"]),
			CategoryType: utils.Interface2String(mapData["categoryType"]),
			Level:        level,
			IsLeaf:       false,
		}
		if utils.MustInterface2Int64(mapData["isValid"]) != 0 {
			cat.IsValid = true
		} else {
			cat.IsValid = false
		}
		cat.Children = interface2CatList(mapData["children"], level+1, interface2Cat)
		if len(cat.Children) == 0 {
			cat.IsLeaf = true
		}
	}
	return cat
}

func interface2CatList(data interface{}, level int, interface2CatHandler func(data interface{}, level int) (cat *CategoryInfo)) (cats []*CategoryInfo) {
	if interface2CatHandler == nil {
		interface2CatHandler = interface2Cat
	}
	maps, ok := data.([]interface{})
	if ok {
		cats = make([]*CategoryInfo, len(maps))
		for index, v := range maps {
			cats[index] = interface2CatHandler(v, level)
		}
	}
	return cats
}

func interface2OBatchModifiedResult(data interface{}) (retVal *OBatchModifiedResult) {
	mapData := data.(map[string]interface{})
	retVal = &OBatchModifiedResult{
		Type: utils.Interface2String(mapData["type"]),
	}
	if modifications, ok := mapData["modifications"].([]interface{}); ok {
		retVal.Modifications = make([]int64, len(modifications))
		for index, v := range modifications {
			retVal.Modifications[index] = utils.MustInterface2Int64(v)
		}
	}
	if failures, ok := mapData["failures"].([]interface{}); ok {
		retVal.Failures = make([]*OBatchModifiedFailure, len(failures))
		for index, v := range failures {
			mp := v.(map[string]interface{})
			retVal.Failures[index] = &OBatchModifiedFailure{
				Id:          utils.MustInterface2Int64(mp["id"]),
				Code:        utils.Interface2String(mp["code"]),
				Description: utils.Interface2String(mp["description"]),
			}
		}
	}
	return retVal
}
