package cms

import (
	"fmt"
	"git.rosy.net.cn/jx-callback/business/partner/purchase/tiktok_store"
	"strings"
	"time"

	"git.rosy.net.cn/baseapi/utils"
	"git.rosy.net.cn/baseapi/utils/errlist"
	"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/business/partner/putils"
	"git.rosy.net.cn/jx-callback/globals"
)

type MultiStoreVendorInfo struct {
	VendorID int
	OrgCode  string
}

func CombineVendorIDAndOrgCode(vendorID int, orgCode string) string {
	return fmt.Sprintf("%d-%s", vendorID, orgCode)
}

func getMultiStoreVendorInfoList() (list []*MultiStoreVendorInfo) {
	vendorIDs := partner.GetMultiStoreVendorIDs()
	for _, vendorID := range vendorIDs {
		orgCodeList := partner.CurAPIManager.GetAppOrgCodeList(vendorID)
		for _, v := range orgCodeList {
			list = append(list, &MultiStoreVendorInfo{
				VendorID: vendorID,
				OrgCode:  v,
			})
		}
	}
	return list
}

func syncCategories(ctx *jxcontext.Context, db *dao.DaoDB, parentTask tasksch.ITask, catList []*dao.SkuStoreCatInfo, isAsync bool) (hint string, err error) {
	if len(catList) > 0 {
		// todo 按vendorID orgCode合并操作
		task := tasksch.NewParallelTask(fmt.Sprintf("同步分类2:%d", len(catList)), tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx,
			func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
				catVendorInfo := batchItemList[0].(*dao.SkuStoreCatInfo)
				if catVendorInfo.Level != 1 && catVendorInfo.ParentVendorCatID == "" {
					return nil, fmt.Errorf("%d的父目录%d没有同步", catVendorInfo.ID, catVendorInfo.ParentID)
				}
				if catVendorInfo.MapID == 0 {
					return nil, fmt.Errorf("分类:%d的数据异常", catVendorInfo.ID)
				}
				//表示是不用京西分类，要用平台分类
				if catVendorInfo.IsJxCat == model.YES {
					if catVendorInfo.VendorCategoryID != 0 {
						catVendorInfo.Seq = catVendorInfo.VendorCategorySeq
						catVendorInfo.Name = catVendorInfo.VendorCategoryName
					}
				}
				if multiStoresHandler, ok := partner.GetPurchasePlatformFromVendorID(catVendorInfo.VendorID).(partner.IMultipleStoresHandler); ok {
					if model.IsSyncStatusDelete(catVendorInfo.CatSyncStatus) { //删除
						if !dao.IsVendorThingIDEmpty(catVendorInfo.VendorCatID) &&
							model.IsSyncStatusNeedDelete(catVendorInfo.CatSyncStatus) {
							err = multiStoresHandler.DeleteCategory2(ctx, catVendorInfo.VendorOrgCode, catVendorInfo.VendorCatID)
						}
					} else if model.IsSyncStatusNew(catVendorInfo.CatSyncStatus) { // 新增
						err = multiStoresHandler.CreateCategory2(ctx, catVendorInfo)
					} else if model.IsSyncStatusUpdate(catVendorInfo.CatSyncStatus) { // 修改
						err = multiStoresHandler.UpdateCategory2(ctx, catVendorInfo)
					}
				} else {
					if catVendorInfo.VendorID != model.VendorIDDD {
						err = fmt.Errorf("平台:%d不合法", catVendorInfo.VendorID)
					}
				}
				if err = OnThingSync(ctx, dao.GetDB(), SkuCategoryVendor2ThingMap(catVendorInfo), err); err == nil {
					retVal = []int{1}
				}
				return retVal, err
			}, catList)
		tasksch.HandleTask(task, parentTask, len(catList) == 0 || len(catList) > 10).Run()
		if isAsync {
			hint = task.GetID()
		} else {
			resultList, err2 := task.GetResult(0)
			if err = err2; err == nil {
				hint = utils.Int2Str(len(resultList))
			}
		}
	}
	return hint, err
}

func SyncCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorIDs []int, appOrgCodes []string, catIDs []int, isAsync bool) (hint string, err error) {
	db := dao.GetDB()
	catList, err := dao.GetSkuCategoryWithVendor(db, vendorIDs, appOrgCodes, -1, catIDs, true)
	if err == nil && len(catList) > 0 {
		//TODO 同一平台不同账号会有影响needSyncParentIDs，暂不处理
		var needSyncParentIDs []int
		for _, cat := range catList {
			if cat.Level == 2 && cat.ParentVendorCatID == "" && cat.IsExdSpec == model.NO {
				needSyncParentIDs = append(needSyncParentIDs, cat.ParentID)
			}
		}
		if len(needSyncParentIDs) > 0 {
			task := tasksch.NewSeqTask(fmt.Sprintf("同步分类1:%v", catIDs), ctx,
				func(task *tasksch.SeqTask, step int, params ...interface{}) (result interface{}, err error) {
					switch step {
					case 0:
						catList2, err := dao.GetSkuCategoryWithVendor(db, vendorIDs, appOrgCodes, -1, needSyncParentIDs, true)
						if err == nil {
							_, err = syncCategories(ctx, db, task, catList2, false)
						}
					case 1:
						catList2, err := dao.GetSkuCategoryWithVendor(db, vendorIDs, appOrgCodes, -1, catIDs, true)
						if err == nil {
							_, err = syncCategories(ctx, db, task, catList2, false)
						}
					}
					return result, err
				}, 2)
			tasksch.HandleTask(task, parentTask, len(catIDs) == 0 || len(catIDs) > 10).Run()
			if isAsync {
				hint = task.GetID()
			} else {
				resultList, err2 := task.GetResult(0)
				if err = err2; err == nil {
					hint = utils.Int2Str(len(resultList))
				}
			}
		} else {
			hint, err = syncCategories(ctx, db, parentTask, catList, false)
		}
	}
	return hint, err
}

func SyncSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, vendorIDs []int, appOrgCodes []string, nameIDs, skuIDs []int, isAsync bool) (hint string, err error) {
	db := dao.GetDB()
	skuList, err := dao.GetSkusWithVendor(db, vendorIDs, appOrgCodes, nameIDs, skuIDs, true)

	cc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
		skuVendorInfo := batchItemList[0].(*dao.StoreSkuSyncInfo)
		var failedList []*partner.StoreSkuInfoWithErr
		// if skuVendorInfo.VendorCatID == "" {
		// 	return nil, fmt.Errorf("商品:%d的商家分类没有同步", skuVendorInfo.SkuID)
		// }
		if skuVendorInfo.BindID == 0 {
			return nil, fmt.Errorf("商品:%d的数据异常", skuVendorInfo.SkuID)
		}
		if skuVendorInfo.ExdSkuID != "" {
			return nil, err
		}
		//todo 暂时注释
		if !model.IsSyncStatusNew(skuVendorInfo.SkuSyncStatus) && skuVendorInfo.VendorSkuID == "" {
			return nil, err
		}
		if skuVendorInfo.SkuVendorMapCatID != "" {
			skuVendorInfo.VendorVendorCatID = utils.Str2Int64(skuVendorInfo.SkuVendorMapCatID)
		}
		skuVendorInfo.SkuName = jxutils.ComposeSkuNameSync(skuVendorInfo.Prefix, skuVendorInfo.Name, skuVendorInfo.Comment, skuVendorInfo.Unit, skuVendorInfo.SpecQuality, skuVendorInfo.SpecUnit, 0, skuVendorInfo.ExPrefix, skuVendorInfo.ExPrefixBegin, skuVendorInfo.ExPrefixEnd, true)
		skuVendorInfo.SkuNameOrigin = jxutils.ComposeSkuNameOriginal(skuVendorInfo.Prefix, skuVendorInfo.Name, skuVendorInfo.Comment, skuVendorInfo.Unit, skuVendorInfo.SpecQuality, skuVendorInfo.SpecUnit, 0)
		if skuVendorInfo.ImgWatermark != "" {
			downLoad, _ := uploadImgStandard(skuVendorInfo.ImgWatermark)
			skuVendorInfo.ImgMix = jxutils.MixWatermarkImg(downLoad, skuVendorInfo.Img, skuVendorInfo.ExPrefixBegin, skuVendorInfo.ExPrefixEnd)
		}
		skuVendorInfo.MergedStatus = jxutils.MergeSkuStatus(skuVendorInfo.Status, skuVendorInfo.NameStatus)
		if multiStoresHandler, ok := partner.GetPurchasePlatformFromVendorID(skuVendorInfo.VendorID).(partner.IMultipleStoresHandler); ok {
			if model.IsSyncStatusDelete(skuVendorInfo.SkuSyncStatus) { //删除
				if !dao.IsVendorThingIDEmpty(skuVendorInfo.VendorSkuID) &&
					model.IsSyncStatusNeedDelete(skuVendorInfo.SkuSyncStatus) {
					err = multiStoresHandler.DeleteSku2(ctx, skuVendorInfo.VendorOrgCode, storeSkuSyncInfo2Bare(skuVendorInfo))
					if err != nil {
						failedList = putils.GetErrMsg2FailedSingleList(skuVendorInfo, err, 0, model.VendorChineseNames[skuVendorInfo.VendorID], "删除商品")
					}
				}
			} else if model.IsSyncStatusNew(skuVendorInfo.SkuSyncStatus) { // 新增
				err = multiStoresHandler.CreateSku2(ctx, skuVendorInfo)
				if err != nil {
					failedList = putils.GetErrMsg2FailedSingleList(skuVendorInfo, err, 0, model.VendorChineseNames[skuVendorInfo.VendorID], "新增商品")
				}
			} else if model.IsSyncStatusUpdate(skuVendorInfo.SkuSyncStatus) { // 修改
				err = multiStoresHandler.UpdateSku2(ctx, skuVendorInfo)
				if err != nil {
					failedList = putils.GetErrMsg2FailedSingleList(skuVendorInfo, err, 0, model.VendorChineseNames[skuVendorInfo.VendorID], "修改商品")
				}
			}
		} else {
			if skuVendorInfo.VendorID != model.VendorIDDD {
				err = fmt.Errorf("平台:%d不合法", skuVendorInfo.VendorID)
			}
		}
		if len(failedList) > 0 {
			task.AddFailedList(failedList)
		} else {
			dao.SetStoreSkuSyncStatus(dao.GetDB(), model.VendorIDJD, []int{skuVendorInfo.StoreID}, []int{skuVendorInfo.SkuID}, model.ThingTypeSyncSuccess)
		}
		if err = OnThingSync(ctx, dao.GetDB(), SkuVendor2ThingMap(skuVendorInfo), err); err == nil {
			retVal = []int{1}
		}
		return retVal, err
	}

	if err == nil && len(skuList) > 0 {
		task := tasksch.NewParallelTask(
			fmt.Sprintf("同步商品:%v,%v", nameIDs, skuIDs),
			tasksch.NewParallelConfig().SetIsContinueWhenError(true), ctx, cc, skuList)
		if isAsync {
			buildSetFinishHook(task, ctx)
		}
		tasksch.HandleTask(task, parentTask, len(skuList) == 0 || len(skuList) > 10).Run()
		if isAsync {
			hint = task.GetID()
		} else {
			resultList, err2 := task.GetResult(0)
			if len(task.GetFailedList()) > 0 {
				err2 = buildErrMsg(task)
				err2 = makeSyncError(err2)
			}
			if err = err2; err == nil {
				hint = utils.Int2Str(len(resultList))
			}
		}
	}
	return hint, err
}

func SyncReorderCategories(ctx *jxcontext.Context, parentCatID int, isAsync bool) (hint string, err error) {
	db := dao.GetDB()
	hint, err = CurVendorSync.LoopMultiStoresVendors(ctx, db, fmt.Sprintf("分类重排序:%d", parentCatID), isAsync, false,
		func(t *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
			vendorInfo := batchItemList[0].(*MultiStoreVendorInfo)
			multiStoresHandler := CurVendorSync.GetMultiStoreHandler(vendorInfo.VendorID)
			vendorOrgCode, err := dao.GetVendorOrgCode(db, vendorInfo.VendorID, vendorInfo.OrgCode, "")
			if multiStoresHandler != nil {
				var vendorCatIDList []string
				var parentVendorCatID string
				//如果用平台分类就走else，用京西分类就还是原来的if
				if vendorOrgCode[0].IsJxCat == model.NO {
					catList, err2 := dao.GetSkuCategoryWithVendor(db, []int{vendorInfo.VendorID}, []string{vendorInfo.OrgCode}, parentCatID, nil, false)
					if err = err2; err == nil {
						for _, v := range catList {
							if v.VendorCatID != "" {
								vendorCatIDList = append(vendorCatIDList, v.VendorCatID)
							}
						}
					}
					parentVendorCatID = catList[0].ParentVendorCatID
				} else {
					vendorCatList, _ := dao.GetVendorCategoryMapExt(db, parentCatID, 0, vendorInfo.VendorID, vendorInfo.OrgCode, 0)
					for _, v := range vendorCatList {
						if v.VendorThingID != "" {
							vendorCatIDList = append(vendorCatIDList, v.VendorThingID)
						}
					}
					thingMaps, _ := dao.GetThingMapList(db, model.ThingTypeCategory, []int{vendorInfo.VendorID}, []int{parentCatID}, []string{vendorInfo.OrgCode})
					parentVendorCatID = thingMaps[0].VendorThingID
				}
				if len(vendorCatIDList) > 0 {
					if err = multiStoresHandler.ReorderCategories2(ctx, vendorInfo.OrgCode, parentVendorCatID, vendorCatIDList); err == nil {
						retVal = []int{len(vendorCatIDList)}
					}
				}
			} else {
				err = fmt.Errorf("非法平台:%d", vendorInfo.VendorID)
			}
			return retVal, err
		})
	return hint, err
}

