package udunservice

import (
	"encoding/json"
	log "github.com/go-admin-team/go-admin-core/logger"
	"github.com/shopspring/decimal"
	"go-admin/app/admin/models"
	"go-admin/pkg/timehelper"
	"go-admin/pkg/udunhelper"
	"go-admin/pkg/utility"
	"go.uber.org/zap"
	"gorm.io/gorm"
	"math"
	"strconv"
	"strings"
)

// TradeCallback 充值，提币回调
func TradeCallback(orm *gorm.DB, timestamp, nonce, body, sign string) string {

	log.Error("充值，提币回调返回值", zap.String("body", body), zap.String("timestamp", timestamp), zap.String("nonce", nonce),
		zap.String("sign", sign))

	//验证签名
	sign1 := udunhelper.CheckCallBackSign(timestamp, nonce, body)
	//udunhelper.CheckCallBackSign()
	if sign != sign1 {
		log.Error("充值，提币回调返回值 签名不正确", zap.String("body", body), zap.String("timestamp", timestamp), zap.String("nonce", nonce),
			zap.String("sign", sign))
		return "error"
	}

	// 反序列化
	var trade udunhelper.CallBackRes
	if err := json.Unmarshal([]byte(body), &trade); err != nil {
		return "error"
	}
	// 充值
	if trade.TradeType == 1 {
		//
		return handleRecharge(orm, trade, timestamp)
	} else if trade.TradeType == 2 {
		//提币
		//return handleWithdraw(trade)
	}
	return "success"
}

