package misc

import (
	"errors"
	"fmt"
	"math"
	"sync"

	"git.rosy.net.cn/jx-callback/business/jxstore/cms"
	"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"
)

const (
	DayNum   = 30  //请求天数
	LimitNum = 100 //最大数据限制
)

func GetStoreSkuSalesInfo(ctx *jxcontext.Context, storeID int) (outStoreSkuSales []*model.StoreSkuSales, err error) {
	db := dao.GetDB()
	//得到所有门店
	storeList, err := GetStoreList(ctx)
	if err == nil {
		storeList = GetFilterStoreListEx(storeList, nil)
	} else {
		return nil, err
	}
	storeMapData := make(map[int]*cms.StoreExt)
	for _, value := range storeList {
		storeMapData[value.ID] = value
	}
	curStoreInfo := storeMapData[storeID]
	if curStoreInfo == nil {
		return nil, errors.New(fmt.Sprintf("未找到商店:[%d]", storeID))
	}
	cityCode := curStoreInfo.CityCode

	//获取本市商品总销量
	citySkuSalesCntMap := make(map[int]int)
	citySkuSalesCntList, err := dao.GetSkuSalesCntList(db, -1, cityCode, DayNum, LimitNum, nil)
	citySkuIDs := []int{}
	if err == nil {
		for _, value := range citySkuSalesCntList {
			citySkuSalesCntMap[value.SkuID] = value.Count
			citySkuIDs = append(citySkuIDs, value.SkuID)
		}
	} else {
		return nil, err
	}

	//获取本店商品总销量
	storeSkuSalesCntMap := make(map[int]int)
	storeSkuSalesCntList, err := dao.GetSkuSalesCntList(db, storeID, cityCode, DayNum, -1, citySkuIDs)
	if err == nil {
		for _, value := range storeSkuSalesCntList {
			storeSkuSalesCntMap[value.SkuID] = value.Count
		}
	} else {
		return nil, err
	}

	//获取本店商品差评数量
	storeSkuBadCommentCntMap := make(map[int]int)
	storeSkuBadCommentCntList, err := dao.GetSkuBadCommentCntList(db, storeID, DayNum)
	if err == nil {
		for _, value := range storeSkuBadCommentCntList {
			storeSkuBadCommentCntMap[value.SkuID] = value.Count
		}
	} else {
		return nil, err
	}

	//得到当前门店商品数据
	storeSkuMapData := make(map[int]*dao.StoreSkuNameExt)
	storeSkuData, err := cms.GetStoreSkus(ctx, storeID, citySkuIDs, true, "", true, false, map[string]interface{}{}, 0, -1)
	if err == nil {
		for _, value := range storeSkuData.SkuNames {
			for _, skuInfo := range value.Skus {
				storeSkuMapData[skuInfo.SkuID] = value
			}
		}
	} else {
		return nil, err
	}

	//得到5KM内的所有门店
	rangeStoreList := GetRangeStoreList(storeID, curStoreInfo.FloatLng, curStoreInfo.FloatLat, SaleSkuCheckRange, storeList)

	//得到5KM内的所有门店的商品的价格
	allStoreSkus := make(map[int]map[int]int)
	var locker sync.RWMutex
	taskFunc := func(task *tasksch.ParallelTask, batchItemList []interface{}, params ...interface{}) (retVal interface{}, err error) {
		storeInfo := batchItemList[0].(*cms.StoreExt)
		storeID := storeInfo.ID
		jxSkuInfoData, err := cms.GetStoreSkus(ctx, storeID, citySkuIDs, true, "", true, false, map[string]interface{}{}, 0, -1)
		jxSkuPriceMapData := make(map[int]int)
		for _, value := range jxSkuInfoData.SkuNames {
			for _, skuInfo := range value.Skus {
				jxSkuPriceMapData[skuInfo.SkuID] = skuInfo.BindPrice
			}
		}
		locker.Lock()
		defer locker.Unlock()
		allStoreSkus[storeID] = jxSkuPriceMapData
		return retVal, err
	}
	taskParallel := tasksch.NewParallelTask("得到所有门店商品", nil, ctx, taskFunc, rangeStoreList)
	taskParallel.Run()
	_, err = taskParallel.GetResult(0)
	if err != nil {
		return nil, err
	}

	//计算商品的平均价格
	skusTotalPrice := make(map[int]int)
	skusCount := make(map[int]int)
	skusAveragePrice := make(map[int]int)
	for _, storeInfo := range rangeStoreList {
		storeID := storeInfo.ID
		storeSkuMapData := allStoreSkus[storeID]
		for skuID, skuPrice := range storeSkuMapData {
			skusTotalPrice[skuID] += skuPrice
			skusCount[skuID]++
		}
	}
	for id, totalPrice := range skusTotalPrice {
		skusAveragePrice[id] = int(math.Round(float64(totalPrice) / float64(skusCount[id])))
	}

	//输出商品销量统计结果
	skuAndNameMapData := make(map[int]*model.SkuAndName)
	if len(storeSkuMapData) < len(citySkuIDs) {
		skuAndNameList, err := dao.GetSkus(db, citySkuIDs, nil, nil, nil, nil)
		if err == nil {
			for _, value := range skuAndNameList {
				skuAndNameMapData[value.ID] = value
			}
		}
	}
	for _, value := range citySkuSalesCntList {
		skuID := value.SkuID
		storeSkuSales := &model.StoreSkuSales{}
		storeSkuSales.SkuID = skuID
		storeSkuInfo := storeSkuMapData[skuID]
		skuAndNameInfo := skuAndNameMapData[skuID]
		if storeSkuInfo != nil {
			skuName := storeSkuInfo.SkuName
			skuInfo := storeSkuInfo.Skus[0]
			storeSkuSales.SkuName = jxutils.ComposeSkuName(skuName.Prefix, skuName.Name, skuInfo.Comment, skuName.Unit, skuInfo.SkuSpecQuality, skuInfo.SkuSpecUnit, 0, skuName.ExPrefix, skuName.ExPrefixBegin, skuName.ExPrefixEnd)
			storeSkuSales.SkuImage = storeSkuInfo.Img
			storeSkuSales.SkuPrice = jxutils.IntPrice2StandardCurrencyString(int64(storeSkuInfo.Skus[0].BindPrice))
		} else if skuAndNameInfo != nil {
			skuNameList, err := dao.GetSkuNames(db, []int{skuAndNameInfo.NameID}, nil, "", false)
			prefix := ""
			if err == nil && len(skuNameList) > 0 {
				storeSkuSales.SkuImage = skuNameList[0].Img
				prefix = skuNameList[0].Prefix
			}
			storeSkuSales.SkuName = jxutils.ComposeSkuName(prefix, skuAndNameInfo.Name, skuAndNameInfo.Comment, skuAndNameInfo.Unit, skuAndNameInfo.SpecQuality, skuAndNameInfo.SpecUnit, 0, skuAndNameInfo.ExPrefix, skuAndNameInfo.ExPrefixBegin, skuAndNameInfo.ExPrefixEnd)
			storeSkuSales.SkuPrice = "N/A"
		} else {
			storeSkuSales.SkuName = "N/A"
			storeSkuSales.SkuPrice = "N/A"
		}
		storeSkuSales.SkuAvgPrice = jxutils.IntPrice2StandardCurrencyString(int64(skusAveragePrice[skuID]))
		storeSkuSales.BadCommentCnt = storeSkuBadCommentCntMap[skuID]
		storeSkuSales.StoreSkuSalesCnt = storeSkuSalesCntMap[skuID]
		storeSkuSales.CitySkuSalesCnt = citySkuSalesCntMap[skuID]
		outStoreSkuSales = append(outStoreSkuSales, storeSkuSales)
	}

	return outStoreSkuSales, err
}