func SyncReorderCategories2(ctx *jxcontext.Context, parentCatID, vendorID int, vendorOrgCode string) (err error) {
	db := dao.GetDB()
	multiStoresHandler := CurVendorSync.GetMultiStoreHandler(vendorID)
	if multiStoresHandler != nil {
		var vendorCatIDList []string
		var parentVendorCatID string
		vendorCatList, _ := dao.GetVendorCategoryMapExt(db, parentCatID, 0, vendorID, vendorOrgCode, 0)
		for _, v := range vendorCatList {
			if v.VendorThingID != "" {
				vendorCatIDList = append(vendorCatIDList, v.VendorThingID)
			}
		}
		thingMaps, _ := dao.GetThingMapList(db, model.ThingTypeCategory, []int{vendorID}, []int{parentCatID}, []string{vendorOrgCode})
		if len(thingMaps) > 0 {
			parentVendorCatID = thingMaps[0].VendorThingID
		}

		if len(vendorCatIDList) > 0 {
			err = multiStoresHandler.ReorderCategories2(ctx, vendorOrgCode, parentVendorCatID, vendorCatIDList)
		}
	} else {
		err = fmt.Errorf("非法平台:%d", vendorID)
	}
	return err
}

func getThingMap(db *dao.DaoDB, thingMap *model.ThingMap) (err error) {
	return dao.GetEntity(db, thingMap, "ThingID", "ThingType", "VendorID", "VendorOrgCode", model.FieldDeletedAt)
}

func OnCreateThing(ctx *jxcontext.Context, db *dao.DaoDB, vendorInfoList []*model.VendorOrgCode, thingID int64, thingType, syncFlag int8, vendorFlag bool) (err error) {
	if thingType == model.ThingTypeSkuName {
		return nil
	}
	if len(vendorInfoList) == 0 {
		vendorInfoList, err = dao.GetVendorOrgCode(db, model.VendorIDJD, "", model.VendorOrgTypePlatform)
	}
	errList := errlist.New()
	for _, v := range vendorInfoList {
		thingMap := &model.ThingMap{
			ThingID:       thingID,
			ThingType:     thingType,
			VendorID:      v.VendorID,
			VendorOrgCode: v.VendorOrgCode,
		}
		if thingType == model.ThingTypeCategory && !vendorFlag {
			if v.IsJxCat == model.YES {
				syncFlag = 0
			}
		}
		thingMap.SyncStatus = syncFlag
		dao.WrapAddIDCULDEntity(thingMap, ctx.GetUserName())
		if err2 := dao.CreateEntity(db, thingMap); err2 != nil {
			if dao.IsDuplicateError(err2) {
				errList.AddErr(onUpdateThing(ctx, db, vendorInfoList, thingID, thingType, syncFlag))
			} else {
				errList.AddErr(err2)
			}
		}
		updateThingMapEntity(db, thingMap)
	}
	err = errList.GetErrListAsOne()
	return err
}

