package jd

import (
	"fmt"
	"git.rosy.net.cn/baseapi/platformapi/jdapi"
	"git.rosy.net.cn/baseapi/utils"
	"git.rosy.net.cn/jx-callback/business/jxutils"
	"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
	"git.rosy.net.cn/jx-callback/business/jxutils/tasksch"
	"git.rosy.net.cn/jx-callback/business/model"
	"git.rosy.net.cn/jx-callback/business/model/dao"
	"git.rosy.net.cn/jx-callback/business/partner"
	"git.rosy.net.cn/jx-callback/globals"
	"git.rosy.net.cn/jx-callback/globals/api/apimanager"
	beego "github.com/astaxie/beego/server/web"
	"strings"
	//beego "github.com/astaxie/beego/server/web"
)

const (
	DefBrandID = 35247

	DefJdCategoryID      = 20362
	DefJdCategoryID4Jxgy = 22410 // 其他国产水果
)

//func getDefJdCategoryID() int {
//	if beego.BConfig.RunMode == model.ServerTypeFruits {
//		return DefJdCategoryID4Jxgy
//	}
//	return DefJdCategoryID
//}

func jdCat2Jx(jdCat *jdapi.CategoryInfo) (jxCat *partner.BareCategoryInfo) {
	return &partner.BareCategoryInfo{
		VendorCatID: utils.Int64ToStr(jdCat.Id),
		Level:       jdCat.Level,
		Name:        jdCat.Name,
		Seq:         jdCat.Sort,
	}
}

func (p *PurchaseHandler) GetAllCategories(ctx *jxcontext.Context, vendorOrgCode string) (cats []*partner.BareCategoryInfo, err error) {
	result, err := getAPI(vendorOrgCode).QueryCategoriesByOrgCode()
	if err == nil {
		catMap := make(map[int64]*partner.BareCategoryInfo)
		level := 1
		for {
			processedCount := 0
			for _, jdCat := range result {
				if jdCat.Level == level {
					processedCount++
					jxCat := jdCat2Jx(jdCat)
					if level == 1 {
						cats = append(cats, jxCat)
					} else {
						parentCat := catMap[jdCat.ParentId]
						if parentCat != nil {
							parentCat.Children = append(parentCat.Children, jxCat)
						}
					}
					catMap[jdCat.Id] = jxCat
				}
			}
			if processedCount == 0 {
				break
			}
			level++
		}
	}
	return cats, err
}

func (p *PurchaseHandler) CreateCategory2(ctx *jxcontext.Context, cat *dao.SkuStoreCatInfo) (err error) {
	parentID := int64(0)
	if cat.Level != 1 {
		parentID = utils.Str2Int64(cat.ParentVendorCatID)
	}
	if globals.EnableJdStoreWrite {
		result, err2 := getAPI(cat.VendorOrgCode).AddShopCategory(parentID, cat.Name, int(cat.Level), cat.Seq, ctx.GetUserName())
		if err = err2; err == nil {
			if jdID := utils.Str2Int64WithDefault(result, 0); jdID != 0 {
				cat.VendorCatID = utils.Int64ToStr(jdID)
			}
		}
	} else {
		cat.VendorCatID = utils.Int64ToStr(jxutils.GenFakeID())
	}
	return err
}

func (p *PurchaseHandler) UpdateCategory2(ctx *jxcontext.Context, cat *dao.SkuStoreCatInfo) (err error) {
	if globals.EnableJdStoreWrite {
		if cat.VendorCatID != "" {
			err = getAPI(cat.VendorOrgCode).UpdateShopCategory(utils.Str2Int64(cat.VendorCatID), cat.Name)
		}
	}
	return err
}

func (p *PurchaseHandler) DeleteCategory2(ctx *jxcontext.Context, vendorOrgCode, vendorCatID string) (err error) {
	if globals.EnableJdStoreWrite {
		err = getAPI(vendorOrgCode).DelShopCategory(utils.Str2Int64(vendorCatID))
	}
	return err
}

func (p *PurchaseHandler) ReorderCategories2(ctx *jxcontext.Context, vendorOrgCode, vendorParentCatID string, vendorCatIDList []string) (err error) {
	if globals.EnableJdStoreWrite {
		err = getAPI(vendorOrgCode).ChangeShopCategoryOrder(utils.Str2Int64WithDefault(vendorParentCatID, 0), utils.StringSlice2Int64(vendorCatIDList))
	}
	return err
}

