package orderman

import (
	"math"

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

const (
	TotalRate                   = 200 // 总费率（千分之200）= 第三方平台费+京西品牌费+京西服务费，现阶段都是合计200‰
	MaxFreightMoneyFromJxByShop = 7   // 商家自送实际转美团/达达后由商家承担的运费金额上限
)

// 处理正向订单结账信息
func (c *OrderManager) SaveOrderFinancialInfo(order *model.OrderFinancial, operation string) (err error) {
	db := dao.GetDB()
	txDB, _ := dao.Begin(db)
	defer func() {
		if r := recover(); r != nil || err != nil {
			dao.Rollback(db, txDB)
			if r != nil {
				panic(r)
			}
		}
	}()
	if operation == partner.UpdatedPeration {
		// db := orm.NewOrm()
		err = utils.CallFuncLogError(func() error {
			_, err = dao.ExecuteSQL(db, "DELETE FROM order_financial WHERE vendor_order_id = ? AND vendor_id = ?", order.VendorOrderID, order.VendorID)
			return err
		}, "SaveOrderFinancialInfo delete order_financial, orderID:%s", order.VendorOrderID)
		if err != nil {
			return err
		}
		err = utils.CallFuncLogError(func() error {
			_, err = dao.ExecuteSQL(db, "DELETE FROM order_sku_financial WHERE vendor_order_id = ? AND vendor_id = ? AND is_afs_order = 0", order.VendorOrderID, order.VendorID)
			return err
		}, "SaveOrderFinancialInfo delete order_sku_financial, orderID:%s", order.VendorOrderID)
		if err != nil {
			return err
		}
		err = utils.CallFuncLogError(func() error {
			_, err = dao.ExecuteSQL(db, "DELETE FROM order_discount_financial WHERE vendor_order_id = ? AND vendor_id = ?", order.VendorOrderID, order.VendorID)
			return err
		}, "SaveOrderFinancialInfo delete order_discount_financial, orderID:%s", order.VendorOrderID)
		if err != nil {
			return err
		}
	}
	for _, activity := range order.Discounts {
		if err = dao.CreateEntity(db, activity); err != nil {
			if !dao.IsDuplicateError(err) {
				return err
			}
			dao.Rollback(db, txDB)
			return nil
		}
	}
	order.ShopMoneyByCal = order.SalePriceMoney - order.TotalDiscountMoney - order.PointsDeductionMoney + order.PmFreightDiscountMoney - order.DistanceFreightMoney - order.FreightTipsMoney - order.DonationMoney + order.SelfDeliveryDiscountMoney + order.PmSubsidyMoney + order.SkuBoxMoney + order.BoxMoney - order.PmMoney
	order.JxPmMoney = utils.Float64TwoInt64(float64(order.ShopMoney+order.PmMoney)*TotalRate/1000) - order.PmMoney // 京西平台费 = 总金额*20%-第三方平台费
	if order.JxPmMoney < 0 {                                                                                       // 如果算出京西平台费为负数，则置0
		order.JxPmMoney = 0
	}

	order.JxShopMoney = order.ShopMoney - order.JxPmMoney + order.JxSubsidyMoney - order.JxFreightMoneyByShop
	// 订单结算金额拆分计算，拆分到单条sku
	// 先获取订单主体优惠金额
	platOrderGoodsDiscountMoney := order.PmSubsidyMoney - order.PmSkuSubsidyMoney + order.SelfDeliveryDiscountMoney
	// 结算平台扣除项汇总---平台佣金，商家设置运费减免，远距离费，小费，公益捐款、、、、
	deductionsByPm := order.FreightDiscountMoney + order.DistanceFreightMoney + order.FreightTipsMoney + order.DonationMoney + order.PmMoney
	// 结算京西扣除项汇总---京西佣金，京西配送运费
	deductionsByJx := order.JxPmMoney + order.JxFreightMoneyByShop
	for _, sku := range order.Skus[1:] {
		// 用户支付菜品金额，用户为这一条sku支付的菜品金额
		sku.UserMoney = utils.Float64TwoInt64(float64(order.SalePriceMoney-order.DiscountMoney-order.PointsDeductionMoney+order.BoxMoney+order.SkuBoxMoney) * float64(sku.SalePrice*int64(sku.Count)+sku.SkuBoxMoney) / float64(order.SalePriceMoney+order.SkuBoxMoney)) // 林峰确认，比如49-2满减，算餐盒费满49元，不算餐盒费不足49元，是可以参加满减活动的，那么餐盒费也应该和商品金额一起进行折算
		order.Skus[0].UserMoney += sku.UserMoney
		// 计算平台订单主体补贴拆分到单条sku的金额 + sku.PmSubsidyMoneyForSku
		sku.PmSubsidyMoney = sku.PmSkuSubsidyMoney + utils.Float64TwoInt64(float64(platOrderGoodsDiscountMoney*sku.SalePrice*int64(sku.Count)+sku.SkuBoxMoney)/float64(order.SalePriceMoney+order.SkuBoxMoney))
		order.Skus[0].PmSubsidyMoney += sku.PmSubsidyMoney
		// 计算京西满减补贴拆分到单条sku的金额 + sku.JxSubsidyMoneyForSku
		sku.JxSubsidyMoney = sku.JxSkuSubsidyMoney + utils.Float64TwoInt64(float64(order.JxSubsidyMoney-order.PmSkuSubsidyMoney)*float64(sku.SalePrice*int64(sku.Count)+sku.SkuBoxMoney)/float64(order.SalePriceMoney+order.SkuBoxMoney))
		order.Skus[0].JxSubsidyMoney += sku.JxSubsidyMoney
		// 计算单条sku需要承担的平台扣费金额
		sku.PmDeductionsMoney = utils.Float64TwoInt64(float64(deductionsByPm) * (float64(sku.UserMoney + sku.PmSubsidyMoney)) / (float64(order.SalePriceMoney + order.BoxMoney + order.SkuBoxMoney - order.DiscountMoney - order.PointsDeductionMoney + order.PmSubsidyMoney)))
		order.Skus[0].PmDeductionsMoney += sku.PmDeductionsMoney
		// 计算单条sku平台应该结算给京西的金额
		sku.ShopMoneyByCal = sku.UserMoney + sku.PmSubsidyMoney - sku.PmDeductionsMoney
		order.Skus[0].ShopMoneyByCal += sku.ShopMoneyByCal
		// j计算单条sku需要承担的京西扣费金额
		sku.JxDeductionsMoney = utils.Float64TwoInt64(float64(deductionsByJx*sku.ShopMoneyByCal) / float64(order.ShopMoney))
		order.Skus[0].JxDeductionsMoney += sku.JxDeductionsMoney
		// 计算单条sku京西应该结算给商家的金额
		sku.JxShopMoney = sku.ShopMoneyByCal + sku.JxSubsidyMoney - sku.JxDeductionsMoney
		order.Skus[0].JxShopMoney += sku.JxShopMoney
		if sku.SkuID >= math.MaxInt32 {
			sku.SkuID = sku.JxSkuID
		}
		if err = dao.CreateEntity(db, sku); err != nil {
			if !dao.IsDuplicateError(err) {
				return err
			}
			dao.Rollback(db, txDB)
			return nil
		}
	}
	if len(order.Skus) > 0 {
		sku := order.Skus[0]
		if sku.SkuID > math.MaxInt32 {
			sku.SkuID = sku.JxSkuID
		}
		sku.UserMoney = order.SalePriceMoney - order.DiscountMoney - sku.UserMoney
		sku.PmSubsidyMoney = platOrderGoodsDiscountMoney + order.SelfDeliveryDiscountMoney - sku.PmSubsidyMoney
		sku.JxSubsidyMoney = order.JxSubsidyMoney - sku.JxSubsidyMoney
		sku.PmDeductionsMoney = deductionsByPm - sku.PmDeductionsMoney
		sku.ShopMoneyByCal = order.ShopMoney - sku.ShopMoneyByCal
		sku.JxDeductionsMoney = deductionsByJx - sku.JxDeductionsMoney
		sku.JxShopMoney = order.JxShopMoney - sku.JxShopMoney
		if err = dao.CreateEntity(db, sku); err != nil {
			if !dao.IsDuplicateError(err) {
				return err
			}
			dao.Rollback(db, txDB)
			return nil
		}
	} else {
		globals.SugarLogger.Warnf("On SaveOrderSkuFinancialInfo order.VendorOrderID:%s err: order have no sku", order.VendorOrderID)
	}
	// 加上京西对单条sku的补贴，再存数据库
	order.JxSubsidyMoney += order.JxSkuSubsidyMoney
	if err = dao.CreateEntity(db, order); err != nil {
		if !dao.IsDuplicateError(err) {
			return err
		}
		dao.Rollback(db, txDB)
		return nil
	}
	dao.Commit(db, txDB)
	return err
}

// 处理售后订单结账信息
func (c *OrderManager) SaveAfsOrderFinancialInfo(afsOrder *model.AfsOrder) (err error) {
	db := dao.GetDB()
	txDB, _ := dao.Begin(db)
	defer func() {
		if r := recover(); r != nil || err != nil {
			dao.Rollback(db, txDB)
			if r != nil {
				panic(r)
			}
		}
	}()
	// 平台结算扣除汇总--平台补贴，售后产生运费，平台收包装费，同城运费、、、
	deductionsByPm := afsOrder.PmSubsidyMoney + afsOrder.AfsFreightMoney + afsOrder.BoxMoney + afsOrder.TongchengFreightMoney
	afsOrder.RefundMoneyByCal = afsOrder.SkuUserMoney + afsOrder.FreightUserMoney + deductionsByPm - afsOrder.PmRefundMoney
	// order.TotalMoney += order.SkuJxMoney // 退款单京西补贴部分先不作计算
	if err = dao.CreateEntity(db, afsOrder); err != nil {
		if !dao.IsDuplicateError(err) {
			return err
		}
		dao.Rollback(db, txDB)
		return nil
	}

	// 京西结算扣除汇总，先不作计算,计算单条sku最终扣款金额（+该条sku承担的平台结算扣除金额）
	for _, orderSku := range afsOrder.Skus[1:] {
		orderSku.RefundMoneyByCal = orderSku.PmSkuSubsidyMoney +
			utils.Float64TwoInt64(float64(afsOrder.RefundMoneyByCal-afsOrder.PmSkuSubsidyMoney)*float64(orderSku.UserMoney+orderSku.PmSubsidyMoney-orderSku.PmSkuSubsidyMoney)/float64(afsOrder.SkuUserMoney+afsOrder.PmSubsidyMoney-afsOrder.PmSkuSubsidyMoney))
		afsOrder.Skus[0].RefundMoneyByCal += orderSku.RefundMoneyByCal
		if err = dao.CreateEntity(db, orderSku); err != nil {
			if !dao.IsDuplicateError(err) {
				return err
			}
			dao.Rollback(db, txDB)
			return nil
		}
	}
	if len(afsOrder.Skus) > 0 {
		orderSku := afsOrder.Skus[0]
		orderSku.RefundMoneyByCal = afsOrder.RefundMoneyByCal - orderSku.RefundMoneyByCal
		if err = dao.CreateEntity(db, orderSku); err != nil {
			if !dao.IsDuplicateError(err) {
				globals.SugarLogger.Warnf("On SaveAfsOrderFinancialInfo afsOrder.AfsOrderID:%s err: SaveAfsOrderSku is err", afsOrder.AfsOrderID)
				return err
			}
			dao.Rollback(db, txDB)
			return nil
		}
	} else {
		globals.SugarLogger.Warnf("On SaveAfsOrderFinancialInfo afsOrder.AfsOrderID:%s err: afsOrder have no sku", afsOrder.AfsOrderID)
	}
	dao.Commit(db, txDB)
	return err
}

// 转自送实际使用美团/达达配送，调用此方法
func (c *OrderManager) UpdataOrderFinancialInfo(orderFinancial *model.OrderFinancial, wayBill *model.Waybill) (err error) {
	// 通过本地数据库去取是否转美团/达达，并计算运费，写在上级调用函数里面传递过来
	//wayBill, err2 := partner.CurOrderManager.LoadWaybill(orderFinancial.VendorOrderID, orderFinancial.VendorID)
	//if err = err2; err == nil {
	//	orderFinancial.JxFreightMoney = wayBill.DesiredFee
	//}
	db := dao.GetDB()
	txDB, _ := dao.Begin(db)
	defer func() {
		if r := recover(); r != nil || err != nil {
			dao.Rollback(db, txDB)
			if r != nil {
				panic(r)
			}
		}
	}()
	orderFinancial.JxFreightMoney = wayBill.DesiredFee
	if (orderFinancial.JxFreightMoney - orderFinancial.SelfDeliveryDiscountMoney) > MaxFreightMoneyFromJxByShop {
		orderFinancial.JxFreightMoneyByShop = orderFinancial.SelfDeliveryDiscountMoney + MaxFreightMoneyFromJxByShop
	} else if (orderFinancial.JxFreightMoney - orderFinancial.SelfDeliveryDiscountMoney) < 0 {
		orderFinancial.JxFreightMoneyByShop = orderFinancial.SelfDeliveryDiscountMoney
	} else {
		orderFinancial.JxFreightMoneyByShop = orderFinancial.JxFreightMoney
	}
	orderFinancial.JxShopMoney -= orderFinancial.JxFreightMoneyByShop
	// orderFinancial.JxFreightMoneyByShop 的改变直接影响到单条sku的京西结算金额的改变
	jxDecMoney := orderFinancial.JxFreightMoneyByShop
	for _, sku := range orderFinancial.Skus[1:] {
		// 重新计算单条sku京西应该结算的金额
		skuJxDecMoney := utils.Float64TwoInt64(float64(jxDecMoney*sku.SalePrice*int64(sku.Count)+sku.SkuBoxMoney) / float64(orderFinancial.SalePriceMoney+orderFinancial.SkuBoxMoney))
		sku.JxDeductionsMoney += skuJxDecMoney
		sku.JxShopMoney -= skuJxDecMoney
		jxDecMoney -= skuJxDecMoney
		if _, err = dao.UpdateEntity(db, sku); err != nil {
			return err
		}
	}
	if len(orderFinancial.Skus) > 0 {
		sku := orderFinancial.Skus[0]
		sku.JxDeductionsMoney += jxDecMoney
		sku.JxShopMoney -= jxDecMoney
		if _, err = dao.UpdateEntity(db, sku); err != nil {
			return err
		}
	}
	if err = dao.CreateEntity(db, orderFinancial); err != nil {
		return err
	}
	dao.Commit(db, txDB)
	// orderFinancial 和 OrderSkuFinancial 数据计算完毕，准备进行更新
	return err
}
