package dao

import (
	"fmt"
	"time"

	"git.rosy.net.cn/jx-callback/globals"

	"git.rosy.net.cn/baseapi/utils"
	"git.rosy.net.cn/jx-callback/business/jxutils"
	"git.rosy.net.cn/jx-callback/business/model"
)

type ActMapPureInfo struct {
	VendorID      int    `orm:"column(vendor_id)" json:"vendorID"`
	VendorOrgCode string `orm:"size(32)" json:"vendorOrgCode"` // 同一平台下不同的商户代码，如果只有一个，可以为空
	VendorActID   string `orm:"column(vendor_act_id);size(48)" json:"vendorActID"`
	SyncStatus    int    `orm:"default(2)" json:"syncStatus"`
	Remark        string `orm:"column(map_remark)" json:"remark"`
}

type ActVendorInfo struct {
	model.Act
	VendorList []*ActMapPureInfo `json:"vendorList"`
}

type tActAndMap struct {
	model.Act
	MapID int `orm:"column(map_id)" json:"-"` // 内部使用，不暴露
	ActMapPureInfo
}

type PagedActListInfo struct {
	TotalCount int              `json:"totalCount"`
	Data       []*ActVendorInfo `json:"data"`
}

func GetActVendorInfo(db *DaoDB, actID int, vendorIDs []int) (actMap map[int]*model.Act2, err error) {
	leftOrEmpty := ""
	if len(vendorIDs) == 1 && vendorIDs[0] == -1 {
		leftOrEmpty = "LEFT"
	}
	sql := fmt.Sprintf(`
	SELECT t1.*,
	t2.id map_id, t2.vendor_id, t2.vendor_org_code, t2.vendor_act_id, t2.sync_status
	FROM act t1
	%s JOIN act_map t2 ON t2.act_id = t1.id AND t2.deleted_at = ?`, leftOrEmpty)
	sqlParams := []interface{}{
		utils.DefaultTimeValue,
	}

	if len(vendorIDs) > 0 {
		sql += " AND t2.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
		sqlParams = append(sqlParams, vendorIDs)
	}

	sql += `
	WHERE t1.deleted_at = ? AND t1.id = ?`
	sqlParams = append(sqlParams, utils.DefaultTimeValue, actID)

	var actList []*model.Act2
	if err = GetRows(db, &actList, sql, sqlParams...); err == nil {
		actMap = make(map[int]*model.Act2)
		for _, v := range actList {
			if leftOrEmpty != "" {
				v.VendorID = -1
			}
			actMap[v.VendorID] = v
		}
	}
	return actMap, err
}