func (p *PurchaseHandler) getVendorCategories(level int, pid int64) (vendorCats []*model.SkuVendorCategory, err error) {
	// 得到平台的分类，不需要指定分账号
	vendorOrgCode := ""
	if beego.BConfig.RunMode == model.ServerTypeFruits {
		vendorOrgCode = jdapi.JdVendorOrgCodeFruit
	} else if beego.BConfig.RunMode == model.ServerTypePet {
		vendorOrgCode = jdapi.JdVendorOrgCodePet
	} else {
		vendorOrgCode = jdapi.JdVendorOrgCodeVagetable
	}
	jdsApi := apimanager.CurAPIManager.GetAPI(model.VendorIDJD, vendorOrgCode).(*jdapi.API)
	cats, err := jdsApi.QueryChildCategoriesForOP(pid)
	if err != nil {
		return nil, err
	}
	for _, v := range cats {
		if v.Status == 1 {
			cat := &model.SkuVendorCategory{
				VendorID:         model.VendorIDJD,
				Name:             v.Name,
				Level:            level,
				VendorCategoryID: utils.Int64ToStr(v.Id),
			}
			if level > 1 {
				cat.ParentID = utils.Int64ToStr(v.ParentId)
				if level == 3 || level == 4 {
					cat.IsLeaf = 1
				}
			}
			vendorCats = append(vendorCats, cat)
			if level < 4 {
				childVendorCats, err2 := p.getVendorCategories(level+1, v.Id)
				if err2 == nil && len(childVendorCats) > 0 {
					vendorCats = append(vendorCats, childVendorCats...)
				} else {
					cat.IsLeaf = 1
				}
			}
		}
	}
	return vendorCats, nil
}

func (p *PurchaseHandler) GetVendorCategories(ctx *jxcontext.Context) (vendorCats []*model.SkuVendorCategory, err error) {
	vendorCats, err = p.getVendorCategories(1, 0)
	return vendorCats, err
}

