package tiktok_store

import (
	"git.rosy.net.cn/baseapi/platformapi/mtwmapi"
	"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/business/partner/putils"
	"git.rosy.net.cn/jx-callback/globals"
	"git.rosy.net.cn/jx-callback/globals/api"
)

func jxActType2Mtwm(actType int) int {
	if actType == model.ActSkuDirectDown {
		actType = mtwmapi.RetailActTypeDirectDown
	} else if actType == model.ActSkuSecKill {
		actType = mtwmapi.RetailActTypeSecKill
	} else {
		actType = 0
	}
	return actType
}

func actOrderRules2Mtwm(actOrderRules []*model.ActOrderRule) (actDetails []*mtwmapi.FullDiscountActDetail) {
	for _, v := range actOrderRules {
		actDetails = append(actDetails, &mtwmapi.FullDiscountActDetail{
			OriginalPrice: jxutils.IntPrice2Standard(v.SalePrice),
			ActPrice:      jxutils.IntPrice2Standard(v.DeductPrice),
		})
	}
	return actDetails
}

func storeSku2ActData(act *model.Act2, actStoreSku []*model.ActStoreSku2, handler func(int8) bool) (actData []*mtwmapi.RetailDiscountActData) {
	orderLimit := 1
	//if act.LimitCount > 0 {
	//	orderLimit = act.LimitCount
	//}
	for _, v := range actStoreSku {
		if handler == nil || handler(v.SyncStatus) {
			dayLimit := -1
			if v.Stock > 0 {
				dayLimit = v.Stock
			}
			actData = append(actData, &mtwmapi.RetailDiscountActData{
				AppFoodCode: utils.Int2Str(v.SkuID),
				// UserType:    0,
				StartTime:  act.BeginAt.Unix(),
				EndTime:    act.EndAt.Unix(),
				OrderLimit: orderLimit,
				DayLimit:   dayLimit,
				// Period:     "",
				// WeeksTime: "",
				SettingType: mtwmapi.SettingTypeAsPrice,
				ActPrice:    jxutils.IntPrice2Standard(v.ActualActPrice),
				// DiscountCoefficient: 0,
				// Sequence: int(v.ActPrice), // 此字段不允许重复
				// ItemID: utils.Str2Int64WithDefault(v.VendorActID, 0),
			})
		}
	}
	return actData
}

func storeSku2ActData4Delete(actStoreSku []*model.ActStoreSku2, handler func(int8) bool) (actIDList []string) {
	for _, v := range actStoreSku {
		if handler == nil || handler(v.SyncStatus) {
			if v.VendorActID != "" {
				actIDList = append(actIDList, v.VendorActID)
			}
		}
	}
	return actIDList
}

func isCreateOrUpdate(syncStatus int8) bool {
	return model.IsSyncStatusNeedCreate(syncStatus) || model.IsSyncStatusNeedUpdate(syncStatus)
}

func createOneShopAct(act *model.Act2, vendorStoreID string, actStoreSku []*model.ActStoreSku2) (failedList []*partner.StoreSkuInfoWithErr, err error) {
	actData := storeSku2ActData(act, actStoreSku, isCreateOrUpdate)
	if len(actData) > 0 {
		if globals.EnableMtwmStoreWrite {
			actResult, faileInfoList, err2 := api.MtwmAPI.RetailDiscountBatchSave2(vendorStoreID, jxActType2Mtwm(act.Type), actData)
			err = err2
			actStoreSkuMap := make(map[int]*model.ActStoreSku2)
			for _, v := range actStoreSku {
				actStoreSkuMap[v.SkuID] = v
			}

			for _, v := range actResult {
				if v2 := actStoreSkuMap[int(utils.Str2Int64WithDefault(v.AppFoodCode, 0))]; v2 != nil {
					v2.VendorActID = utils.Int64ToStr(v.ActID)
				}
			}
			for _, v := range faileInfoList {
				if v2 := actStoreSkuMap[int(utils.Str2Int64WithDefault(v.AppFoodCode, 0))]; v2 != nil {
					failedList = append(failedList, &partner.StoreSkuInfoWithErr{
						StoreSkuInfo: &partner.StoreSkuInfo{
							SkuID: v2.SkuID,
						},
						VendoreID: model.VendorIDMTWM,
						StoreID:   int(utils.Str2Int64WithDefault(vendorStoreID, 0)),
						ErrMsg:    v.ErrorMsg,
					})
				}
			}
		} else {
			for _, v := range actStoreSku {
				v.VendorActID = utils.Int64ToStr(jxutils.GenFakeID())
			}
		}
	}
	return failedList, err
}

func cancelOneShopAct(act *model.Act2, vendorStoreID string, actStoreSku []*model.ActStoreSku2) (failedList []*partner.StoreSkuInfoWithErr, err error) {
	if list := storeSku2ActData4Delete(actStoreSku, nil /*model.IsSyncStatusNeedDelete*/); len(list) > 0 {
		if globals.EnableMtwmStoreWrite {
			failedList2, err2 := api.MtwmAPI.RetailDiscountDelete2(vendorStoreID, jxActType2Mtwm(act.Type), list)
			actStoreSkuMap := make(map[string]*model.ActStoreSku2)
			for _, v := range actStoreSku {
				actStoreSkuMap[v.VendorActID] = v
			}
			for _, v := range failedList2 {
				if !mtwmapi.CanDeleteActErrMsgIgnore(v.ErrorMsg) {
					failedList = append(failedList, &partner.StoreSkuInfoWithErr{
						StoreSkuInfo: &partner.StoreSkuInfo{
							SkuID: actStoreSkuMap[utils.Int64ToStr(v.ActID)].SkuID,
						},
						StoreID:   int(utils.Str2Int64WithDefault(vendorStoreID, 0)),
						ErrMsg:    v.ErrorMsg,
						VendoreID: model.VendorIDMTWM,
					})
				}
			}
			err = err2
			err = nil // 强制不返回错误，使用部分错误
		}
	}
	return failedList, err
}