func OnCreateThing2Tiktok(ctx *jxcontext.Context, db *dao.DaoDB, appOrgCode string, vendorThingList []*tiktok_store.TiktokIdAndLocalSkuId, thingType, syncFlag int8, vendorFlag bool) (err error) {
	if thingType == model.ThingTypeSkuName {
		return nil
	}
	errList := errlist.New()
	for _, v := range vendorThingList {
		thingMap := &model.ThingMap{
			ThingID:       v.LocalSkuId,
			ThingType:     thingType,
			VendorID:      model.VendorIDDD,
			VendorOrgCode: appOrgCode,
			VendorThingID: v.MainId,
			Remark:        v.SkuAttrId,
		}
		if thingType == model.ThingTypeCategory && !vendorFlag {
			syncFlag = 0
		}
		thingMap.SyncStatus = syncFlag
		dao.WrapAddIDCULDEntity(thingMap, ctx.GetUserName())
		if err2 := dao.CreateEntity(db, thingMap); err2 != nil {
			if err2 := getThingMap(db, thingMap); err2 == nil {
				thingMap.SyncStatus = 2
				thingMap.LastOperator = ctx.GetUserName()
				_, err2 = dao.UpdateEntity(db, thingMap)
				errList.AddErr(err2)
			}
		}
	}
	err = errList.GetErrListAsOne()
	return err
}

func onUpdateThing(ctx *jxcontext.Context, db *dao.DaoDB, vendorInfoList []*model.VendorOrgCode, thingID int64, thingType int8, syncStatus int8) (err error) {
	if thingType == model.ThingTypeSkuName {
		return nil
	}
	if len(vendorInfoList) == 0 {
		vendorInfoList, err = dao.GetVendorOrgCode(db, model.VendorIDJD, "", model.VendorOrgTypePlatform)
	}
	errList := errlist.New()
	for _, v := range vendorInfoList {
		thingMap := &model.ThingMap{
			ThingID:       thingID,
			ThingType:     thingType,
			VendorID:      v.VendorID,
			VendorOrgCode: v.VendorOrgCode,
		}
		thingMap.DeletedAt = utils.DefaultTimeValue
		if err2 := getThingMap(db, thingMap); err2 == nil {
			thingMap.SyncStatus |= syncStatus
			thingMap.LastOperator = ctx.GetUserName()
			_, err2 = dao.UpdateEntity(db, thingMap)
			errList.AddErr(err2)

			updateThingMapEntity(db, thingMap)
		} else {
			if dao.IsNoRowsError(err2) {
				err2 = nil
			} else {
				errList.AddErr(err2)
			}
		}
	}
	err = errList.GetErrListAsOne()
	return err
}

func DeleteThingByData(ctx *jxcontext.Context, db *dao.DaoDB, appOrgCode string, startTime time.Time, endTime time.Time) error {
	sql := ` DELETE FROM thing_map WHERE vendor_org_code = ? AND created_at  >= ? AND created_at < ? `
	_, err := dao.ExecuteSQL(db, sql, []interface{}{appOrgCode, startTime, endTime})
	return err
}

func OnUpdateThing(ctx *jxcontext.Context, db *dao.DaoDB, vendorInfoList []*model.VendorOrgCode, thingID int64, thingType int8) (err error) {
	return onUpdateThing(ctx, db, vendorInfoList, thingID, thingType, model.SyncFlagModifiedMask)
}

func OnDeleteThing(ctx *jxcontext.Context, db *dao.DaoDB, vendorInfoList []*MultiStoreVendorInfo, thingID int64, thingType int8) (err error) {
	if thingType == model.ThingTypeSkuName {
		return nil
	}
	if len(vendorInfoList) == 0 {
		vendorInfoList = getMultiStoreVendorInfoList()
	}
	errList := errlist.New()
	for _, v := range vendorInfoList {
		thingMap := &model.ThingMap{
			ThingID:       thingID,
			ThingType:     thingType,
			VendorID:      v.VendorID,
			VendorOrgCode: v.OrgCode,
		}
		thingMap.DeletedAt = utils.DefaultTimeValue
		if err2 := getThingMap(db, thingMap); err2 == nil {
			if model.IsSyncStatusNew(thingMap.SyncStatus) {
				thingMap.SyncStatus = 0
				thingMap.DeletedAt = time.Now()
			} else {
				thingMap.SyncStatus |= model.SyncFlagDeletedMask
			}
			thingMap.LastOperator = ctx.GetUserName()
			_, err2 = dao.UpdateEntity(db, thingMap)
			errList.AddErr(err2)

			updateThingMapEntity(db, thingMap)
		} else if !dao.IsNoRowsError(err2) {
			errList.AddErr(err2)
		}
	}
	err = errList.GetErrListAsOne()
	return err
}