func GetActStoreSkuVendorList(db *DaoDB, actID int, vendorIDs, storeIDs, skuIDs []int, keyword string, offset, pageSize int) (totalCount int, actStoreSkuList []*model.ActStoreSku2, err error) {
	offset = jxutils.FormalizePageOffset(offset)
	pageSize = jxutils.FormalizePageSize(pageSize)

	leftOrEmpty := ""
	if len(vendorIDs) == 1 && (vendorIDs[0] == -1 || vendorIDs[0] == model.VendorIDJX) {
		leftOrEmpty = "LEFT"
	}
	sql := fmt.Sprintf(`
	SELECT SQL_CALC_FOUND_ROWS
	t1.*,
	t2.id map_id, t2.vendor_id, t2.vendor_act_id, t2.sync_status, t2.actual_act_price, t2.vendor_price, t2.trend_type, t2.trend_price,
	t3.vendor_store_id,
	CASE t2.vendor_id
		WHEN 0 THEN
			t4m.vendor_thing_id
		WHEN 1 THEN
			t5.mtwm_id
		WHEN 3 THEN
			t5.ebai_id
		ELSE
			''
	END vendor_sku_id,
	t4.comment, t4.spec_quality, t4.spec_unit,
	t6.name store_name,
	t7.name sku_name_name, t7.unit, t7.prefix, t7.ex_prefix, t7.ex_prefix_begin, t7.ex_prefix_end
	FROM act_store_sku t1
	%s JOIN act_store_sku_map t2 ON t2.act_id = ? AND t2.bind_id = t1.id AND t2.deleted_at = ?`, leftOrEmpty)
	sqlParams := []interface{}{
		actID,
		utils.DefaultTimeValue,
	}

	if len(vendorIDs) > 0 {
		sql += " AND t2.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
		sqlParams = append(sqlParams, vendorIDs)
	}
	sql += `
	LEFT JOIN store_map t3 ON t3.store_id = t1.store_id AND t3.vendor_id = t2.vendor_id AND t3.deleted_at = ?
	JOIN sku t4 ON t4.id = t1.sku_id
	LEFT JOIN thing_map t4m ON t4m.vendor_id = ? AND t4m.thing_id = t4.id AND t4m.thing_type = ? AND t4m.vendor_id = t2.vendor_id AND t4m.vendor_org_code = t3.vendor_org_code AND t4m.deleted_at = ?
	LEFT JOIN store_sku_bind t5 ON t5.sku_id = t1.sku_id AND t5.store_id = t1.store_id AND t5.deleted_at = ?
	LEFT JOIN store t6 ON t6.id = t1.store_id
	JOIN sku_name t7 ON t7.id = t4.name_id
	WHERE t1.act_id = ?
	`
	sqlParams = append(sqlParams,
		utils.DefaultTimeValue,
		model.VendorIDJD, model.ThingTypeSku, utils.DefaultTimeValue,
		utils.DefaultTimeValue,
		actID,
	)
	if keyword != "" {
		keywordLike := "%" + keyword + "%"
		sql += " AND (t7.name LIKE ? OR t6.name LIKE ?"
		sqlParams = append(sqlParams, keywordLike, keywordLike)
		if intKeyword := int(utils.Str2Int64WithDefault(keyword, 0)); intKeyword > 0 {
			sql += " OR t1.sku_id = ? OR t1.store_id = ?"
			sqlParams = append(sqlParams, intKeyword, intKeyword)
		}
		sql += ")"
	}
	if leftOrEmpty != "" {
		sql += " AND t1.deleted_at = ?"
		sqlParams = append(sqlParams, utils.DefaultTimeValue)
	}
	if len(storeIDs) > 0 {
		sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
		sqlParams = append(sqlParams, storeIDs)
	}
	if len(skuIDs) > 0 {
		sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
		sqlParams = append(sqlParams, skuIDs)
	}
	sql += " LIMIT ? OFFSET ?;"
	sqlParams = append(sqlParams, pageSize, offset)
	txDB, _ := Begin(db)
	defer Commit(db, txDB)
	if err = GetRowsTx(txDB, &actStoreSkuList, sql, sqlParams...); err == nil {
		totalCount = GetLastTotalRowCount2(db, txDB)
	}

	// 统计门店活动商品一个月之内的销量
	storeAndSkuMap := make(map[int][]int, 0)
	storeActMap := make(map[int][]*model.ActStoreSku2, 0)
	for _, v := range actStoreSkuList {
		storeAndSkuMap[v.StoreID] = append(storeAndSkuMap[v.StoreID], v.SkuID)
		storeActMap[v.StoreID] = append(storeActMap[v.StoreID], v)
	}
	for storeID, skuIds := range storeAndSkuMap {
		settleSkuCountSql := ` SELECT sum(s.count) count,s.sku_id FROM order_sku_financial s WHERE s.jx_store_id = ? AND s.created_at >= ? `
		settleSkuCountParam := []interface{}{storeID, time.Now().AddDate(0, -1, 0)}
		if len(skuIds) != 0 {
			settleSkuCountSql += ` AND s.sku_id IN (` + GenQuestionMarks(len(skuIds)) + ")"
			settleSkuCountParam = append(settleSkuCountParam, skuIds)
		}
		settleSkuCountSql += ` AND s.is_afs_order = 0 GROUP BY s.sku_id`

		settleCount := make([]*SettleSkuCount, 0, 0)
		if err = GetRows(db, &settleCount, settleSkuCountSql, settleSkuCountParam...); err != nil {
			globals.SugarLogger.Debugf("统计商品月销量异常:%v", err)
			continue
		}

		for _, scv := range settleCount {
			for _, sam := range storeActMap[storeID] {
				if scv.SkuId == sam.SkuID {
					sam.MonthlySales = scv.Count
				}
			}
		}

	}

	return totalCount, actStoreSkuList, err
}

type SettleSkuCount struct {
	Count int `json:"count"`  // 销量
	SkuId int `json:"sku_id"` // 商品
}

func GetActStoreSkuVendorInfo(db *DaoDB, actID int, vendorIDs, storeIDs, skuIDs []int) (actStoreSkuMap map[int][]*model.ActStoreSku2, err error) {
	leftOrEmpty := ""
	if len(vendorIDs) == 1 && vendorIDs[0] == -1 {
		leftOrEmpty = "LEFT"
	}
	_, actStoreSkuList, err := GetActStoreSkuVendorList(db, actID, vendorIDs, storeIDs, skuIDs, "", 0, -1)
	if err == nil {
		actStoreSkuMap = make(map[int][]*model.ActStoreSku2)
		for _, v := range actStoreSkuList {
			if leftOrEmpty != "" {
				v.VendorID = -1
			}
			actStoreSkuMap[v.VendorID] = append(actStoreSkuMap[v.VendorID], v)
		}
	}
	return actStoreSkuMap, err
}

