package dao

import (
	"time"

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

type StatisticsForOrdersExists struct {
	StoreID int `orm:"column(store_id)" json:"storeId"`
}

type StatisticsReportForOrdersList struct {
	StatisticsForOrdersExists
	StoreName              string  `json:"name"`                   //门店名
	OrderCounts            int     `json:"orderCounts"`            //订单数
	SalePrice              int     `json:"salePrice"`              //GMV（售卖价）
	ActualPayPrice         int     `json:"actualPayPrice"`         //实付
	ShopPrice              int     `json:"shopPrice"`              //京西
	DiscountMoney          int     `json:"discountMoney"`          //优惠
	DesiredFee             int     `json:"desiredFee"`             //配送费
	DistanceFreightMoney   int     `json:"distanceFreightMoney"`   //远距离
	WaybillTipMoney        int     `json:"waybillTipMoney"`        //小费
	TotalShopMoney         int     `json:"totalShopMoney"`         //平台结算
	PmSubsidyMoney         int     `json:"pmSubsidyMoney"`         //平台补贴
	EarningPrice           int     `json:"earningPrice"`           //门店收益（预计收益）
	TotalGrossProfit       int     `json:"totalGrossProfit"`       //总毛利
	ComGrossProfit         float32 `json:"comGrossProfit"`         //公司毛利
	CityManagerGrossProfit float32 `json:"cityManagerGrossProfit"` //城市经理毛利
	MarketManName          string  `json:"marketManName"`          //市场负责人
	OperatorName           string  `json:"operatorName"`           //运营负责人
	OperatorName2          string  `json:"operatorName2"`
	OperatorName3          string  `json:"operatorName3"`

	Address  string `json:"address"`
	CityName string `json:"cityName"`
	Status   int    `json:"status"`
	Tel1     string `orm:"size(32);index" json:"tel1"`
}

type PriceReferSnapshotExt struct {
	model.PriceReferSnapshot
	CityName    string `json:"cityName"`
	SkuName     string `json:"skuName"`
	SpecQuality float32
	Unit        string
	SpecUnit    string
}

//查询统计订单信息
func GetStatisticsReportForOrders(db *DaoDB, storeIDs, vendorIDs []int, fromDate time.Time, toDate time.Time, marketPhone, jdPhone, mtPhone, ebaiPhone string) (statisticsReportForOrdersList []*StatisticsReportForOrdersList, err error) {
	sql := `
	SELECT 	
		c.id store_id,
		c.name store_name,
		c.address,
	  	s.order_counts,
		s.sale_price,
		s.actual_pay_price,
		s.shop_price,
		s.discount_money,
		s.desired_fee,
		s.distance_freight_money,
		s.waybill_tip_money,
		s.total_shop_money,
		s.pm_subsidy_money,
		s.earning_price,
		s.total_gross_profit,
		IF(c.jx_brand_fee_factor = 0 AND c.market_add_fee_factor = 0,s.total_gross_profit,(s.total_gross_profit*c.jx_brand_fee_factor)/(c.jx_brand_fee_factor+market_add_fee_factor)) com_gross_profit,
		IF(c.jx_brand_fee_factor = 0 AND c.market_add_fee_factor = 0,0,(s.total_gross_profit*c.market_add_fee_factor)/(c.jx_brand_fee_factor+market_add_fee_factor)) city_manager_gross_profit,
		c.status, c.tel1,
		IF(mm.name <> '', mm.name, mm.user_id2) market_man_name,
		IF(om.name <> '', om.name, om.user_id2) operator_name,
		IF(om2.name <> '', om2.name, om2.user_id2) operator_name2,
		IF(om3.name <> '', om3.name, om3.user_id2) operator_name3,
		p.name city_name
	FROM store c
	LEFT JOIN place p ON p.code = c.city_code
	LEFT JOIN user mm ON mm.mobile <> '' AND mm.mobile = c.market_man_phone 
	LEFT JOIN user om ON om.mobile <> '' AND om.mobile = c.operator_phone 
	LEFT JOIN user om2 ON om2.mobile <> '' AND om2.mobile = c.operator_phone2
	LEFT JOIN user om3 ON om3.mobile <> '' AND om3.mobile = c.operator_phone3
	JOIN
		(
			SELECT ss.*,
				   ss.earning_price1 - IFNULL(ss.afs_shop_price,0) earning_price,
				   ss.total_shop_money1 - IFNULL(ss.afs_total_money,0) total_shop_money,
				   ss.total_gross_profit1 + IFNULL(ss.afs_shop_price,0) - IFNULL(ss.afs_total_money,0) - ss.order_counts*0.8*100 total_gross_profit
			  FROM (
				SELECT
					IF(a.jx_store_id <> 0,a.jx_store_id,a.store_id) store_id,
					COUNT(*) order_counts,
					SUM(a.sale_price) sale_price,
					SUM(a.actual_pay_price) actual_pay_price,
					SUM(a.shop_price) shop_price,
					SUM(a.discount_money) discount_money,
					SUM(b.desired_fee) desired_fee,
					SUM(a.distance_freight_money) distance_freight_money,
					SUM(IF(a.vendor_id = a.waybill_vendor_id,a.waybill_tip_money,0)) waybill_tip_money,
					SUM(a.total_shop_money) total_shop_money1,
					SUM(a.pm_subsidy_money) pm_subsidy_money,
					SUM(IF(a.earning_type = 1, a.earning_price, a.new_earning_price)) earning_price1,
					SUM(a.total_shop_money-IF(a.earning_type = 1, a.earning_price, a.new_earning_price)-b.desired_fee) total_gross_profit1,
					SUM(d.shop_price) afs_shop_price,
					SUM(IF(d.refund_money_by_cal > 0, d.refund_money_by_cal, 0)) afs_total_money
				FROM goods_order a 
				LEFT JOIN waybill b ON IF(a.waybill_vendor_id = -1,a.vendor_order_id,a.vendor_waybill_id) = b.vendor_waybill_id
				LEFT JOIN afs_order c ON c.vendor_order_id = a.vendor_order_id 
				LEFT JOIN order_sku_financial d ON d.afs_order_id = c.afs_order_id AND d.is_afs_order = ? 
				WHERE a.status = ?
	`
	sqlParams := []interface{}{
		model.YES,
		model.OrderStatusFinished,
	}
	if !utils.IsTimeZero(fromDate) && !utils.IsTimeZero(toDate) {
		sql += ` AND a.order_created_at BETWEEN ? AND ?`
		sqlParams = append(sqlParams, fromDate, toDate)
	}
	if len(storeIDs) > 0 {
		sql += ` AND IF(a.jx_store_id != 0, a.jx_store_id, a.store_id) IN(` + GenQuestionMarks(len(storeIDs)) + `)`
		sqlParams = append(sqlParams, storeIDs)
	}
	if len(vendorIDs) > 0 {
		sql += ` AND a.vendor_id IN(` + GenQuestionMarks(len(vendorIDs)) + `)`
		sqlParams = append(sqlParams, vendorIDs)
	}
	sql += `
	GROUP BY 1
	)ss ) s
	ON s.store_id = c.id
	WHERE 1 = 1
	`
	if len(storeIDs) > 0 {
		sql += ` AND c.id IN (` + GenQuestionMarks(len(storeIDs)) + `)`
		sqlParams = append(sqlParams, storeIDs)
	}
	if marketPhone != "" {
		sql += ` AND c.market_man_phone = ?`
		sqlParams = append(sqlParams, marketPhone)
	}
	if jdPhone != "" {
		sql += ` AND c.operator_phone = ?`
		sqlParams = append(sqlParams, jdPhone)
	}
	if mtPhone != "" {
		sql += ` AND c.operator_phone2 = ?`
		sqlParams = append(sqlParams, mtPhone)
	}
	if ebaiPhone != "" {
		sql += ` AND c.operator_phone3 = ?`
		sqlParams = append(sqlParams, ebaiPhone)
	}
	if err = GetRows(db, &statisticsReportForOrdersList, sql, sqlParams...); err == nil {
		return statisticsReportForOrdersList, nil
	}
	return nil, err
}

//查询统计售后单信息
func GetGetStatisticsReportForAfsOrders(db *DaoDB, storeIDs []int, fromDate time.Time, toDate time.Time) (statisticsReportForOrdersList []*StatisticsReportForOrdersList, err error) {
	sql := `
	SELECT 	
		c.id store_id,
		c.name store_name,
	  	s.order_counts,
		s.sale_price,
		s.actual_pay_price,
		s.shop_price,
		s.discount_money,
		s.desired_fee,
		s.distance_freight_money,
		s.waybill_tip_money,
		s.total_shop_money,
		s.pm_subsidy_money,
		s.earning_price,
		s.total_gross_profit,
		IF(c.jx_brand_fee_factor = 0 AND c.market_add_fee_factor = 0,total_gross_profit,(total_gross_profit*c.jx_brand_fee_factor)/(c.jx_brand_fee_factor+market_add_fee_factor)) com_gross_profit,
		IF(c.jx_brand_fee_factor = 0 AND c.market_add_fee_factor = 0,0,(total_gross_profit*c.market_add_fee_factor)/(c.jx_brand_fee_factor+market_add_fee_factor)) city_manager_gross_profit,
		c.status, c.tel1,
		IF(mm.name <> '', mm.name, mm.user_id2) market_man_name,
		IF(om.name <> '', om.name, om.user_id2) operator_name,
		IF(om2.name <> '', om2.name, om2.user_id2) operator_name2,
		IF(om3.name <> '', om3.name, om3.user_id2) operator_name3,
		p.name city_name
	FROM store c
	LEFT JOIN place p ON p.code = c.city_code
	LEFT JOIN user mm ON mm.mobile <> '' AND mm.mobile = c.market_man_phone
	LEFT JOIN user om ON om.mobile <> '' AND om.mobile = c.operator_phone
	LEFT JOIN user om2 ON om2.mobile <> '' AND om2.mobile = c.operator_phone2
	LEFT JOIN user om3 ON om3.mobile <> '' AND om3.mobile = c.operator_phone3
	LEFT JOIN
		(
		SELECT
			IF(a.jx_store_id <> 0,a.jx_store_id,store_id) store_id,
			COUNT(*) order_counts,
			SUM(sale_price) sale_price,
			SUM(actual_pay_price) actual_pay_price,
			SUM(shop_price) shop_price,
			SUM(discount_money) discount_money,
			SUM(afs_freight_money) desired_fee,
			SUM(distance_freight_money) distance_freight_money,
			SUM(IF(a.vendor_id = a.waybill_vendor_id,waybill_tip_money,0)) waybill_tip_money,
			SUM(total_shop_money) total_shop_money,
			SUM(b.pm_subsidy_money) pm_subsidy_money,
			SUM(earning_price) earning_price,
			SUM(total_shop_money-earning_price-afs_freight_money-distance_freight_money-waybill_tip_money-80) total_gross_profit
		FROM goods_order a JOIN afs_order b ON a.vendor_order_id = b.vendor_order_id
		WHERE a.status != ?
	`
	sqlParams := []interface{}{
		model.OrderStatusCanceled, //排除已取消的订单
	}
	if !utils.IsTimeZero(fromDate) && !utils.IsTimeZero(toDate) {
		sql += ` AND a.order_created_at BETWEEN ? AND ?`
		sqlParams = append(sqlParams, fromDate, toDate)
	}
	if len(storeIDs) > 0 {
		sql += ` AND IF(a.jx_store_id != 0, a.jx_store_id, a.store_id) IN(` + GenQuestionMarks(len(storeIDs)) + `)`
		sqlParams = append(sqlParams, storeIDs)
	}
	sql += `
	GROUP BY 1
	)s
	ON s.store_id = c.id
	`
	if len(storeIDs) > 0 {
		sql += ` WHERE c.id IN (` + GenQuestionMarks(len(storeIDs)) + `)`
		sqlParams = append(sqlParams, storeIDs)
	}
	if err = GetRows(db, &statisticsReportForOrdersList, sql, sqlParams...); err == nil {
		return statisticsReportForOrdersList, nil
	}
	return nil, err
}

func GetStatisticsReportForStoreSkusPrice(db *DaoDB, cityCodes, skuIDs []int) (priceReferSnapshot []*model.PriceReferSnapshot, err error) {
	var sql string
	sql1 := `
	SELECT a.sku_id, c.name_id,
	`
	sql2 := `
	MAX(a.jd_price) max_jd_price,
	MIN(a.jd_price) min_jd_price,
	ROUND(AVG(a.jd_price)) avg_jd_price,
	ROUND(SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(a.jd_price ORDER BY a.jd_price),',',Count(1)/2),',',-1),2) mid_jd_price,
	MAX(a.ebai_price) max_ebai_price,
	MIN(a.ebai_price) min_ebai_price,
	ROUND(AVG(a.ebai_price)) avg_ebai_price,
	ROUND(SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(a.ebai_price ORDER BY a.ebai_price),',',Count(1)/2),',',-1),2) mid_ebai_price,
	MAX(a.mtwm_price) max_mtwm_price,
	MIN(a.mtwm_price) min_mtwm_price,
	ROUND(AVG(a.mtwm_price)) avg_mtwm_price,
	ROUND(SUBSTRING_INDEX(SUBSTRING_INDEX(GROUP_CONCAT(a.mtwm_price ORDER BY a.mtwm_price),',',Count(1)/2),',',-1),2) mid_mtwm_price,
	t1.max_sale_price,
	t1.min_sale_price,
	t1.avg_sale_price,
	t1.max_vendor_price,
	t1.min_vendor_price,
	t1.avg_vendor_price
	FROM store_sku_bind a
	JOIN store b ON a.store_id = b.id AND b.deleted_at = ? AND b.status != ?
	JOIN sku c ON a.sku_id = c.id
	LEFT JOIN (
		SELECT SUM(t1.count),t1.sku_id,MAX(t1.sale_price) max_sale_price,MIN(t1.sale_price) min_sale_price,ROUND(AVG(t1.sale_price)) avg_sale_price,MAX(t1.vendor_price) max_vendor_price,MIN(t1.vendor_price) min_vendor_price,ROUND(AVG(t1.vendor_price)) avg_vendor_price
		FROM order_sku t1
		WHERE t1.order_created_at BETWEEN ? AND NOW()
		GROUP BY 2
	)t1 ON t1.sku_id = a.sku_id
	WHERE a.deleted_at = ?
	`
	sql = sql1 + "b.city_code, " + sql2
	sqlParams := []interface{}{
		utils.DefaultTimeValue,
		model.StoreStatusDisabled,
		time.Now().AddDate(0, -1, 0),
		utils.DefaultTimeValue,
	}
	if len(skuIDs) > 0 {
		sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
		sqlParams = append(sqlParams, skuIDs)
	}
	if len(cityCodes) > 0 {
		sql += " AND b.city_code IN (" + GenQuestionMarks(len(cityCodes)) + ")"
		sqlParams = append(sqlParams, cityCodes)
	}
	sql += ` GROUP BY 1,2,3
	UNION `
	sql += sql1 + "0 city_code," + sql2
	if len(skuIDs) > 0 {
		sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
		sqlParams = append(sqlParams, skuIDs)
	}
	if len(cityCodes) > 0 {
		sql += " AND b.city_code IN (" + GenQuestionMarks(len(cityCodes)) + ")"
		sqlParams = append(sqlParams, cityCodes)
	}
	sql += " GROUP BY 1,2"
	sqlParams = append(sqlParams, sqlParams...)
	if err = GetRows(db, &priceReferSnapshot, sql, sqlParams...); err == nil {
		return priceReferSnapshot, nil
	}
	return nil, err
}

func GetPriceReferSnapshot(db *DaoDB, cityCodes, skuIDs []int, skuNameID int, snapDate time.Time, offset, pageSize int) (priceReferSnapshot []*PriceReferSnapshotExt, totalCount int, err error) {
	sql := `
		SELECT SQL_CALC_FOUND_ROWS a.*,IF(a.city_code = 0,'全国',b.name) city_name 
		FROM price_refer_snapshot a
		LEFT JOIN place b ON a.city_code = b.code
		WHERE 1=1
		AND a.deleted_at = ?
	`
	sqlParams := []interface{}{
		utils.DefaultTimeValue,
	}
	if skuNameID > 0 {
		sql += " AND a.name_id = ?"
		sqlParams = append(sqlParams, skuNameID)
	}
	if len(skuIDs) > 0 {
		sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
		sqlParams = append(sqlParams, skuIDs)
	}
	if len(cityCodes) > 0 {
		sql += " AND a.city_code IN (" + GenQuestionMarks(len(cityCodes)) + ")"
		sqlParams = append(sqlParams, cityCodes)
	}
	if !utils.IsTimeZero(snapDate) {
		sql += " AND a.snapshot_at = ?"
		sqlParams = append(sqlParams, snapDate)
	}
	sql += " LIMIT ? OFFSET ?"
	sqlParams = append(sqlParams, pageSize, offset)
	txDB, _ := Begin(db)
	defer Commit(db, txDB)
	if err = GetRowsTx(txDB, &priceReferSnapshot, sql, sqlParams...); err == nil {
		totalCount = GetLastTotalRowCount2(db, txDB)
	}
	for _, v := range priceReferSnapshot {
		skuList, err2 := GetSkus(db, []int{v.SkuID}, nil, nil, nil, nil)
		err = err2
		if len(skuList) > 0 {
			skuAndName := skuList[0]
			jxSkuDetailName := jxutils.ComposeSkuNameOriginal(skuAndName.Prefix, skuAndName.Name, skuAndName.Comment, skuAndName.Unit, skuAndName.SpecQuality, skuAndName.SpecUnit, 0)
			v.SkuName = jxSkuDetailName
		}
	}
	return priceReferSnapshot, totalCount, err
}

func GetPriceReferSnapshotNoPage(db *DaoDB, cityCodes, skuIDs, skuNameIDs []int, snapDate time.Time) (priceReferSnapshot []*model.PriceReferSnapshot, err error) {
	sql := `
		SELECT  a.*
		FROM price_refer_snapshot a
		WHERE 1=1
		AND a.deleted_at = ?
	`
	sqlParams := []interface{}{
		utils.DefaultTimeValue,
	}
	if len(skuNameIDs) > 0 {
		sql += " AND a.name_id IN (" + GenQuestionMarks(len(skuNameIDs)) + ")"
		sqlParams = append(sqlParams, skuNameIDs)
	}
	if len(skuIDs) > 0 {
		sql += " AND a.sku_id IN (" + GenQuestionMarks(len(skuIDs)) + ")"
		sqlParams = append(sqlParams, skuIDs)
	}
	if len(cityCodes) > 0 {
		sql += " AND a.city_code IN (" + GenQuestionMarks(len(cityCodes)) + ")"
		sqlParams = append(sqlParams, cityCodes)
	}
	if !utils.IsTimeZero(snapDate) {
		sql += " AND a.snapshot_at = ?"
		sqlParams = append(sqlParams, snapDate)
	}
	err = GetRows(db, &priceReferSnapshot, sql, sqlParams...)
	return priceReferSnapshot, err
}

func DeletePriceReferHistory(db *DaoDB, snapDate time.Time) (num int64, err error) {
	sql := `
		DELETE FROM price_refer_snapshot 
		WHERE snapshot_at <= ?
	`
	sqlParams := []interface{}{
		snapDate,
	}
	return ExecuteSQL(db, sql, sqlParams...)
}

type UserMemberReportResult struct {
	Mobile            string `json:"mobile"` //电话
	Name              string `json:"name"`   //姓名
	Status            int    `json:"status"` //状态
	VendorID          int    `orm:"column(vendor_id)" json:"vendorID"`
	BuyCount          int    `json:"buyCount"`          //购买次数
	NewPrice          int64  `json:"newPrice"`          //最近订单金额
	FinishedCount     int    `json:"finishedCount"`     //完成订单数
	BuyPrice          int    `json:"buyPrice"`          //购买总金额
	FinishedPrice     int    `json:"finishedPrice"`     //完成订单金额
	GoodsCommentCount int    `json:"goodsCommentCount"` //好评数
	BadCommentCount   int    `json:"badCommentCount"`   //差评数
	CityCode          int    `json:"cityCode"`          // 常住城市
	CityName          string `json:"cityName"`
}
