package binanceservice

import (
	"errors"
	"time"

	"github.com/shopspring/decimal"
)

// OrderPlacementService 币安现货下单
type OrderPlacementService struct {
	ApiId            int             `json:"api_id"`           //api_id
	Symbol           string          `json:"symbol"`           //交易对
	Side             string          `json:"side"`             //购买方向
	Type             string          `json:"type"`             //下单类型 MARKET=市价 LIMIT=限价 TAKE_PROFIT_LIMIT=限价止盈 STOP_LOSS_LIMIT=限价止损
	TimeInForce      string          `json:"timeInForce"`      // 订单有效期，默认为 GTC (Good Till Cancelled)
	Price            decimal.Decimal `json:"price"`            //限价单价
	Quantity         decimal.Decimal `json:"quantity"`         //下单数量
	NewClientOrderId string          `json:"newClientOrderId"` //系统生成的订单号
	StopPrice        decimal.Decimal `json:"stopprice"`        //止盈止损时需要
	Rate             string          `json:"rate"`             //下单百分比
}

func (s *OrderPlacementService) CheckParams() error {

	if s.ApiId == 0 || s.Symbol == "" || s.Type == "" || s.NewClientOrderId == "" || s.Side == "" || s.Quantity.LessThan(decimal.Zero) {
		return errors.New("缺失下单必要参数")
	}

	if s.Type == "LIMIT" && s.Price.LessThanOrEqual(decimal.Zero) {
		return errors.New("缺失限价单参数price")
	}
	if s.Type == "TAKE_PROFIT_LIMIT" || s.Type == "STOP_LOSS_LIMIT" {
		if s.StopPrice.LessThanOrEqual(decimal.Zero) {
			return errors.New("缺失止盈止损订单参数stopprice")
		}
	}
	return nil
}

// CancelOpenOrdersReq 撤销单一交易对的所有挂单
type CancelOpenOrdersReq struct {
	ApiId  int    `json:"api_id"` //api_id
	Symbol string `json:"symbol"` //交易对
}

func (r *CancelOpenOrdersReq) CheckParams() error {
	if r.Symbol == "" {
		return errors.New("缺失下单必要参数")
	}
	return nil
}

// EntryPriceResult 计算均价结果
type EntryPriceResult struct {
	TotalNum   decimal.Decimal `json:"total_num"`   //总数量
	EntryPrice decimal.Decimal `json:"entry_price"` //均价
	FirstPrice decimal.Decimal `json:"first_price"` //主单的下单价格
	TotalMoney decimal.Decimal `json:"total_money"` //总金额（U）
	FirstId    int             `json:"first_id"`    //主单id
}

type FutOrderPlace struct {
	ApiId            int             `json:"api_id"`     //api用户id
	Symbol           string          `json:"symbol"`     //合约交易对
	Side             string          `json:"side"`       //购买方向
	Quantity         decimal.Decimal `json:"quantity"`   //数量
	Price            decimal.Decimal `json:"price"`      //限价单价
	SideType         string          `json:"side_type"`  //现价或者市价
	OpenOrder        int             `json:"open_order"` //是否开启限价单止盈止损
	Profit           decimal.Decimal `json:"profit"`     //止盈价格
	StopPrice        decimal.Decimal `json:"stopprice"`  //止损价格
	OrderType        string          `json:"order_type"` //订单类型，市价或限价MARKET(市价单) TAKE_PROFIT_MARKET（市价止盈） TAKE_PROFIT(限价止盈) STOP (限价止损)  STOP_MARKET（市价止损）
	NewClientOrderId string          `json:"newClientOrderId"`
}

func (s FutOrderPlace) CheckParams() error {
	if s.ApiId == 0 || s.Symbol == "" || s.OrderType == "" || s.NewClientOrderId == "" || s.Side == "" || s.Quantity.LessThan(decimal.Zero) {
		return errors.New("缺失下单必要参数")
	}
	if s.OrderType == "LIMIT" && s.Price.LessThan(decimal.Zero) {
		return errors.New("缺失限价单参数price")
	}
	if s.OrderType == "TAKE_PROFIT_MARKET" || s.OrderType == "STOP_MARKET" {
		if s.StopPrice.LessThanOrEqual(decimal.Zero) || s.Profit.LessThanOrEqual(decimal.Zero) {
			return errors.New("缺失止盈止损订单参数stopprice")
		}
	}
	return nil
}

// PositionRisk 用户持仓风险
type PositionRisk struct {
	Symbol                 string `json:"symbol"`
	PositionSide           string `json:"positionSide"`
	PositionAmt            string `json:"positionAmt"`
	EntryPrice             string `json:"entryPrice"`
	BreakEvenPrice         string `json:"breakEvenPrice"`
	MarkPrice              string `json:"markPrice"`
	UnRealizedProfit       string `json:"unRealizedProfit"`
	LiquidationPrice       string `json:"liquidationPrice"`
	IsolatedMargin         string `json:"isolatedMargin"`
	Notional               string `json:"notional"`
	MarginAsset            string `json:"marginAsset"`
	IsolatedWallet         string `json:"isolatedWallet"`
	InitialMargin          string `json:"initialMargin"`
	MaintMargin            string `json:"maintMargin"`
	PositionInitialMargin  string `json:"positionInitialMargin"`
	OpenOrderInitialMargin string `json:"openOrderInitialMargin"`
	Adl                    int    `json:"adl"`
	BidNotional            string `json:"bidNotional"`
	AskNotional            string `json:"askNotional"`
	UpdateTime             int64  `json:"updateTime"`
}
type FutOrderResp struct {
	ClientOrderId           string `json:"clientOrderId"`
	CumQty                  string `json:"cumQty"`
	CumQuote                string `json:"cumQuote"`
	ExecutedQty             string `json:"executedQty"`
	OrderId                 int    `json:"orderId"`
	AvgPrice                string `json:"avgPrice"`
	OrigQty                 string `json:"origQty"`
	Price                   string `json:"price"`
	ReduceOnly              bool   `json:"reduceOnly"`
	Side                    string `json:"side"`
	PositionSide            string `json:"positionSide"`
	Status                  string `json:"status"`
	StopPrice               string `json:"stopPrice"`
	ClosePosition           bool   `json:"closePosition"`
	Symbol                  string `json:"symbol"`
	TimeInForce             string `json:"timeInForce"`
	Type                    string `json:"type"`
	OrigType                string `json:"origType"`
	ActivatePrice           string `json:"activatePrice"`
	PriceRate               string `json:"priceRate"`
	UpdateTime              int64  `json:"updateTime"`
	WorkingType             string `json:"workingType"`
	PriceProtect            bool   `json:"priceProtect"`
	PriceMatch              string `json:"priceMatch"`
	SelfTradePreventionMode string `json:"selfTradePreventionMode"`
	GoodTillDate            int64  `json:"goodTillDate"`
}