func getActStoreSkuFromTaskResult(taskReslt []interface{}) (list []*model.ActStoreSku2) {
	for _, v := range taskReslt {
		actStoreSkuList := v.([]*model.ActStoreSku2)
		list = append(list, actStoreSkuList...)
	}
	return list
}

func createSkuAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreSku []*model.ActStoreSku2) (createdList []*model.ActStoreSku2, err error) {
	actStoreSkuListList := partner.SplitActStoreSku2List(actStoreSku)
	task := tasksch.NewParallelTask("Tiktok createSkuAct", nil, ctx,
		func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
			list := batchItemList[0].([]*model.ActStoreSku2)
			failedList, err2 := createOneShopAct(act, list[0].VendorStoreID, list)
			if err = err2; err2 == nil {
				if len(failedList) > 0 {
					failedMap := putils.StoreSkuInfoWithErrList2MapBySku(failedList)
					list = []*model.ActStoreSku2{}
					for _, v := range actStoreSku {
						if failedMap[v.SkuID] == nil {
							list = append(list, v)
						}
					}
					list = []*model.ActStoreSku2{}
				}
				retVal = []interface{}{list}
			}
			return retVal, err
		}, actStoreSkuListList)
	tasksch.HandleTask(task, parentTask, true).Run()
	result, err := task.GetResult(0)
	return getActStoreSkuFromTaskResult(result), err
}

func cancelSkuAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actStoreSku []*model.ActStoreSku2) (canceledList []*model.ActStoreSku2, err error) {
	actStoreSkuListList := partner.SplitActStoreSku2List(actStoreSku)
	task := tasksch.NewParallelTask("mtwm cancelSkuAct", nil, ctx,
		func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
			actStoreSkuList := batchItemList[0].([]*model.ActStoreSku2)
			if _, err = cancelOneShopAct(act, actStoreSkuList[0].VendorStoreID, actStoreSkuList); err == nil {
				retVal = []interface{}{actStoreSkuList}
			}
			return retVal, err
		}, actStoreSkuListList)
	tasksch.HandleTask(task, parentTask, true).Run()
	result, err := task.GetResult(0)
	return getActStoreSkuFromTaskResult(result), err
}

func (c *PurchaseHandler) SyncAct(ctx *jxcontext.Context, parentTask tasksch.ITask, act *model.Act2, actOrderRules []*model.ActOrderRule, actStoreSkuList []*model.ActStoreSku2) (err error) {
	var actStoreSkuList4Create, actStoreSkuList4Delete []*model.ActStoreSku2
	var updateItems []*dao.KVUpdateItem

	actStoreSkuMap := partner.SplitActStoreSku(actStoreSkuList)
	for storeID := range actStoreSkuMap {
		for _, actStoreSku := range actStoreSkuMap[storeID] {
			if model.IsSyncStatusDelete(actStoreSku.SyncStatus) {
				actStoreSkuList4Delete = append(actStoreSkuList4Delete, actStoreSku)
			} else if model.IsSyncStatusNew(actStoreSku.SyncStatus) {
				actStoreSkuList4Create = append(actStoreSkuList4Create, actStoreSku)
			}
		}
	}
	err = func() (err error) {
		if model.IsSyncStatusDelete(act.SyncStatus) {
			canceledList, err2 := cancelSkuAct(ctx, nil, act, actStoreSkuList)
			updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, canceledList, model.SyncFlagModifiedMask)...)
			if err = err2; err == nil {
				updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagModifiedMask))
			}
		} else if model.IsSyncStatusNew(act.SyncStatus) {
			createdList, err2 := createSkuAct(ctx, nil, act, actStoreSkuList4Create)
			updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, createdList, model.SyncFlagNewMask)...)
			if err = err2; err == nil {
				updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagNewMask))
			}
		} else if model.IsSyncStatusUpdate(act.SyncStatus) {
			if len(actStoreSkuList4Create) > 0 {
				addedList, err2 := createSkuAct(ctx, nil, act, actStoreSkuList4Create)
				updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, addedList, model.SyncFlagNewMask)...)
				if err = err2; err != nil {
					return err
				}
			}
			if len(actStoreSkuList4Delete) > 0 {
				deletedList, err2 := cancelSkuAct(ctx, nil, act, actStoreSkuList4Delete)
				updateItems = append(updateItems, partner.ActStoreSku2Update(ctx, deletedList, model.SyncFlagDeletedMask)...)
				if err = err2; err != nil {
					return err
				}
			}
			if err == nil {
				updateItems = append(updateItems, partner.Act2Update(ctx, act, model.SyncFlagModifiedMask))
			}
		}
		return err
	}()
	db := dao.GetDB()
	_, err2 := dao.BatchUpdateActEntity(db, model.IsSyncStatusDelete(act.SyncStatus), updateItems)
	if err == nil {
		err = err2
	}
	return err
}

func (c *PurchaseHandler) GetActAmple(ctx *jxcontext.Context, vendorStoreID, vendorOrgCode string) (ample int, err error) {
	return 0, err
	//for _, v := range mtwmapi.ActTypeList {
	//	//1表示进行中
	//	if actList, err := getAPI(vendorOrgCode, 0, vendorStoreID).GetByAppPoiCodeAndType(vendorOrgCode, 1, v); err == nil {
	//		ample += len(actList)
	//	}
	//}
	//return ample, err
}