func QueryActs(db *DaoDB, actID int, offset, pageSize int, syncStatus int, keyword string, vendorID int, statusList, actTypeList, createTypeList []int,
	storeID int, skuIDs []int, cityCode int, beginAt, endAt, createdAtFrom, createdAtTo time.Time) (pagedInfo *PagedActListInfo, err error) {
	if actID == 0 && utils.IsTimeZero(createdAtFrom) && utils.IsTimeZero(beginAt) {
		return nil, fmt.Errorf("actID,createdAtFrom和beginAt中，至少要指定一个条件")
	}
	offset = jxutils.FormalizePageOffset(offset)
	pageSize = jxutils.FormalizePageSize(pageSize)
	isGetAll := offset == 0 && pageSize == model.UnlimitedPageSize

	sql := `
	SELECT SQL_CALC_FOUND_ROWS
	DISTINCT t1.id
	FROM act t1`
	sqlParams := []interface{}{}
	if isGetAll {
		sql = `
		SELECT
		t1.*,
		t2.id map_id, t2.vendor_id, t2.vendor_act_id, t2.sync_status, t2.remark map_remark
		FROM act t1`
	}
	sql += " LEFT JOIN act_map t2 ON t2.act_id = t1.id AND t2.deleted_at = ?"
	sqlParams = append(sqlParams, utils.DefaultTimeValue)
	if syncStatus >= 0 {
		sql += " AND (t2.sync_status = ? OR t2.sync_status & ? <> 0)"
		sqlParams = append(sqlParams, syncStatus, syncStatus)
	}
	sql += `
	WHERE t1.deleted_at = ?`
	if syncStatus >= 0 {
		sql += " AND t2.id IS NOT NULL"
	}
	sqlParams = append(sqlParams, utils.DefaultTimeValue)
	keywordInt := int64(0)
	if keyword != "" {
		keywordLike := "%" + keyword + "%"
		sql += " AND ( t1.name LIKE ? OR t1.advertising LIKE ? OR t1.remark LIKE ? OR t2.vendor_act_id LIKE ?"
		sqlParams = append(sqlParams, keywordLike, keywordLike, keywordLike, keywordLike)
		keywordInt = utils.Str2Int64WithDefault(keyword, 0)
		if keywordInt > 0 {
			sql += `
			OR t1.id = ?`
			sqlParams = append(sqlParams, keywordInt)
		}
		sql += ")"
	}
	if storeID > 0 || len(skuIDs) > 0 || cityCode > 0 {
		sql += ` AND (SELECT COUNT(*)
					FROM act_store_sku t2`
		if cityCode > 0 {
			sql += " JOIN store t3 ON t3.id = t2.store_id AND t3.city_code = ?"
			sqlParams = append(sqlParams, cityCode)
		}
		sql += `
		WHERE t2.act_id = t1.id AND t2.deleted_at = ?`
		sqlParams = append(sqlParams, utils.DefaultTimeValue)
		if storeID > 0 {
			sql += " AND t2.store_id = ?"
			sqlParams = append(sqlParams, storeID)
		}
		if len(skuIDs) > 0 {
			sql += " AND t2.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
			sqlParams = append(sqlParams, skuIDs)
		}
		sql += ") > 0"
	}
	if actID > 0 {
		sql += " AND t1.id = ?"
		sqlParams = append(sqlParams, actID)
	}
	if vendorID >= 0 {
		sql += " AND t1.vendor_mask & ? <> 0"
		sqlParams = append(sqlParams, model.GetVendorMask(vendorID))
	}
	if len(statusList) > 0 {
		sql += " AND t1.status IN (" + GenQuestionMarks(len(statusList)) + ")"
		sqlParams = append(sqlParams, statusList)
	}
	if len(actTypeList) > 0 {
		sql += " AND t1.type IN (" + GenQuestionMarks(len(actTypeList)) + ")"
		sqlParams = append(sqlParams, actTypeList)
	}
	if len(createTypeList) > 0 {
		sql += " AND t1.create_type IN (" + GenQuestionMarks(len(createTypeList)) + ")"
		sqlParams = append(sqlParams, createTypeList)
	}
	if !utils.IsTimeZero(beginAt) {
		sql += " AND t1.begin_at <= ?"
		sqlParams = append(sqlParams, beginAt)
	}
	if !utils.IsTimeZero(endAt) {
		sql += " AND t1.end_at >= ?"
		sqlParams = append(sqlParams, endAt)
	}
	if !utils.IsTimeZero(createdAtFrom) {
		sql += " AND t1.created_at >= ?"
		sqlParams = append(sqlParams, createdAtFrom)
	}
	if !utils.IsTimeZero(createdAtTo) {
		sql += " AND t1.created_at <= ?"
		sqlParams = append(sqlParams, createdAtTo)
	}

	pagedInfo = &PagedActListInfo{}
	if isGetAll {
		sql += `
		ORDER BY t1.id DESC, t2.vendor_id`
	} else {
		sql += `
		ORDER BY 1 DESC
		LIMIT ? OFFSET ?
		`
		sqlParams = append(sqlParams, pageSize, offset)
		var idList []int

		txDB, _ := Begin(db)
		defer Commit(db, txDB)
		defer func() {
			if r := recover(); r != nil {
				Rollback(db, txDB)
				panic(r)
			}
		}()
		if err = GetRowsTx(txDB, &idList, sql, sqlParams...); err != nil || len(idList) == 0 {
			//Rollback(db, txDB)
			Commit(db, txDB)
			return pagedInfo, err
		}
		pagedInfo.TotalCount = GetLastTotalRowCount2(db, txDB)

		sql = `
		SELECT
		t1.*,
		t2.id map_id, t2.vendor_id, t2.vendor_org_code, t2.vendor_act_id, t2.sync_status, t2.remark map_remark
		FROM act t1
		LEFT JOIN act_map t2 ON t2.act_id = t1.id AND t2.deleted_at = ?
		WHERE t1.id IN (` + GenQuestionMarks(len(idList)) + `)`
		if syncStatus >= 0 {
			sql += " AND t2.id IS NOT NULL"
		}
		sql += `
		ORDER BY t1.id DESC, t2.vendor_id`
		sqlParams = []interface{}{
			utils.DefaultTimeValue,
			idList,
		}
	}
	var actList []*tActAndMap
	if err = GetRows(db, &actList, sql, sqlParams...); err != nil {
		return nil, err
	}
	actMap := make(map[int]*ActVendorInfo)
	for _, v := range actList {
		tmpAct := actMap[v.ID]
		if tmpAct == nil {
			tmpAct = &ActVendorInfo{
				Act: v.Act,
			}
			actMap[v.ID] = tmpAct
			pagedInfo.Data = append(pagedInfo.Data, tmpAct)
		}
		if v.MapID > 0 {
			tmpAct.VendorList = append(tmpAct.VendorList, &v.ActMapPureInfo)
		}
	}
	if isGetAll {
		pagedInfo.TotalCount = len(pagedInfo.Data)
	}
	return pagedInfo, err
}