func SkuCategoryVendor2ThingMap(cat *dao.SkuStoreCatInfo) (thingMap *model.ThingMap) {
	thingMap = &model.ThingMap{
		ThingID:       int64(cat.ID),
		ThingType:     model.ThingTypeCategory,
		VendorID:      cat.VendorID,
		VendorOrgCode: cat.VendorOrgCode,

		SyncStatus:    cat.CatSyncStatus,
		VendorThingID: cat.VendorCatID,
	}
	thingMap.ID = cat.MapID // 一定要赋值
	return thingMap
}

func SkuVendor2ThingMap(sku *dao.StoreSkuSyncInfo) (thingMap *model.ThingMap) {
	thingMap = &model.ThingMap{
		ThingID:       int64(sku.SkuID),
		ThingType:     model.ThingTypeSku,
		VendorID:      sku.VendorID,
		VendorOrgCode: sku.VendorOrgCode,

		SyncStatus:    sku.SkuSyncStatus,
		VendorThingID: sku.VendorSkuID,
	}
	thingMap.DeletedAt = utils.DefaultTimeValue
	thingMap.ID = sku.BindID // 一定要赋值
	return thingMap
}

func OnThingSync(ctx *jxcontext.Context, db *dao.DaoDB, thingMap *model.ThingMap, syncErr error) (err error) {
	if syncErr != nil {
		err = syncErr
		thingMap.Remark = utils.LimitUTF8StringLen(err.Error(), 255)
		dao.UpdateEntity(db, thingMap, "Remark")

		if thingMap.VendorOrgCode == globals.JdcsOrgCode {
			if strings.Contains(err.Error(), "店内分类信息不存在") {
				err = nil
			}
		}
	} else {
		updateFields := []string{
			model.FieldSyncStatus,
			model.FieldUpdatedAt,
			model.FieldLastOperator,
			"Remark",
		}
		if model.IsSyncStatusDelete(thingMap.SyncStatus) { //删除
			thingMap.DeletedAt = time.Now()
			thingMap.VendorThingID = ""
			updateFields = append(updateFields, "VendorThingID", model.FieldDeletedAt)
		} else if model.IsSyncStatusNew(thingMap.SyncStatus) { // 新增
			updateFields = append(updateFields, "VendorThingID")
		}
		thingMap.SyncStatus = 0
		thingMap.LastOperator = ctx.GetUserName()
		thingMap.UpdatedAt = time.Now()
		thingMap.Remark = ""
		_, err = dao.UpdateEntity(db, thingMap, updateFields...)

		updateThingMapEntity(db, thingMap)
	}
	return err
}

func updateThingMapEntity(db *dao.DaoDB, thingMap *model.ThingMap) {
	// if thingMap.VendorOrgCode == globals.JdOrgCode {
	// 	if thingMap.ThingType == model.ThingTypeCategory {
	// 		cat := &model.SkuCategory{
	// 			JdID:         utils.Str2Int64WithDefault(thingMap.VendorThingID, 0),
	// 			JdSyncStatus: thingMap.SyncStatus,
	// 		}
	// 		cat.ID = int(thingMap.ThingID)
	// 		dao.UpdateEntity(db, cat, "JdID", "JdSyncStatus")
	// 	} else if thingMap.ThingType == model.ThingTypeSku {
	// 		sku := &model.Sku{
	// 			JdID:         utils.Str2Int64WithDefault(thingMap.VendorThingID, 0),
	// 			JdSyncStatus: thingMap.SyncStatus,
	// 		}
	// 		sku.ID = int(thingMap.ThingID)
	// 		dao.UpdateEntity(db, sku, "JdID", "JdSyncStatus")
	// 	}
	// }
}