type HoldeData struct {
	Id                     int             `json:"id"` //主单id
	UpdateTime             time.Time       `json:"updateTime" comment:"最后更新时间"`
	Type                   string          `json:"type" comment:"1-现货 2-合约"`
	Symbol                 string          `json:"symbol"`
	AveragePrice           decimal.Decimal `json:"averagePrice" comment:"均价"`
	Side                   string          `json:"side" comment:"持仓方向"`
	TotalQuantity          decimal.Decimal `json:"totalQuantity" comment:"持仓数量"`
	TotalBuyPrice          decimal.Decimal `json:"totalBuyPrice" comment:"总购买金额"`
	PositionIncrementCount int             `json:"positionIncrementCount"` //加仓次数
	HedgeCloseCount        int             `json:"hedgeCloseCount" comment:"对冲平仓数量"`
	TriggerStatus          int             `json:"triggerStatus" comment:"触发状态 平仓之后重置 0-未触发 1-触发中 2-触发完成"`
	PositionStatus         int             `json:"positionStatus" comment:"加仓状态 0-未开始 1-未完成 2-已完成 3-失败"`
}

// OpenOrders 挂单信息
type OpenOrders struct {
	AvgPrice                string `json:"avgPrice"`                // 平均成交价
	ClientOrderId           string `json:"clientOrderId"`           // 用户自定义的订单号
	CumQuote                string `json:"cumQuote"`                // 成交金额
	ExecutedQty             string `json:"executedQty"`             // 成交量
	OrderId                 int    `json:"orderId"`                 // 系统订单号
	OrigQty                 string `json:"origQty"`                 // 原始委托数量
	OrigType                string `json:"origType"`                // 触发前订单类型
	Price                   string `json:"price"`                   // 委托价格
	ReduceOnly              bool   `json:"reduceOnly"`              // 是否仅减仓
	Side                    string `json:"side"`                    // 买卖方向
	PositionSide            string `json:"positionSide"`            // 持仓方向
	Status                  string `json:"status"`                  // 订单状态
	StopPrice               string `json:"stopPrice"`               // 触发价，对`TRAILING_STOP_MARKET`无效
	ClosePosition           bool   `json:"closePosition"`           // 是否条件全平仓
	Symbol                  string `json:"symbol"`                  // 交易对
	Time                    int64  `json:"time"`                    // 订单时间
	TimeInForce             string `json:"timeInForce"`             // 有效方法
	Type                    string `json:"type"`                    // 订单类型
	ActivatePrice           string `json:"activatePrice"`           // 跟踪止损激活价格, 仅`TRAILING_STOP_MARKET` 订单返回此字段
	PriceRate               string `json:"priceRate"`               // 跟踪止损回调比例, 仅`TRAILING_STOP_MARKET` 订单返回此字段
	UpdateTime              int64  `json:"updateTime"`              // 更新时间
	WorkingType             string `json:"workingType"`             // 条件价格触发类型
	PriceProtect            bool   `json:"priceProtect"`            // 是否开启条件单触发保护
	PriceMatch              string `json:"priceMatch"`              //price match mode
	SelfTradePreventionMode string `json:"selfTradePreventionMode"` //self trading preventation mode
	GoodTillDate            int    `json:"goodTillDate"`            //order pre-set auot cancel time for TIF GTD order
}

// SpotAccountInfo 现货账户信息
type SpotAccountInfo struct {
	MakerCommission  int `json:"makerCommission"`
	TakerCommission  int `json:"takerCommission"`
	BuyerCommission  int `json:"buyerCommission"`
	SellerCommission int `json:"sellerCommission"`
	CommissionRates  struct {
		Maker  string `json:"maker"`
		Taker  string `json:"taker"`
		Buyer  string `json:"buyer"`
		Seller string `json:"seller"`
	} `json:"commissionRates"`
	CanTrade                   bool   `json:"canTrade"`
	CanWithdraw                bool   `json:"canWithdraw"`
	CanDeposit                 bool   `json:"canDeposit"`
	Brokered                   bool   `json:"brokered"`
	RequireSelfTradePrevention bool   `json:"requireSelfTradePrevention"`
	PreventSor                 bool   `json:"preventSor"`
	UpdateTime                 int    `json:"updateTime"`
	AccountType                string `json:"accountType"`
	Balances                   []struct {
		Asset  string `json:"asset"`
		Free   string `json:"free"`
		Locked string `json:"locked"`
	} `json:"balances"`
	Permissions []string `json:"permissions"`
	Uid         int      `json:"uid"`
}
