package cms

import (
	"git.rosy.net.cn/baseapi/utils"
	"git.rosy.net.cn/jx-callback/business/jxutils/jxcontext"
	"git.rosy.net.cn/jx-callback/business/jxutils/smsmsg"
	"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"
	"git.rosy.net.cn/jx-callback/globals/api"
)

type StoreAcctManager struct {
}

var (
	FixedStoreAcctManager *StoreAcctManager
)

func init() {
	FixedStoreAcctManager = &StoreAcctManager{}
	partner.InitStoreAcctManager(FixedStoreAcctManager)
}

func (s *StoreAcctManager) InsertStoreAcctIncome(ctx *jxcontext.Context, storeID, price, acctType int, vendorOrderID string, expendID int) (err error) {
	var (
		userID, userName   string
		goodsVendorOrderID string
		db                 = dao.GetDB()
	)
	if ctx != nil {
		userID = ctx.GetUserID()
		userName = ctx.GetUserName()
		goodsVendorOrderID = vendorOrderID
	} else {
		storeOrder := &model.StoreAcctOrder{
			VendorOrderID: vendorOrderID,
		}
		if err = dao.GetEntity(db, storeOrder, "VendorOrderID"); err == nil && storeOrder.ID != 0 {
			userID = storeOrder.UserID
			userName = storeOrder.LastOperator
			goodsVendorOrderID = storeOrder.GoodsVendorOrderID
		}
	}
	storeAcctIncome := &model.StoreAcctIncome{
		StoreID:       storeID,
		IncomePrice:   price,
		Type:          acctType,
		UserID:        userID,
		VendorOrderID: goodsVendorOrderID,
	}
	dao.WrapAddIDCULEntity(storeAcctIncome, userName)
	if expendID != 0 {
		storeAcctIncome.ExpID = expendID
	}
	err = dao.CreateEntity(db, storeAcctIncome)
	globals.SugarLogger.Debugf("InsertStoreAcctIncome orderID: [%v] , price :[%v] , type :[%v]", vendorOrderID, price, acctType)
	return err
}

func (s *StoreAcctManager) InsertStoreAcctExpend(ctx *jxcontext.Context, storeID, price, acctType int, vendorOrderID string, expendID int) (err error) {
	var (
		userID, userName string
		db               = dao.GetDB()
	)
	if ctx != nil {
		userID = ctx.GetUserID()
		userName = ctx.GetUserName()
	} else {
		storeOrder := &model.StoreAcctOrder{
			VendorOrderID: vendorOrderID,
		}
		if err = dao.GetEntity(db, storeOrder, "VendorOrderID"); err == nil && storeOrder.ID != 0 {
			userID = storeOrder.UserID
			userName = storeOrder.LastOperator
		}
	}
	storeAcctExpend := &model.StoreAcctExpend{
		StoreID:       storeID,
		ExpendPrice:   price,
		Type:          acctType,
		UserID:        userID,
		VendorOrderID: vendorOrderID,
	}
	dao.WrapAddIDCULEntity(storeAcctExpend, userName)
	if expendID != 0 {
		storeAcctExpend.ExpID = expendID
	}
	err = dao.CreateEntity(db, storeAcctExpend)
	globals.SugarLogger.Debugf("InsertStoreAcctExpend orderID: [%v] , price :[%v] , type :[%v]", vendorOrderID, price, acctType)
	return err
}

func (s *StoreAcctManager) UpdateStoreAcctBalance(ctx *jxcontext.Context, storeID, price int, isIncome bool) (err error) {
	var (
		db = dao.GetDB()
	)
	globals.SugarLogger.Debugf("UpdateStoreAcctBalance storeID: [%v] , price :[%v] ,", storeID, price)
	if ctx == nil {
		ctx = jxcontext.AdminCtx
	}
	storeAcct := &model.StoreAcct{
		StoreID: storeID,
	}
	txDB, _ := dao.Begin(db)
	defer func() {
		if r := recover(); r != nil || err != nil {
			dao.Rollback(db, txDB)
			if r != nil {
				panic(r)
			}
		}
	}()
	if err = dao.GetEntity(db, storeAcct, "StoreID"); err != nil && dao.IsNoRowsError(err) {
		//新增门店账单
		dao.WrapAddIDCULEntity(storeAcct, ctx.GetUserName())
		if err = dao.CreateEntityTx(txDB, storeAcct); err != nil {
			dao.Rollback(db, txDB)
			return err
		}
	} else {
		globals.SugarLogger.Debugf("UpdateStoreAcctBalance1 storeID: [%v] , balance :[%v] ,", storeID, storeAcct.AccountBalance)
		if isIncome {
			storeAcct.AccountBalance += price
		} else {
			storeAcct.AccountBalance -= price
		}
		if _, err = dao.UpdateEntityTx(txDB, storeAcct, "AccountBalance"); err != nil {
			dao.Rollback(db, txDB)
			return err
		}
		globals.SugarLogger.Debugf("UpdateStoreAcctBalance2 storeID: [%v] , balance :[%v] ,", storeID, storeAcct.AccountBalance)
	}
	dao.Commit(db, txDB)
	return err
}