func amendAndPruneVendorStuff(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID, vendorID int, vendorOrgCode string, isAsync, isContinueWhenError bool, opType int, isForceUpdate bool) (hint string, err error) {
	handler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler)
	if handler == nil {
		return "", fmt.Errorf("平台:%s不支持此操作", model.VendorChineseNames[vendorID])
	}
	db := dao.GetDB()
	vendorOrgCodes, _ := dao.GetVendorOrgCode(db, vendorID, vendorOrgCode, model.VendorOrgTypePlatform)
	var sku2Delete []*partner.StoreSkuInfo
	var cat2Delete []*partner.BareCategoryInfo
	task := tasksch.NewParallelTask(fmt.Sprintf("平台:%s,账号:%s上的商品与商家分类", model.VendorChineseNames[vendorID], vendorOrgCode),
		tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(isContinueWhenError), ctx,
		func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
			step := batchItemList[0].(int)
			switch step {
			case 0:
				localSkuList, err := dao.GetSkusWithVendor(db, []int{vendorID}, []string{vendorOrgCode}, nil, nil, false)
				if err != nil {
					return nil, err
				}
				localSkuMap := make(map[string]*dao.StoreSkuSyncInfo)
				for _, v := range localSkuList {
					if v.VendorSkuID != "" {
						localSkuMap[v.VendorSkuID] = v
					}
				}

				remoteSkuList, err2 := handler.GetSkus(ctx, vendorOrgCode, 0, "")
				if err = err2; err == nil {
					remoteSkuMap := make(map[string]int)
					for _, v := range remoteSkuList {
						if vendorSkuID := v.SkuList[0].VendorSkuID; vendorSkuID != "" {
							if localSkuMap[vendorSkuID] == nil {
								sku2Delete = append(sku2Delete, &partner.StoreSkuInfo{
									SkuID:       v.SkuList[0].SkuID,
									VendorSkuID: vendorSkuID,
								})
							} else {
								remoteSkuMap[vendorSkuID] = 1
							}
						} else if v.VendorNameID != "" {
							sku2Delete = append(sku2Delete, &partner.StoreSkuInfo{
								SkuID:       v.NameID,
								VendorSkuID: v.VendorNameID,
							})
						}
					}
					StoreSkuMap := make(map[int]*dao.StoreSkuSyncInfo)
					if storeID != 0 {
						skuList2, _ := dao.GetStoreSkuListWithVendor(db, storeID, vendorID, vendorOrgCode)
						for _, v := range skuList2 {
							if _, ok := StoreSkuMap[v.ID]; !ok {
								StoreSkuMap[v.ID] = v
							}
						}
					}
					getSyncFlag := func(skuID int) int8 {
						if StoreSkuMap[skuID] != nil {
							return model.SyncFlagNewMask
						}
						return 0
					}
					if opType == AmendPruneOnlyAmend || opType == AmendPruneAll {
						for _, v := range localSkuList {
							if v.ExdSkuID == "" {
								if v.BindID != 0 {
									if !model.IsSyncStatusDelete(v.SkuSyncStatus) {
										if remoteSkuMap[v.VendorSkuID] == 0 {
											if !model.IsSyncStatusNew(v.SkuSyncStatus) {
												err = OnCreateThing(ctx, db, vendorOrgCodes, int64(v.SkuID), model.ThingTypeSku, getSyncFlag(v.SkuID), false)
											}
										} else if isForceUpdate {
											err = OnUpdateThing(ctx, db, vendorOrgCodes, int64(v.SkuID), model.ThingTypeSku)
										}
									}
								} else {
									//表示根据某门店的门店商品同步京东商品库中，这个门店关注并可售了这个商品，插到thingmap里同步标志是待创建（SyncFlagNewMask）才会创建
									//若该门店没关注可售，那插到thingmap里的话就该同步标志为0，就不会创建
									//getSyncFlag
									err = OnCreateThing(ctx, db, vendorOrgCodes, int64(v.SkuID), model.ThingTypeSku, getSyncFlag(v.SkuID), false)
								}
							}
						}
					}
				}
			case 1:
				// if (opType == AmendPruneOnlyPrune || opType == AmendPruneAll) && len(sku2Delete) > 0 {
				// 	_, err = putils.FreeBatchStoreSkuInfo("删除商品", func(task tasksch.ITask, batchedStoreSkuList []*partner.StoreSkuInfo) (result interface{}, successCount int, err error) {
				// 		if err = handler.DeleteSku2(ctx, vendorOrgCode, batchedStoreSkuList[0]); err == nil {
				// 			successCount = 1
				// 		}
				// 		return nil, successCount, err
				// 	}, ctx, task, sku2Delete, 1, isContinueWhenError)
				// }
				sku2Delete = nil
			case 2:
				localCatList, err := dao.GetSkuCategoryWithVendor(db, []int{vendorID}, []string{vendorOrgCode}, -1, nil, false)
				if err != nil {
					return nil, err
				}
				localCatMap := make(map[string]*dao.SkuStoreCatInfo)
				for _, v := range localCatList {
					localCatMap[v.VendorCatID] = v
					localCatMap[v.Name] = v
					localCatMap[utils.Int2Str(v.ID)] = v
				}

				vendorCatMap := make(map[int]*model.VendorCategoryMap)
				if vendorOrgCodes[0].IsJxCat == model.YES {
					vendorCats, _ := dao.GetVendorCategoryMap(db, -1, 0, vendorID, vendorOrgCode, 0)
					for _, v := range vendorCats {
						if _, ok := vendorCatMap[v.CategoryID]; !ok {
							vendorCatMap[v.CategoryID] = v
						}
					}
				}
				getSyncFlagCat := func(categoryID int) int8 {
					if vendorCatMap[categoryID] != nil || vendorOrgCodes[0].IsJxCat == model.NO {
						return model.SyncFlagNewMask
					}
					return 0
				}
				remoteCatList, err2 := handler.GetAllCategories(ctx, vendorOrgCode)
				if err = err2; err == nil {
					remoteCatMap := make(map[string]int)
					cat2Delete = checkRemoteCatExist(remoteCatMap, localCatMap, remoteCatList)
					for _, v := range localCatList {
						if v.IsExdSpec == model.NO {
							if v.MapID != 0 {
								if !model.IsSyncStatusDelete(v.CatSyncStatus) {
									if remoteCatMap[v.VendorCatID] == 0 {
										if !model.IsSyncStatusNew(v.CatSyncStatus) {
											err = OnCreateThing(ctx, db, vendorOrgCodes, int64(v.ID), model.ThingTypeCategory, getSyncFlagCat(v.ID), true)
										}
									} else if isForceUpdate && !model.IsSyncStatusUpdate(v.CatSyncStatus) {
										OnUpdateThing(ctx, db, vendorOrgCodes, int64(v.ID), model.ThingTypeCategory)
									}
								}
							} else {
								OnCreateThing(ctx, db, vendorOrgCodes, int64(v.ID), model.ThingTypeCategory, getSyncFlagCat(v.ID), true)
							}
						}
					}
				}
			case 3:
				if (opType == AmendPruneOnlyPrune || opType == AmendPruneAll) && len(cat2Delete) > 0 {
					for i := 0; i < 2; i++ {
						level := 2 - i
						var levelCat2Delete []*partner.BareCategoryInfo
						for _, v := range cat2Delete {
							if v.Level == level {
								levelCat2Delete = append(levelCat2Delete, v)
							}
						}
						if len(levelCat2Delete) > 0 {
							// task4Delete := tasksch.NewParallelTask(fmt.Sprintf("删除商家分类,level:%d", level), tasksch.NewParallelConfig().SetIsContinueWhenError(isContinueWhenError), ctx,
							// 	func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
							// 		cat := batchItemList[0].(*partner.BareCategoryInfo)
							// 		err = handler.DeleteCategory2(ctx, vendorOrgCode, cat.VendorCatID)
							// 		return nil, err
							// 	}, levelCat2Delete)
							// tasksch.HandleTask(task4Delete, task, true).Run()
							// _, err = task4Delete.GetResult(0)
						}
					}
				}
				cat2Delete = nil
			}
			return nil, err
		}, []int{0, 1, 2, 3})
	tasksch.HandleTask(task, parentTask, true).Run()
	if !isAsync {
		_, err = task.GetResult(0)
		hint = "1"
	} else {
		hint = task.ID
	}
	return hint, err
}