func GetExistVendorActIDs(db *DaoDB, vendorID int) (vendorActIDs []string, err error) {
	// todo 不应该是全表扫描
	sql := `
	SELECT
	DISTINCT t1.vendor_act_id
	FROM act_store_sku_map t1
	WHERE t1.deleted_at = ? AND t1.vendor_id = ?`
	sqlParams := []interface{}{
		utils.DefaultTimeValue,
		vendorID,
	}
	err = GetRows(db, &vendorActIDs, sql, sqlParams...)
	return vendorActIDs, err
}

func GetEffectiveActStoreSkuInfo(db *DaoDB, actID int, vendorIDs []int, actType int, storeIDs, skuIDs []int, beginAt, endAt time.Time) (actStoreSkuList []*model.ActStoreSku2, err error) {
	if utils.IsTimeZero(beginAt) {
		return nil, fmt.Errorf("GeActStoreSkuInfo必须指定活动开始时间")
	}
	if utils.IsTimeZero(endAt) {
		endAt = beginAt
	}
	sql := `
	SELECT
	t1.type, t1.discount_type, t1.discount_value1, t1.discount_value2,
	t2.*,
	t3.actual_act_price, t3.sync_status, t3.vendor_price, t3.vendor_id, t3.trend_type, t3.trend_price
	FROM act t1
	JOIN act_store_sku t2 ON t2.act_id = t1.id AND t2.deleted_at = ?
	JOIN act_store_sku_map t3 ON t3.bind_id = t2.id AND t3.act_id = t1.id AND (t3.sync_status & ? = 0 OR t1.type = ?)
	JOIN act_map t4 ON t4.act_id = t1.id AND t4.vendor_id = t3.vendor_id AND t4.deleted_at = ? AND (t4.sync_status & ? = 0 OR t1.type = ?)
	WHERE t1.deleted_at = ? AND t1.status = ? AND NOT (t1.begin_at > ? OR t1.end_at < ?) AND t1.create_type = ?`
	sqlParams := []interface{}{
		utils.DefaultTimeValue,

		model.SyncFlagNewMask,
		model.ActSkuFake,

		utils.DefaultTimeValue, model.SyncFlagNewMask, model.ActSkuFake,
		utils.DefaultTimeValue, model.ActStatusCreated, endAt, beginAt, model.ActCreateTypeAPI,
	}
	if len(vendorIDs) > 0 {
		sql += " AND (t1.vendor_mask & ?) <> 0 AND t3.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
		sqlParams = append(sqlParams, model.GetVendorMask(vendorIDs...), vendorIDs)
	}
	if actID > 0 {
		sql += " AND t1.id = ?"
		sqlParams = append(sqlParams, actID)
	}
	if actType != model.ActTypeAll {
		sql += " AND t1.type = ?"
		sqlParams = append(sqlParams, actType)
	}
	if len(storeIDs) > 0 {
		sql += " AND t2.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
		sqlParams = append(sqlParams, storeIDs)
	}
	if len(skuIDs) > 0 {
		sql += " AND t2.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
		sqlParams = append(sqlParams, skuIDs)
	}
	if globals.IsStoreSkuAct {
		sql += " AND t1.is_special = 0"
	}
	err = GetRows(db, &actStoreSkuList, sql, sqlParams...)
	return actStoreSkuList, err
}