// 充值回调处理
func handleRecharge(orm *gorm.DB, trade udunhelper.CallBackRes, timestamp string) string {
	// 检测是否已经写入,根据交易Hash判断是否已经存在充值记录
	var charge models.LineRecharge
	err := orm.Model(&models.LineRecharge{}).Where("txid = ?", trade.TxId).Find(&charge).Error
	if err != nil {
		log.Error("GetVtsRechargeByOrderNo", zap.Error(err))
		return "error"
	}

	if charge.Status == "2" {
		// 已经成功，则不继续写入
		log.Error("已经成功，则不继续写入", zap.String("txId", trade.TxId))
		return "error"
	}

	// 充币通知
	amount := getBalance(trade.Amount, trade.Decimals)
	fee := getBalance(trade.Fee, trade.Decimals)
	// 查询钱包信息
	var wallet models.LineWallet
	err = orm.Model(&models.LineWallet{}).Where("address = ?", trade.Address).Find(&wallet).Error
	//wallet, err := walletdb.GetVtsWalletByAddress(trade.Address)
	if err != nil {
		log.Error("GetVtsWalletByAddress", zap.Error(err), zap.String("address", trade.Address))
		return "error"
	}
	// 加载币种信息
	var udCoin models.LineUduncoin
	err = orm.Model(&models.LineUduncoin{}).Where("main_coin_type = ? AND coin_type = ?", trade.MainCoinType, trade.CoinType).Find(&udCoin).Error
	//udCoin, err := uduncoindb.GetVtsUduncoinItemByCoinType(trade.MainCoinType, trade.CoinType)
	if err != nil {
		log.Error("GetVtsUduncoinItemByCoinType", zap.Error(err), zap.String("MainCoinType", trade.MainCoinType),
			zap.String("CoinType", trade.CoinType))
		return "error"
	}
	height := utility.StringAsInteger(trade.BlockHigh)
	//currTime := time.Now()
	status := 1
	switch trade.Status {
	case 0:
		status = 1
	case 1:
		status = 1
	case 2:
		status = 3 // 失败
	case 3:
		status = 2 // 成功
	case 4:
		status = 3 // 失败
	}
	coinCode := udCoin.Symbol
	if strings.EqualFold(coinCode, "TRCUSDT") {
		coinCode = "USDT"
	}
	//coin := coinservice.CoinCache.GetByCode(coinCode)
	//if coin.Id == 0 {
	//	loghelper.Error("TradeCallback 充值，提币回调 未找到系统对应的币种Id", zap.String("udCoin.Symbol", udCoin.Symbol))
	//	return "error"
	//}
	t1 := timehelper.IntToTime(utility.StringAsInt64(timestamp))
	//timehelper.IntToTime()
	// 充值
	recharge := models.LineRecharge{
		UserId:       wallet.UserId,
		Confirms:     strconv.Itoa(0),
		TranType:     strconv.Itoa(1),
		BlockIndex:   strconv.Itoa(height),
		Amount:       utility.FloatToStr(amount),
		Fee:          utility.FloatToStr(fee),
		Account:      "",
		Address:      trade.Address,
		Txid:         trade.TxId,
		BlockTime:    t1,
		TimeReceived: t1,
		MainCoin:     udCoin.MainSymbol,
		OrderNo:      trade.TradeId, // 流水号
		Status:       strconv.Itoa(status),
		State:        strconv.Itoa(trade.Status),
		AddressFrom:  "",
	}
	// 加载账户信息
	//beforeAmount := float64(0)
	//afterAmount := float64(0)
	if trade.Status == 3 {
		tx := orm.Begin()
		err := tx.Model(&models.LineRecharge{}).Create(&recharge).Error
		if err != nil {
			tx.Rollback()
			log.Error("create LineRecharge err", zap.Error(err), zap.String("wallet.UserId", strconv.FormatInt(wallet.UserId, 10)),
				zap.String("money", utility.FloatToStr(amount)))
		}
		err = tx.Model(&models.LineUser{}).Where("id = ?", wallet.UserId).Update("money", gorm.Expr("money + ?", amount)).Error
		if err != nil {
			tx.Rollback()
			log.Error("update user money err", zap.Error(err), zap.String("wallet.UserId", strconv.FormatInt(wallet.UserId, 10)),
				zap.String("money", utility.FloatToStr(amount)))
			return "error"
		}
		tx.Commit()
	}

	//hold := holddb.GetUserHold(wallet.UserId, recharge.CoinId)
	//if hold.Id == 0 {
	//	hold = dbmodel.VtsHold{
	//		Id:         0,
	//		CoinId:     recharge.CoinId,
	//		UserId:     wallet.UserId,
	//		Num:        0,
	//		UseNum:     amount,
	//		FreezeNum:  0,
	//		CreateTime: currTime,
	//		UpdateTime: currTime,
	//	}
	//	beforeAmount = 0
	//	afterAmount = amount
	//} else {
	//	beforeAmount = hold.UseNum
	//	afterAmount = utility.FloatAdd(hold.UseNum, amount)
	//	hold.UseNum = amount
	//	hold.UpdateTime = currTime
	//}
	//// 流水
	//log := dbmodel.VtsCurrentHoldLog{
	//	ID:            0,
	//	UserID:        wallet.UserId,
	//	CoinID:        recharge.CoinId,
	//	UseFree:       1,
	//	DealType:      5,
	//	Remarks:       "优顿充值",
	//	RelateOrderNo: trade.TradeId,
	//	Amount:        amount,
	//	BeforeAmount:  beforeAmount,
	//	AfterAmount:   afterAmount,
	//	Poundage:      fee,
	//	CreateTime:    currTime,
	//}
	//
	//// 开启事务
	//tx, err := dbhelper.MasterPgdb.Beginx()
	//if err != nil {
	//	loghelper.Error("Begin", zap.Error(err))
	//	return "error"
	//}
	//if err = walletdb.RechargeInsert(recharge, tx); err != nil {
	//	_ = tx.Rollback()
	//	return "error"
	//}
	//// 账户写入
	//if trade.Status == 3 {
	//	if err = holddb.UpdateHoldUseNum(hold, tx); err != nil {
	//		_ = tx.Rollback()
	//		return "error"
	//	}
	//	// 流水
	//	if err = holddb.AddCurrentHoldLog(log, tx); err != nil {
	//		_ = tx.Rollback()
	//		loghelper.Error("handleRecharge", zap.Error(err))
	//		return "error"
	//	}
	//}
	//// 提交
	//if err = tx.Commit(); err != nil {
	//	loghelper.Error("Commit", zap.Error(err))
	//	return "error"
	//}
	////保存消息日志
	//templates := cmsdb.GetTempContent(3, 3) //充币通知
	//var template adminmodel.CmsTemplateContentDb
	//if len(templates) > 0 {
	//	template = templates[0]
	//}
	//if template.TemplateId > 0 {
	//	// 写入站内信
	//	store := dbmodel.CmsMessageUserDB{
	//		UserId:      recharge.UserId,
	//		MessageId:   template.TemplateId,
	//		IsRead:      1,
	//		Type:        1,
	//		CreateTime:  time.Now(),
	//		CategoryId:  template.CategoryId,
	//		Content:     strings.ReplaceAll(template.Content, "{num}", " "+utility.FloatToStr(amount)+" "+coinCode),
	//		LittleTitle: template.LittleTitle,
	//	}
	//	err = cmsdb.AddMessageUserItem(store)
	//	if err != nil {
	//		loghelper.Error("AddCmsMessageUser Error:", zap.Error(err))
	//	}
	//}
	return "success"
}