func FullSyncVendorStuff(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID, vendorID int, vendorOrgCode string, isAsync, isContinueWhenError bool) (hint string, err error) {
	multiStoreHandler, _ := partner.GetPurchasePlatformFromVendorID(vendorID).(partner.IMultipleStoresHandler)
	if multiStoreHandler == nil {
		return "", fmt.Errorf("vendorID:%d不是多门店平台", vendorID)
	}
	worker := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
		step := batchItemList[0].(int)
		switch step {
		case 0:
			_, err = amendAndPruneVendorStuff(ctx, task, storeID, vendorID, vendorOrgCode, false, isContinueWhenError, AmendPruneAll, false)
		case 1:
			//_, err = SyncCategories(ctx, task, []int{vendorID}, []string{vendorOrgCode}, nil, false)
		case 2:
			_, err = SyncSkus(ctx, task, []int{vendorID}, []string{vendorOrgCode}, nil, nil, false)
		}
		return retVal, err
	}
	task := tasksch.NewParallelTask("FullSyncStoreSkuNew", tasksch.NewParallelConfig().SetParallelCount(1).SetIsContinueWhenError(false), ctx, worker, []int{0, 1, 2})
	tasksch.HandleTask(task, parentTask, true).Run()
	if !isAsync {
		_, err = task.GetResult(0)
	} else {
		hint = task.GetID()
	}
	return hint, err
}
