package partner

import (
	"math"
	"regexp"
	"time"

	"git.rosy.net.cn/baseapi/utils"
	"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"
)

const (
	// FuncGetStoreSkusBareInfo  = 1 // 此接口要求实现为不限制批处理大小的
	FuncUpdateStoreSkusStock  = 2  // 更新门店库存
	FuncUpdateStoreSkusStatus = 3  // 更新门店状态
	FuncUpdateStoreSkusPrice  = 4  // 更新门店价格
	FuncGetStoreSkusFullInfo  = 6  // 获取门店商品完整信息
	FuncCreateStoreSkus       = 7  // 创建门店商品
	FuncUpdateStoreSkus       = 8  // 修改门店商品
	FuncDeleteStoreSkus       = 9  // 删除门店商品
	FuncCreateActs            = 10 // 创建活动
	FuncCancelActs            = 11 // 取消活动
)

const (
	UnlimitedBatchSize = math.MaxInt32

	MaxStoreSkuStock       = model.MaxStoreSkuStockQty
	UnlimitedStoreSkuStock = -1
)

type StoreSkuInfo struct {
	SkuID        int    `json:"skuID,omitempty"`
	VendorSkuID  string `json:"vendorSkuID,omitempty"`
	NameID       int    `json:"nameID,omitempty"`
	VendorNameID string `json:"vendorNameID,omitempty"`

	Stock       int   `json:"stock,omitempty"`
	VendorPrice int64 `json:"price,omitempty"`
	Status      int   `json:"status,omitempty"`

	Seq int `json:"seq,omitempty"`

	ActPrice       int64   `json:"actPrice,omitempty"`
	VendorActID    string  `json:"vendorActID,omitempty"`
	IsSpecialty    int     `json:"isSpecialty,omitempty"`
	JxPrice        int64   `json:"jxPrice,omitempty"`
	JxUnitPrice    int64   `json:"jxUnitPrice,omitempty"`
	VendorSkuID2   string  `json:"vendorSkuID2,omitempty"`
	JdsStockSwitch int     `json:"jdsStockSwitch"`
	IsDeletedBySku bool    `json:"isDeletedBySku"`
	VendorOrgCode  string  `json:"vendorOrgCode"`
	SpecUnit       string  `json:"specUnit"`
	SpecQuality    float32 `json:"specQuality"`

	VendorMainId    string `json:"vendorMainId"`    // 主商品id
	VendorSkuAttrId string `json:"vendorSkuAttrId"` //主商品sku_id
	VendorSonSkuID  string `json:"vendorSonSkuID"`  // 子商品skuid
}

type StoreSkuInfoWithErr struct {
	StoreSkuInfo *StoreSkuInfo
	CategoryName string
	VendoreID    int
	VendoreName  string
	StoreID      int
	SyncType     string
	ErrMsg       string
}

type SkuInfo struct {
	StoreSkuInfo
	SkuName     string
	Comment     string
	SpecQuality float64
	SpecUnit    string
	Weight      int
	ActPrice    int64
}

type SkuNameInfo struct {
	NameID       int    `json:"nameID,omitempty"`
	VendorNameID string `json:"vendorNameID,omitempty"`

	Prefix          string
	Name            string
	Description     string
	Unit            string
	VendorCatIDList []string
	PictureList     []string
	UPC             string
	Status          int `json:"status,omitempty"`
	YbBarCode       string
	SkuList         []*SkuInfo
}

type BareStoreSkuInfoList []*StoreSkuInfo

func (l BareStoreSkuInfoList) GetVendorSkuIDList() (vendorSkuIDList []string) {
	for _, v := range l {
		if !dao.IsVendorThingIDEmpty(v.VendorSkuID) {
			vendorSkuIDList = append(vendorSkuIDList, v.VendorSkuID)
		}
	}
	return vendorSkuIDList
}

func (l BareStoreSkuInfoList) GetVendorSkuIDIntList() (vendorSkuIDIntList []int64) {
	for _, v := range l {
		if !dao.IsVendorThingIDEmpty(v.VendorSkuID) {
			vendorSkuIDIntList = append(vendorSkuIDIntList, utils.Str2Int64(v.VendorSkuID))
		}
	}
	return vendorSkuIDIntList
}

func (l BareStoreSkuInfoList) GetSkuIDList() (skuIDList []int) {
	for k, v := range l {
		if v.SkuID > 0 {
			skuIDList[k] = v.SkuID
		}
	}
	return skuIDList
}

func (l BareStoreSkuInfoList) Len() int {
	return len(l)
}

