package orderservice

import (
	"fmt"
	"go-admin/app/admin/models"
	"go-admin/common/const/rediskey"
	"go-admin/common/helper"
	"go-admin/pkg/utility"
	"go-admin/pkg/utility/snowflakehelper"
	"time"

	"github.com/go-admin-team/go-admin-core/logger"
	"github.com/go-admin-team/go-admin-core/sdk/service"
	"github.com/jinzhu/copier"
	"github.com/shopspring/decimal"
	"gorm.io/gorm"
)

type OrderService struct {
	service.Service
}

// 创建减仓后减仓单
func (e *OrderService) CreateReduceReduceOrder(db *gorm.DB, pid int, price, num decimal.Decimal, priceDigit int) (models.LinePreOrder, error) {
	var preOrder models.LinePreOrder
	var result models.LinePreOrder
	var ext models.LinePreOrderExt

	if err := db.Model(&models.LinePreOrder{}).Preload("Childs").Where("id =? ", pid).First(&preOrder).Error; err != nil {
		return preOrder, err
	}

	if err := db.Model(&models.LinePreOrderExt{}).Where("order_id =? ", pid).Find(&ext).Error; err != nil {
		return preOrder, err
	}

	copier.Copy(&result, &preOrder)

	result.Id = 0
	result.OrderSn = utility.Int64ToString(snowflakehelper.GetOrderId())
	result.Status = 0
	result.CreatedAt = time.Now()
	result.TriggerTime = nil
	result.UpdatedAt = time.Now()
	result.BuyPrice = decimal.Zero.String()
	result.Price = price.String()
	result.Num = num.String()
	result.ReduceOrderId = preOrder.Id

	for index := range result.Childs {
		result.Childs[index].Id = 0
		result.Childs[index].OrderSn = utility.Int64ToString(snowflakehelper.GetOrderId())
		result.Childs[index].Status = 0
		result.Childs[index].CreatedAt = time.Now()
		result.Childs[index].TriggerTime = nil
		result.Childs[index].UpdatedAt = time.Now()
		result.Childs[index].BuyPrice = decimal.Zero.String()
		var pricePercent decimal.Decimal

		if result.Childs[index].OrderType == 1 && ext.TakeProfitRatio.Cmp(decimal.Zero) > 0 {
			// 减仓单卖出
			if preOrder.Site == "SELL" {
				pricePercent = decimal.NewFromInt(100).Add(ext.TakeProfitRatio).Div(decimal.NewFromInt(100))
			} else {
				pricePercent = decimal.NewFromInt(100).Sub(ext.TakeProfitRatio).Div(decimal.NewFromInt(100))
			}

		} else if result.Childs[index].OrderType == 2 && ext.StopLossRatio.Cmp(decimal.Zero) > 0 {
			if preOrder.Site == "SELL" {
				pricePercent = decimal.NewFromInt(100).Sub(ext.StopLossRatio).Div(decimal.NewFromInt(100))
			} else {
				pricePercent = decimal.NewFromInt(100).Add(ext.StopLossRatio).Div(decimal.NewFromInt(100))
			}
		}

		//重新计算止盈止损价
		if pricePercent.Cmp(decimal.Zero) > 0 {
			result.Childs[index].Price = price.Mul(pricePercent).Truncate(int32(priceDigit)).String()
		}
	}

	if err := db.Create(&result).Error; err != nil {
		return result, fmt.Errorf("复制减仓单失败：pid:%d err:%v", pid, err)
	}

	return result, nil
}

// 触发主单失败
// preOrderId 主单id
// preOrderItem 触发单缓存内容
func (e *OrderService) ErrorTrigger(preOrderId, symbolType int, exchangeType, preOrderItem string, errData string) error {
	var cacheOrderKey string

	if symbolType == 1 {
		cacheOrderKey = fmt.Sprintf(rediskey.PreSpotOrderList, exchangeType)
	} else {
		cacheOrderKey = fmt.Sprintf(rediskey.PreFutOrderList, exchangeType)
	}

	if _, err := helper.DefaultRedis.LRem(cacheOrderKey, preOrderItem); err != nil {
		logger.Errorf("删除缓存减仓单失败：key:%s item:%s err:%v", cacheOrderKey, preOrderItem, err)
		return err
	}

	if err := e.Orm.Model(&models.LinePreOrder{}).
		Where("id = ? and status =0", preOrderId).
		Updates(map[string]interface{}{
			"status":       2,
			"desc":         errData,
			"trigger_time": time.Now(),
		}).Error; err != nil {
		return err
	}

	return nil
}