func skuInfo2Param(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (param *jdapi.OpSkuParam) {
	param = &jdapi.OpSkuParam{
		TraceID:        ctx.GetTrackInfo(),
		OutSkuID:       utils.Int2Str(sku.SkuID),
		ShopCategories: []int64{},
		BrandID:        DefBrandID,
		SkuName:        utils.LimitUTF8StringLen(sku.SkuName, jdapi.MaxSkuNameCharCount),
		SkuPrice:       int(sku.Price),
		Weight:         float64(jxutils.IntWeight2Float(sku.Weight)),
		FixedStatus:    jxStatus2jdStatus(sku.MergedStatus),
		IsSale:         jdapi.IsSaleNo, // todo ?

		Upc: sku.Upc,
		// Images: jxutils.BatchString2Slice(sku.Img, sku.Img2),
	}
	if sku.VendorCatID != "" {
		param.ShopCategories = append(param.ShopCategories, utils.Str2Int64(sku.VendorCatID))
	}
	if sku.ImgMix != "" {
		param.Images = jxutils.BatchString2Slice(sku.ImgMix, sku.Img2, sku.Img3, sku.Img4, sku.Img5)
	} else {
		param.Images = jxutils.BatchString2Slice(sku.Img, sku.Img2, sku.Img3, sku.Img4, sku.Img5)
	}

	if sku.SkuVendorMapCatID != "" && sku.SkuVendorMapCatID != "0" {
		param.CategoryID = utils.Str2Int64(sku.SkuVendorMapCatID)
	} else if sku.VendorVendorCatID != 0 {
		param.CategoryID = sku.VendorVendorCatID
	}
	// 京东强制要求upc的商品，如果没有设置upc，自动生成一个假的
	if param.Upc == "" && isSkuMustHaveUpc(sku.Unit, param.CategoryID) {
		param.Upc = jxutils.GenFakeUPC(sku.SkuID)
	}
	if sku.IsGlobal == 0 && len(sku.SellCities) > 0 {
		param.SellCities = utils.StringSlice2Int64(sku.SellCities)
	}
	if sku.DescImg != "" {
		param.ProductDesc = fmt.Sprintf(`<img src="%s"  alt="一张图片" />`, sku.DescImg)
	}

	return param
}

func (p *PurchaseHandler) CreateSku2(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (err error) {
	jdApi := getAPI(sku.VendorOrgCode)
	param := skuInfo2Param(ctx, sku)
	if globals.EnableJdStoreWrite {
		sku.VendorSkuID, err = jdApi.AddSku2(param)
		if err != nil && strings.Contains(err.Error(), jdapi.ErrMustUPC) {
			result, err2 := jdApi.BatchAddSkuByUPC([]*jdapi.CreateByUpcParam2{
				&jdapi.CreateByUpcParam2{
					OutSkuId:       utils.Int2Str(sku.SkuID),
					Upc:            sku.Upc,
					JdPrice:        utils.Int64ToStr(sku.Price),
					ShopCategoryID: utils.Str2Int64WithDefault(sku.VendorCatID, 0),
				},
			})
			if err2 == nil {
				sku.VendorSkuID = result.SkuID
			} else {
				err = err2
			}
		} else if err != nil && strings.Contains(err.Error(), "类目ID不存在") {
			recommendCategory, _ := jdApi.GetSkuCategoryBySkuName(param.SkuName)
			if recommendCategory != nil && recommendCategory.CategoryId != model.NO {
				param.CategoryID = int64(recommendCategory.CategoryId)
				sku.VendorSkuID, _ = jdApi.AddSku2(param)
				if sku.VendorSkuID != "" {
					skuVendorCategory := &model.SkuVendorCategoryMap{
						NameID:   sku.NameID,
						VendorID: model.VendorIDJD,
					}
					skuVendorCategory.VendorCategoryID = utils.Int2Str(recommendCategory.CategoryId)
					if err2 := dao.GetEntity(dao.GetDB(), skuVendorCategory, "NameID", "VendorID"); err2 != nil {
						dao.WrapAddIDCULDEntity(skuVendorCategory, ctx.GetUserName())
						dao.CreateEntity(dao.GetDB(), skuVendorCategory)
					} else {
						dao.UpdateEntity(dao.GetDB(), skuVendorCategory, "VendorCategoryID")
					}
					err = nil
				}
				//dao.ExecuteSQL(dao.GetDB(), ` UPDATE sku_category SET jd_category_id = ? WHERE id =  ? `, []interface{}{recommendCategory.CategoryId, sku.LocalCategoryId}...)
				//dao.ExecuteSQL(dao.GetDB(), ` UPDATE sku_name SET jd_category_id = ? WHERE id =  ? `, []interface{}{recommendCategory.CategoryId, sku.NameID})
			}
		} else if err != nil && strings.Contains(err.Error(), "商家skuId已存在") {
			vendorSkuId := strings.Split(strings.Split(err.Error(), ":")[2], " ")[0]
			sku.VendorSkuID = vendorSkuId
			err = nil
		}

	} else {
		sku.VendorSkuID = utils.Int64ToStr(jxutils.GenFakeID())
	}
	return err
}

func (p *PurchaseHandler) UpdateSku2(ctx *jxcontext.Context, sku *dao.StoreSkuSyncInfo) (err error) {
	param := skuInfo2Param(ctx, sku)
	if globals.EnableJdStoreWrite {
		_, err = getAPI(sku.VendorOrgCode).UpdateSku2(param)
	}
	return err
}

func (p *PurchaseHandler) DeleteSku2(ctx *jxcontext.Context, vendorOrgCode string, sku *partner.StoreSkuInfo) (err error) {
	// 京东到家只能通过商家ID删除SKU，如果没有的话，先绑定，再删除
	if sku.SkuID == 0 {
		skuPairList := []*jdapi.SkuIDPair{
			&jdapi.SkuIDPair{
				SkuId:    utils.Str2Int64(sku.VendorSkuID),
				OutSkuId: sku.VendorSkuID,
			},
		}
		if globals.EnableJdStoreWrite {
			_, err = getAPI(vendorOrgCode).BatchUpdateOutSkuId(skuPairList)
			if err != nil {
				return err
			}
			sku.SkuID = int(utils.Str2Int64(sku.VendorSkuID))
		}
	}
	param := &jdapi.OpSkuParam{
		TraceID:     ctx.GetTrackInfo(),
		OutSkuID:    utils.Int2Str(sku.SkuID),
		FixedStatus: jdapi.SkuFixedStatusDeleted,
	}
	if globals.EnableJdStoreWrite {
		_, err = getAPI(vendorOrgCode).UpdateSku2(param)
	}
	return err
}

func (p *PurchaseHandler) GetSkus(ctx *jxcontext.Context, vendorOrgCode string, skuID int, vendorSkuID string) (skuNameList []*partner.SkuNameInfo, err error) {
	param := &jdapi.QuerySkuParam{
		SkuID:       utils.Str2Int64WithDefault(vendorSkuID, 0),
		IsFilterDel: jdapi.IsFilterDelTrue,
		PageNo:      1,
		PageSize:    jdapi.MaxSkuIDsCount4QueryListBySkuIds, // 为了同时取图，这个值不要大于jdapi.MaxSkuIDsCount4QueryListBySkuIds
	}
	for {
		skuList, _, err2 := getAPI(vendorOrgCode).QuerySkuInfos(param)
		if err = err2; err != nil {
			return nil, err
		}
		if len(skuList) > 0 {
			batchSkuNameList := make([]*partner.SkuNameInfo, len(skuList))
			for k, v := range skuList {
				batchSkuNameList[k] = vendorSku2Jx(v)
			}
			setSkuNameListPic(vendorOrgCode, batchSkuNameList)
			skuNameList = append(skuNameList, batchSkuNameList...)
		}
		if len(skuList) < param.PageSize {
			break
		}
		param.PageNo++
	}
	return skuNameList, err
}

func (p *PurchaseHandler) GetSkuCategoryIdByName(vendorOrgCode, skuName string) (vendorCategoryId string, err error) {
	vendorCategory, err := getAPI(vendorOrgCode).GetSkuCategoryBySkuName(skuName)
	if err != nil {
		return "", err
	}

	if vendorCategory == nil {
		return "", nil
	}

	return utils.Int2Str(vendorCategory.CategoryId), nil
}

func setSkuNameListPic(vendorOrgCode string, skuNameList []*partner.SkuNameInfo) []*partner.SkuNameInfo {
	jdSkuIDs := make([]int64, len(skuNameList))
	for k, v := range skuNameList {
		jdSkuIDs[k] = utils.Str2Int64(v.SkuList[0].VendorSkuID)
	}

	imgMap := make(map[int64]*jdapi.ImgHandleQueryResult)
	if imgList, err2 := getAPI(vendorOrgCode).QueryListBySkuIds(&jdapi.QueryListBySkuIdsParam{
		SkuIDs: jdSkuIDs,
	}); err2 == nil {
		for _, v := range imgList {
			if v.ImgType == jdapi.ImgTypeMain {
				imgResult := imgMap[v.SkuID]
				if imgResult == nil || imgResult.IsMain < v.IsMain {
					imgMap[v.SkuID] = v
				}
			}
		}
	}

	// 使用扒页面方式获取商品图片
	if false {
		var leftJdSkuIDs []int64
		for _, v := range jdSkuIDs {
			if imgMap[v] == nil {
				leftJdSkuIDs = append(leftJdSkuIDs, v)
			}
		}
		task := tasksch.NewParallelTask("jd setSkuNameListPic", nil, jxcontext.AdminCtx,
			func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
				jdSkuID := batchItemList[0].(int64)
				imgList, err := getAPI(vendorOrgCode).GetSkuPageImageInfo(jdSkuID)
				if err == nil && len(imgList) > 0 {
					retVal = [][]string{
						[]string{utils.Int64ToStr(jdSkuID), imgList[0].Big},
					}
				}
				return retVal, err
			}, leftJdSkuIDs)
		task.Run()
		if resultList, err := task.GetResult(0); err == nil {
			for _, v := range resultList {
				strList := v.([]string)
				imgMap[utils.Str2Int64(strList[0])] = &jdapi.ImgHandleQueryResult{
					SourceImgURL: strList[1],
				}
			}
		}
	}

	// 设置商品图片
	for _, v := range skuNameList {
		if imgResult := imgMap[utils.Str2Int64(v.SkuList[0].VendorSkuID)]; imgResult != nil {
			v.PictureList = []string{imgResult.SourceImgURL}
		}
	}
	return skuNameList
}

func vendorSku2Jx(vendorSku *jdapi.SkuMain) (skuName *partner.SkuNameInfo) {
	prefix, name, comment, specUnit, unit, specQuality := jxutils.SplitSkuName(vendorSku.SkuName)
	weight := int(vendorSku.Weight * 1000)
	if weight <= 0 {
		weight = jxutils.FormatSkuWeight(specQuality, specUnit)
	}
	skuID := int(utils.Str2Int64WithDefault(vendorSku.OutSkuID, 0))
	vendorSkuID := utils.Int64ToStr(vendorSku.SkuID)
	skuName = &partner.SkuNameInfo{
		NameID:          skuID,
		VendorNameID:    vendorSkuID,
		VendorCatIDList: []string{utils.Int64ToStr(vendorSku.CategoryID)},

		Prefix: prefix,
		Name:   name,
		Unit:   unit,
		SkuList: []*partner.SkuInfo{
			&partner.SkuInfo{
				StoreSkuInfo: partner.StoreSkuInfo{
					VendorSkuID: vendorSkuID,
					SkuID:       skuID,

					VendorPrice: int64(vendorSku.SkuPrice),
					Status:      jdStatus2jxStatus(vendorSku.FixedStatus),
				},
				SkuName:     vendorSku.SkuName,
				Comment:     comment,
				SpecQuality: float64(specQuality),
				SpecUnit:    specUnit,
				Weight:      weight,
			},
		},
	}
	return skuName
}

func jdStatus2jxStatus(jdStatus int) (jxStatus int) {
	switch jdStatus {
	case jdapi.SkuFixedStatusOnline:
		jxStatus = model.SkuStatusNormal
	case jdapi.SkuFixedStatusOffline:
		jxStatus = model.SkuStatusDontSale
	case jdapi.SkuFixedStatusDeleted:
		jxStatus = model.SkuStatusDeleted
	}
	return jxStatus
}

func jxStatus2jdStatus(jxStatus int) (jdStatus int) {
	switch jxStatus {
	case model.SkuStatusNormal:
		jdStatus = jdapi.SkuFixedStatusOnline
	case model.SkuStatusDontSale:
		jdStatus = jdapi.SkuFixedStatusOffline
	case model.SkuStatusDeleted:
		jdStatus = jdapi.SkuFixedStatusDeleted
	}
	return jdStatus
}

func isSkuMustHaveUpc(unit string, vendorVendorCatID int64) bool {
	return unit != model.SpecialUnit || !upcLessMap[vendorVendorCatID]
}

var (
	upcLessMap = map[int64]bool{
		20250: true,
		20252: true,
		20258: true,
		20259: true,
		20261: true,
		20262: true,
		20263: true,
		20264: true,
		20265: true,
		20266: true,
		20267: true,
		22822: true,
		20269: true,
		20270: true,
		20271: true,
		20272: true,
		20273: true,
		20275: true,
		20276: true,
		20277: true,
		20278: true,
		20279: true,
		20281: true,
		20282: true,
		20283: true,
		20285: true,
		20286: true,
		20287: true,
		22821: true,
		20289: true,
		20290: true,
		23018: true,
		20354: true,
		20355: true,
		20357: true,
		20359: true,
		23019: true,
		20294: true,
		20295: true,
		20296: true,
		20297: true,
		20298: true,
		20299: true,
		20300: true,
		20302: true,
		20303: true,
		20304: true,
		22840: true,
		22841: true,
		20317: true,
		20320: true,
		20321: true,
		20323: true,
		20325: true,
		20326: true,
		20328: true,
		20329: true,
		20331: true,
		20335: true,
		20337: true,
		20338: true,
		20339: true,
		22842: true,
		22843: true,
		23020: true,
		20309: true,
		20310: true,
		20311: true,
		20312: true,
		20313: true,
		20314: true,
		20315: true,
		22410: true,
		23050: true,
		20319: true,
		20322: true,
		20330: true,
		20332: true,
		20334: true,
		20336: true,
		20340: true,
		20342: true,
		23049: true,
		20356: true,
		20358: true,
		20360: true,
		20361: true,
		20362: true,
		20364: true,
	}
)