// 门店到账
func (s *StoreAcctManager) InsertStoreAcctExpendAndUpdateStoreAcctBalance(ctx *jxcontext.Context, storeID, price, acctType int, vendorOrderID string, expendID int) (err error) {
	utils.CallFuncAsync(func() {
		if err = s.InsertStoreAcctExpend(ctx, storeID, price, acctType, vendorOrderID, expendID); err == nil {
			s.UpdateStoreAcctBalance(ctx, storeID, price, false)
		}
	})
	return err
}

func (s *StoreAcctManager) InsertStoreAcctIncomeAndUpdateStoreAcctBalance(ctx *jxcontext.Context, storeID, price, acctType int, vendorOrderID string, expendID int) (err error) {
	utils.CallFuncAsync(func() {
		if err = s.InsertStoreAcctIncome(ctx, storeID, price, acctType, vendorOrderID, expendID); err == nil {
			s.UpdateStoreAcctBalance(ctx, storeID, price, true)
		}
	})
	return err
}

// 检查当前订单的状态以及支出收入比
func (s *StoreAcctManager) CheckStoreAcctExpendExist(vendorOrderID string) (isEqual, isZero bool, err error) {
	var (
		expends, incomes int
		db               = dao.GetDB()
	)
	globals.SugarLogger.Debugf("CheckStoreAcctExpendExist orderID:[%v]", vendorOrderID)
	expends, err = dao.GetStoreAcctExpendTotal(db, 0, []int{partner.StoreAcctTypeExpendCreateWaybillEx, partner.StoreAcctTypeRealFeeExpend}, vendorOrderID, utils.ZeroTimeValue, utils.ZeroTimeValue)
	incomes, err = dao.GetStoreAcctIncomeTotal(db, 0, []int{partner.StoreAcctTypeRealFeeIncome, partner.StoreAcctTypeIncomeCancelTemp, partner.StoreAcctTypeIncomeCancelReal}, vendorOrderID, utils.ZeroTimeValue, utils.ZeroTimeValue)
	if expends != incomes {
		if expends > incomes {
			return false, false, err
		} else {
			globals.SugarLogger.Debugf("CheckStoreAcctExpendExist 收入大于支出！ orderID:[%v]", vendorOrderID)
		}
	} else {
		if expends == 0 && incomes == 0 {
			return true, true, err
		} else {
			return true, false, err
		}
	}
	return false, false, err
}

func (s *StoreAcctManager) GetStoreAcctExpendLastCreateWayBillFee(vendorOrderID string) (expend *dao.GetStoreAcctExpendLastCreateWayBillFeeResult, lastFee int, err error) {
	return dao.GetStoreAcctExpendLastCreateWayBillFee(dao.GetDB(), vendorOrderID)
}

func (s *StoreAcctManager) GetBrandBalance(brandID int) (balance int, err error) {
	return dao.GetBrandBalance(dao.GetDB(), brandID)
}

func (s *StoreAcctManager) InsertBrandBill(ctx *jxcontext.Context, brandID, price, billType, feeType int, vendorOrderID string) (err error) {
	utils.CallFuncAsync(func() {
		var (
			db = dao.GetDB()
		)
		if price == 0 {
			globals.SugarLogger.Debugf("InsertBrandBill failed price is 0, brandID: %d, vendorOrderID: %s", brandID, vendorOrderID)
			return
		}
		brandBill := &model.BrandBill{
			BrandID:       brandID,
			Price:         price,
			BillType:      billType,
			FeeType:       feeType,
			VendorOrderID: vendorOrderID,
		}
		dao.WrapAddIDCULEntity(brandBill, ctx.GetUserName())
		//扣除后，如果余额小于10元要发消息通知 ,每天通知一次
		if err = dao.CreateEntity(db, brandBill); err == nil {
			if mark := api.Cacher.Get("brandID" + utils.Int2Str(brandID)); mark == nil {
				if balance, _ := s.GetBrandBalance(brandID); balance < model.BrandBalanceLimit {
					smsmsg.NotifyBrandBalance(brandID)
				}
			}
		}
	})
	return err
}