func GetEffectiveActStoreSkuInfo2(db *DaoDB, actID int, vendorIDs []int, actTypes []int, storeIDs, skuIDs []int, beginAt, endAt time.Time) (actStoreSkuList []*model.ActStoreSku2, err error) {
	if utils.IsTimeZero(beginAt) {
		return nil, fmt.Errorf("GeActStoreSkuInfo必须指定活动开始时间")
	}
	if utils.IsTimeZero(endAt) {
		endAt = beginAt
	}
	sql := `
	SELECT
	t1.type,
	t2.*,
	t3.actual_act_price, t3.sync_status, t3.vendor_price, t3.vendor_id
	FROM act t1
	JOIN act_store_sku t2 ON t2.act_id = t1.id AND t2.deleted_at = ?
	JOIN act_store_sku_map t3 ON t3.bind_id = t2.id AND t3.act_id = t1.id AND (t3.sync_status & ? = 0 OR t1.type = ?)
	JOIN act_map t4 ON t4.act_id = t1.id AND t4.vendor_id = t3.vendor_id AND t4.deleted_at = ? AND (t4.sync_status & ? = 0 OR t1.type = ?)
	WHERE t1.deleted_at = ? AND t1.status = ? AND NOT (t1.begin_at > ? OR t1.end_at < ?) AND t1.create_type = ?`
	sqlParams := []interface{}{
		utils.DefaultTimeValue,

		model.SyncFlagNewMask,
		model.ActSkuFake,

		utils.DefaultTimeValue, model.SyncFlagNewMask, model.ActSkuFake,
		utils.DefaultTimeValue, model.ActStatusCreated, endAt, beginAt, model.ActCreateTypeAPI,
	}
	if len(vendorIDs) > 0 {
		sql += " AND (t1.vendor_mask & ?) <> 0 AND t3.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
		sqlParams = append(sqlParams, model.GetVendorMask(vendorIDs...), vendorIDs)
	}
	if actID > 0 {
		sql += " AND t1.id = ?"
		sqlParams = append(sqlParams, actID)
	}
	if len(actTypes) > 0 {
		sql += " AND t1.type IN (" + GenQuestionMarks(len(actTypes)) + ")"
		sqlParams = append(sqlParams, actTypes)
	}
	if len(storeIDs) > 0 {
		sql += " AND t2.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
		sqlParams = append(sqlParams, storeIDs)
	}
	if len(skuIDs) > 0 {
		sql += " AND t2.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
		sqlParams = append(sqlParams, skuIDs)
	}
	if globals.IsStoreSkuAct {
		sql += " AND t1.is_special = 0"
	}
	err = GetRows(db, &actStoreSkuList, sql, sqlParams...)
	return actStoreSkuList, err
}

func UpdateActStatusByTime(db *DaoDB, refTime time.Time) (num int64, err error) {
	sql := `
	UPDATE act t1
	SET t1.status = ?
	WHERE t1.deleted_at = ? AND t1.status < ? AND t1.end_at < ?;`
	sqlParams := []interface{}{
		model.ActStatusEnded,
		utils.DefaultTimeValue,
		model.ActStatusCanceled,
		utils.Time2Date(refTime),
	}
	num, err = ExecuteSQL(db, sql, sqlParams...)
	return num, err
}

// func ActStoreSkuMap2StoreSkuAct(actStoreSkuMap *model.ActStoreSkuMap, isCanceled bool) (storeSkuAct *model.StoreSkuAct) {
// 	storeSkuAct = &model.StoreSkuAct{
// 		StoreID:  actStoreSkuMap.StoreID,
// 		SkuID:    actStoreSkuMap.SkuID,
// 		VendorID: actStoreSkuMap.VendorID,
// 	}
// 	storeSkuAct.CreatedAt = actStoreSkuMap.CreatedAt
// 	storeSkuAct.UpdatedAt = actStoreSkuMap.UpdatedAt
// 	storeSkuAct.LastOperator = actStoreSkuMap.LastOperator

// 	if actStoreSkuMap.ActualActPrice > 0 {
// 		if isCanceled || !utils.IsTimeZero(actStoreSkuMap.DeletedAt) {
// 			storeSkuAct.ActID = 0
// 		} else {
// 			storeSkuAct.ActID = actStoreSkuMap.ActID
// 			storeSkuAct.VendorActID = actStoreSkuMap.VendorActID
// 			storeSkuAct.SyncStatus = actStoreSkuMap.SyncStatus
// 			storeSkuAct.VendorPrice = actStoreSkuMap.VendorPrice
// 			storeSkuAct.ActualActPrice = actStoreSkuMap.ActualActPrice
// 		}
// 	}
// 	if actStoreSkuMap.EarningPrice > 0 {
// 		if isCanceled || !utils.IsTimeZero(actStoreSkuMap.DeletedAt) {
// 			storeSkuAct.EarningActID = 0
// 		} else {
// 			storeSkuAct.EarningActID = actStoreSkuMap.ActID
// 			storeSkuAct.EarningPrice = actStoreSkuMap.EarningPrice
// 		}
// 	}
// 	return storeSkuAct
// }

func BatchUpdateActEntity(db *DaoDB, isCanceled bool, items []*KVUpdateItem) (num int64, err error) {
	return BatchUpdateEntityByKV(db, items)
	// if globals.IsStoreSkuAct {
	// 	Begin(db)
	// 	defer func() {
	// 		if r := recover(); r != nil || err != nil {
	// 			Rollback(db)
	// 			if r != nil {
	// 				panic(r)
	// 			}
	// 		}
	// 	}()

	// 	for _, v := range items {
	// 		if actStoreSku, ok := v.Item.(*model.ActStoreSkuMap); ok {
	// 			for k1, v1 := range v.KVs {
	// 				refutil.SetObjFieldByName(actStoreSku, k1, v1)
	// 			}
	// 			if err = CreateOrUpdateActStoreSku(db, ActStoreSkuMap2StoreSkuAct(actStoreSku, isCanceled)); err != nil {
	// 				return 0, err
	// 			}
	// 		}
	// 	}
	// }

	// if _, err = BatchUpdateEntityByKV(db, items); err != nil {
	// 	return 0, err
	// }

	// if globals.IsStoreSkuAct {
	// 	Commit(db)
	// }
	// return num, err
}