// 提币回调处理
//func handleWithdraw(trade udunhelper.CallBackRes) string {
//	// 提币通知
//	status := 7
//	switch trade.Status {
//	case 0:
//		status = 7
//	case 1:
//		status = 7
//	case 2:
//		status = 9
//	case 3:
//		status = 8
//	case 4:
//		status = 9
//	}
//	if status < 8 {
//		return "success"
//	}
//	// 加载
//	data, err := walletdb.GetWithdrawItemByOrderNo(trade.BusinessId)
//	if err != nil {
//		return "error"
//	}
//	data.Status = status
//	data.State = trade.Status
//	data.TxId = trade.TxId
//	if status == 9 {
//		data.Remark = "未知原因"
//	}
//	num := data.SumNum //utility.FloatAddCut(data.Num, data.NumFee, 8)
//	// 更新这个表的状态
//	tx, err := dbhelper.MasterPgdb.Beginx()
//	if err != nil {
//		loghelper.Error("Begin", zap.Error(err))
//		return "error"
//	}
//	err = walletdb.WithdrawStatusByUd(data, tx)
//	if err != nil {
//		_ = tx.Rollback()
//		return "error"
//	}
//	if status == 9 {
//		//如果失败则把资金重新返回给用户,减去相应的冻结资金
//		err = holddb.UpdateHoldWithdraw(num, -num, data.UserId, data.CoinId, tx)
//		if err != nil {
//			_ = tx.Rollback()
//			return "error"
//		}
//	} else {
//		//成功的话则减去相应的冻结资金
//		err = holddb.UpdateHoldWithdraw(0, -num, data.UserId, data.CoinId, tx)
//		if err != nil {
//			_ = tx.Rollback()
//			return "error"
//		}
//	}
//	_ = tx.Commit()
//
//	//保存消息日志
//	templates := cmsdb.GetTempContent(4, 3) // 提币通知
//	var template adminmodel.CmsTemplateContentDb
//	if len(templates) > 0 {
//		template = templates[0]
//	}
//	if template.TemplateId > 0 {
//		coin := coinservice.CoinCache.GetById(data.CoinId)
//		// 写入站内信
//		store := dbmodel.CmsMessageUserDB{
//			UserId:      data.UserId,
//			MessageId:   template.TemplateId,
//			IsRead:      1,
//			Type:        1,
//			CreateTime:  time.Now(),
//			CategoryId:  template.CategoryId,
//			Content:     strings.ReplaceAll(template.Content, "{num}", " "+utility.FloatToStr(data.Num)+" "+coin.CoinCode),
//			LittleTitle: template.LittleTitle,
//		}
//		err = cmsdb.AddMessageUserItem(store)
//		if err != nil {
//			loghelper.Error("AddCmsMessageUser Error:", zap.Error(err))
//		}
//	}
//	return "success"
//}

// getBalance 获取金额
func getBalance(balance, decimals string) float64 {
	am, _ := strconv.ParseFloat(balance, 64)
	dec, _ := strconv.ParseFloat(decimals, 64)
	res := decimal.NewFromFloat(am / math.Pow(10, dec))
	amount, _ := res.Truncate(8).Float64()
	return amount
}