func (l BareStoreSkuInfoList) Less(i, j int) bool {
	if l[i].Seq != l[j].Seq {
		return l[i].Seq < l[j].Seq
	}
	return l[i].VendorPrice < l[j].VendorPrice
}

func (l BareStoreSkuInfoList) Swap(i, j int) {
	l[i], l[j] = l[j], l[i]
}

type BareCategoryInfo struct {
	VendorCatID string `json:"vendorCatID"`

	Level    int                 `json:"level"`
	Name     string              `json:"name"`
	Seq      int                 `json:"seq,omitempty"`
	Children []*BareCategoryInfo `json:"children,omitempty"`
}

// 批处理函数，如果是部分失败的情况会返回失败，successedList中会返回成功的列表

type IPurchasePlatformStoreSkuHandler interface {
	GetStoreSkusBatchSize(funcID int) int

	ListOrders(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, queryDate time.Time, vendorStoreID string) (vendorOrderIDs []string, err error)

	// 此接口要求实现为不限制批处理大小的
	GetStoreSkusBareInfo(ctx *jxcontext.Context, vendorOrgCode string, parentTask tasksch.ITask, storeID int, vendorStoreID string, inStoreSkuList []*StoreSkuInfo) (outStoreSkuList []*StoreSkuInfo, err error)
	UpdateStoreSkusStock(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (failedList []*StoreSkuInfoWithErr, err error)
	UpdateStoreSkusStatus(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo, status int) (failedList []*StoreSkuInfoWithErr, err error)
	UpdateStoreSkusPrice(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (failedList []*StoreSkuInfoWithErr, err error)

	CreateStoreSkusAct(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (failedList []*StoreSkuInfoWithErr, err error)
	CancelActs(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (failedList []*StoreSkuInfoWithErr, err error)
	UpdateStoreSkusSpecTag(ctx *jxcontext.Context, vendorOrgCode string, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (err error)
	// GetSkuCategoryIdByName 获取各个平台推荐分类
	GetSkuCategoryIdByName(vendorOrgCode, skuName string) (vendorCategoryId string, err error)

	// GetVendorAllSkuList 同平台商品复制(饿了么复制饿了么,美团复制美团),获取商品

	// UploadInvoice 发票回复
	UploadInvoice(param *model.InvoiceMsg, base64 string) ([]string, []string, error)
	// UploadPickingImg 上传订单拣货图片
	UploadPickingImg(order *model.GoodsOrder, imgList interface{}) error
}

type ISingleStoreStoreSkuHandler interface {
	IPurchasePlatformStoreSkuHandler

	GetStoreSkusFullInfo(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (outSkuNameList []*SkuNameInfo, err error)
	CreateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*StoreSkuInfoWithErr, err error)
	UpdateStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*dao.StoreSkuSyncInfo) (failedList []*StoreSkuInfoWithErr, err error)
	DeleteStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeSkuList []*StoreSkuInfo) (failedList []*StoreSkuInfoWithErr, err error)
	DeleteStoreAllSkus(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, isContinueWhenError bool) (err error)
	IsErrSkuExist(err error) (isExist bool)
	IsErrSkuNotExist(err error) (isNotExist bool)

	GetStoreAllCategories(ctx *jxcontext.Context, storeID int, vendorStoreID string) (cats []*BareCategoryInfo, err error)
	GetStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID, catName string) (cat *BareCategoryInfo, err error)
	CreateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error)
	UpdateStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID string, storeCat *dao.SkuStoreCatInfo) (err error)
	DeleteStoreCategory(ctx *jxcontext.Context, storeID int, vendorStoreID, vendorCatID string, level int) (err error)
	DeleteStoreAllCategories(ctx *jxcontext.Context, parentTask tasksch.ITask, storeID int, vendorStoreID string, isContinueWhenError bool) (err error)

	IsErrCategoryExist(err error) (isExist bool)
	IsErrCategoryNotExist(err error) (isNotExist bool)

	GetSensitiveWordRegexp() *regexp.Regexp
}

type IStoreSkuSorter interface {
	ReorderStoreSkus(ctx *jxcontext.Context, storeID int, vendorStoreID string, vendorCatID string, storeSkuList []*StoreSkuInfo) (err error)
}

func BuildSkuName(skuID int, vendorSkuID string) (skuName *SkuNameInfo) {
	return &SkuNameInfo{
		SkuList: []*SkuInfo{
			&SkuInfo{
				StoreSkuInfo: StoreSkuInfo{
					SkuID:       skuID,
					VendorSkuID: vendorSkuID,
				},
			},
		},
	}
}