func CreateOrUpdateActStoreSku(db *DaoDB, storeSkuAct *model.StoreSkuAct) (err error) {
	storeSkuActCopy := *storeSkuAct
	if err2 := GetEntity(db, &storeSkuActCopy, model.FieldStoreID, model.FieldSkuID, model.FieldVendorID); err2 == nil {
		storeSkuAct.ID = storeSkuActCopy.ID
		_, err = UpdateEntity(db, storeSkuAct)
	} else if IsNoRowsError(err2) {
		err = CreateEntity(db, storeSkuAct)
	} else {
		err = err2
	}
	return err
}

func GetStoresSkusAct(db *DaoDB, hintActID int, mustDirty bool, storeIDs, skuIDs, vendorIDs []int, mustHaveVendorActID bool, minActPercentage, maxActPercentage int) (storeSkuActList []*model.StoreSkuAct, err error) {
	sql := `
	SELECT *
	FROM store_sku_act t1
	WHERE 1 = 1
	`
	sqlParams := []interface{}{}
	if hintActID > 0 {
		sql += " AND t1.hint_act_id = ?"
		sqlParams = append(sqlParams, hintActID)
	}
	if mustDirty {
		sql += " AND (t1.sync_status <> 0 OR (t1.act_percentage = 0 AND t1.vendor_act_id <> '') OR (t1.act_percentage <> 0 AND t1.vendor_act_id = ''))"
	}
	if len(storeIDs) > 0 {
		sql += " AND t1.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
		sqlParams = append(sqlParams, storeIDs)
	}
	if len(skuIDs) > 0 {
		sql += " AND t1.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
		sqlParams = append(sqlParams, skuIDs)
	}
	if len(vendorIDs) > 0 {
		sql += " AND t1.vendor_id IN (" + GenQuestionMarks(len(vendorIDs)) + ")"
		sqlParams = append(sqlParams, vendorIDs)
	}
	if mustHaveVendorActID {
		sql += " AND t1.vendor_act_id <> ''"
	}
	if minActPercentage > 0 {
		sql += " AND t1.act_percentage >= ?"
		sqlParams = append(sqlParams, minActPercentage)
	}
	if maxActPercentage > 0 {
		sql += " AND t1.act_percentage <= ?"
		sqlParams = append(sqlParams, maxActPercentage)
	}
	err = GetRows(db, &storeSkuActList, sql, sqlParams...)
	return storeSkuActList, err
}

func GetStoresSkusAndActInfo(db *DaoDB, storeIDs, skuIDs, vendorIDs []int, minActPercentage, maxActPercentage int) (storeSkuAndActList []*StoreSkuAndAct, err error) {
	storeSkuList, err := GetStoresSkusInfo(db, storeIDs, skuIDs)
	if err == nil && len(storeSkuList) > 0 {
		storeSkuActList, err2 := GetStoresSkusAct(db, 0, false, storeIDs, skuIDs, vendorIDs, false, minActPercentage, maxActPercentage)
		if err = err2; err == nil {
			actMap := make(map[int64][]*model.StoreSkuAct)
			for _, v := range storeSkuActList {
				actMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = append(actMap[jxutils.Combine2Int(v.StoreID, v.SkuID)], v)
			}
			for _, v := range storeSkuList {
				storeSkuAct := &StoreSkuAndAct{
					StoreSkuBind: v,
					ActMap:       make(map[int]*model.StoreSkuAct),
				}
				for _, vv := range actMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] {
					storeSkuAct.ActMap[vv.VendorID] = vv
				}
				storeSkuAndActList = append(storeSkuAndActList, storeSkuAct)
			}
		}
	}
	return storeSkuAndActList, err
}

// func GetConflictStoreSkuActInfo(db *DaoDB, vendorIDs []int, inStoreSkuActList []*model.StoreSkuAct) (outStoreSkuActList []*model.StoreSkuAct, err error) {
// 	storeIDMap := make(map[int]int)
// 	skuIDMap := make(map[int]int)
// 	inStoreSkuActMap := make(map[int64]*model.StoreSkuAct)
// 	for _, v := range inStoreSkuActList {
// 		storeIDMap[v.StoreID] = 1
// 		skuIDMap[v.SkuID] = 1
// 		inStoreSkuActMap[jxutils.Combine2Int(v.StoreID, v.SkuID)] = v
// 	}
// 	storeIDs := jxutils.IntMap2List(storeIDMap)
// 	skuIDs := jxutils.IntMap2List(skuIDMap)

// 	sql := `
// 	SELECT *
// 	FROM store_sku_act t1
// 	WHERE
// 		t1.store_id IN (` + GenQuestionMarks(len(storeIDs)) + `)
// 	AND t1.sku_id IN (` + GenQuestionMarks(len(skuIDs)) + `)
// 	`
// 	sqlParams := []interface{}{
// 		storeIDs,
// 		skuIDs,
// 	}
// 	if len(vendorIDs) > 0 {
// 		sql += ` AND t1.vendor_Id IN (` + GenQuestionMarks(len(storeIDs)) + `)`
// 		sqlParams = append(sqlParams, vendorIDs)
// 	}

// 	var tmpStoreSkuActList []*model.StoreSkuAct
// 	if err = GetRows(db, &tmpStoreSkuActList, sql, sqlParams...); err == nil {
// 		for _, v := range tmpStoreSkuActList {
// 			tmpStoreSkuAct := inStoreSkuActMap[jxutils.Combine2Int(v.StoreID, v.SkuID)]
// 			if tmpStoreSkuAct != nil && (tmpStoreSkuAct.ActualActPrice > 0 && v.ActID != 0 && v.SyncStatus == 0 || tmpStoreSkuAct.EarningPrice > 0 && v.EarningActID != 0) {
// 				outStoreSkuActList = append(outStoreSkuActList, v)
// 			}
// 		}
// 	}
// 	return outStoreSkuActList, err
// }

func GetActMtwmVendors(db *DaoDB, storeIDs, skuIDs []int) (actMtwmVendors []*model.ActMtwmVendor, err error) {
	sql := `
		SELECT * 
		  FROM act_mtwm_vendor
 		 WHERE 1 = 1
	`
	sqlParams := []interface{}{}
	if len(storeIDs) > 0 {
		sql += " AND store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
		sqlParams = append(sqlParams, storeIDs)
	}
	if len(skuIDs) > 0 {
		sql += " AND sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
		sqlParams = append(sqlParams, skuIDs)
	}
	err = GetRows(db, &actMtwmVendors, sql, sqlParams)
	return actMtwmVendors, err
}

func GetActEbaiVendorSkus(db *DaoDB, storeIDs, skuIDs []int) (actEbaiVendorSku []*model.ActEbaiVendorSku, err error) {
	sql := `
		SELECT * 
		  FROM act_ebai_vendor_sku
 		 WHERE 1 = 1
	`
	sqlParams := []interface{}{}
	if len(storeIDs) > 0 {
		sql += " AND store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
		sqlParams = append(sqlParams, storeIDs)
	}
	if len(skuIDs) > 0 {
		sql += " AND sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
		sqlParams = append(sqlParams, skuIDs)
	}
	err = GetRows(db, &actEbaiVendorSku, sql, sqlParams)
	return actEbaiVendorSku, err
}

func GetActMtwmVendorPage(db *DaoDB, storeIDs, skuIDs []int, keyword string, beginAt, endAt time.Time, actType, offset, pageSize int) (page *model.PagedInfo, err error) {
	var (
		acts []*model.ActMtwmVendor
	)
	pageInfo := &model.PagedInfo{}

	sql := `
		SELECT SQL_CALC_FOUND_ROWS  b.name store_name ,a.*
		  FROM act_mtwm_vendor a
     LEFT JOIN store b ON a.store_id = b.id 
 	 WHERE 1 = 1 
	`
	sqlParams := []interface{}{}
	if len(storeIDs) > 0 {
		sql += " AND a.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
		sqlParams = append(sqlParams, storeIDs)
	}
	if len(skuIDs) > 0 {
		sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
		sqlParams = append(sqlParams, skuIDs)
	}
	if keyword != "" {
		sql += " AND (a.store_id = ? OR a.sku_id = ? OR a.sku_name LIKE ? OR b.name LIKE ?)"
		sqlParams = append(sqlParams, keyword, keyword, "%"+keyword+"%", "%"+keyword+"%")
	}
	if !utils.IsTimeZero(beginAt) {
		sql += " AND a.begin_at >= ?"
		sqlParams = append(sqlParams, beginAt)
	}
	if !utils.IsTimeZero(endAt) {
		sql += " AND a.end_at <= ?"
		sqlParams = append(sqlParams, endAt)
	}
	if actType != 0 {
		sql += " AND a.act_type = ?"
		sqlParams = append(sqlParams, actType)
	}
	sql += `
		GROUP BY 1, 2, 3, 4
		LIMIT ? OFFSET ?
	`
	sqlParams = append(sqlParams, pageSize, (offset-1)*pageSize)
	txDB, _ := Begin(db)
	defer Commit(db, txDB)
	defer func() {
		if r := recover(); r != nil {
			Rollback(db, txDB)
			panic(r)
		}
	}()

	if err = GetRowsTx(txDB, &acts, sql, sqlParams...); err == nil && len(acts) != 0 {
		pageInfo.TotalCount = GetLastTotalRowCount2(db, txDB)
		pageInfo.Data = acts
	}
	return pageInfo, err
}

// GetDontHaveSku 获取不存在此商品活动的门店
func GetDontHaveSku(db *DaoDB, storeIds []int, offSet, pageSize int) (interface{}, error) {
	var parma []interface{}
	sql := `
			SELECT a.store_id,b.name store_name FROM act_mtwm_vendor a 
			LEFT JOIN store b ON a.store_id = b.id
			WHERE 1=1 
`
	type SkuAct struct {
		StoreId   int    `json:"store_id"`
		StoreName string `json:"store_name"`
	}

	if len(storeIds) != 0 {
		sql += "AND a.store_id NOT IN (" + GenQuestionMarks(len(storeIds)) + ")"
		parma = append(parma, storeIds)
	}

	sql += ` GROUP BY a.store_id LIMIT ? OFFSET ? `
	parma = append(parma, pageSize, (offSet-1)*pageSize)
	var result []*SkuAct
	if err := GetRows(db, &result, sql, parma); err != nil {
		return nil, err
	}
	return result, nil
}

func GetActMtwmVendorSkuPage(db *DaoDB, storeID int, keyword string, actType, offset, pageSize int) (page *model.PagedInfo, err error) {
	var (
		acts []*model.ActMtwmVendor
	)
	sql := `
		SELECT SQL_CALC_FOUND_ROWS a.*
		  FROM act_mtwm_vendor a WHERE store_id = ?
	`
	sqlParams := []interface{}{storeID}
	if keyword != "" {
		sql += " AND (a.store_id = ? OR a.sku_id = ? OR a.sku_name LIKE ?)"
		sqlParams = append(sqlParams, keyword, keyword, "%"+keyword+"%")
	}
	if actType != 0 {
		sql += " AND a.act_type = ?"
		sqlParams = append(sqlParams, actType)
	}
	sql += `
		LIMIT ? OFFSET ?
	`
	sqlParams = append(sqlParams, (offset-1)*pageSize, pageSize)
	txDB, _ := Begin(db)
	defer Commit(db, txDB)
	defer func() {
		if r := recover(); r != nil {
			Rollback(db, txDB)
			panic(r)
		}
	}()
	if err = GetRowsTx(txDB, &acts, sql, sqlParams...); err == nil {
		page.TotalCount = GetLastTotalRowCount2(db, txDB)
		page.Data = acts
	}
	return page, err
}

func GetActEbaiVendorPage(db *DaoDB, storeIDs, skuIDs []int, keyword string, beginAt, endAt time.Time, actType, offset, pageSize int) (page *model.PagedInfo, err error) {
	var (
		acts []*model.ActEbaiVendor
	)
	sql := `
		SELECT SQL_CALC_FOUND_ROWS a.begin_at, a.end_at, a.act_id, a.act_name
		  FROM act_ebai_vendor a
     LEFT JOIN act_ebai_vendor_sku b ON a.act_id = b.act_id
	 LEFT JOIN store c ON c.id = b.store_id
	`
	sqlParams := []interface{}{}
	if len(storeIDs) > 0 {
		sql += " AND b.store_id IN (" + GenQuestionMarks(len(storeIDs)) + ")"
		sqlParams = append(sqlParams, storeIDs)
	}
	if len(skuIDs) > 0 {
		sql += " AND b.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
		sqlParams = append(sqlParams, skuIDs)
	}
	if keyword != "" {
		sql += " AND (b.store_id = ? OR b.sku_id = ? OR b.sku_name LIKE ? OR a.name LIKE ? OR c.name LIKE ?)"
		sqlParams = append(sqlParams, keyword, keyword, "%"+keyword+"%", "%"+keyword+"%", "%"+keyword+"%")
	}
	if !utils.IsTimeZero(beginAt) {
		sql += " AND a.begin_at <= ?"
		sqlParams = append(sqlParams, beginAt)
	}
	if !utils.IsTimeZero(endAt) {
		sql += " AND a.end_at >= ?"
		sqlParams = append(sqlParams, endAt)
	}
	if actType != 0 {
		sql += " AND a.act_type = ?"
		sqlParams = append(sqlParams, actType)
	}
	sql += `
		GROUP BY 1, 2, 3, 4
		LIMIT ? OFFSET ?
	`
	sqlParams = append(sqlParams, pageSize, offset)
	txDB, _ := Begin(db)
	defer Commit(db, txDB)
	defer func() {
		if r := recover(); r != nil {
			Rollback(db, txDB)
			panic(r)
		}
	}()
	if err = GetRowsTx(txDB, &acts, sql, sqlParams...); err == nil {
		page.TotalCount = GetLastTotalRowCount2(db, txDB)
		page.Data = acts
	}
	return page, err
}

func GetActEbaiVendorSkuPage(db *DaoDB, actID, keyword string, offset, pageSize int) (page *model.PagedInfo, err error) {
	var (
		acts []*model.ActEbaiVendorSku
	)
	sql := `
		SELECT SQL_CALC_FOUND_ROWS a.*
		  FROM act_ebai_vendor_sku a WHERE act_id = ?
     LEFT JOIN store b ON b.id = a.store_id 
	`
	sqlParams := []interface{}{actID}
	if keyword != "" {
		sql += " AND (a.store_id = ? OR a.sku_id = ? OR a.sku_name LIKE ? OR b.name LIKE ?)"
		sqlParams = append(sqlParams, keyword, keyword, "%"+keyword+"%", "%"+keyword+"%")
	}
	sql += `
		LIMIT ? OFFSET ?
	`
	sqlParams = append(sqlParams, pageSize, offset)
	txDB, _ := Begin(db)
	defer Commit(db, txDB)
	defer func() {
		if r := recover(); r != nil {
			Rollback(db, txDB)
			panic(r)
		}
	}()
	if err = GetRowsTx(txDB, &acts, sql, sqlParams...); err == nil {
		page.TotalCount = GetLastTotalRowCount2(db, txDB)
		page.Data = acts
	}
	return page, err
}
