package forex

import (
	"context"
	"encoding/json"
	"github.com/redis/go-redis/v9"
	"matchmaking-system/internal/biz/structure"
	"matchmaking-system/internal/data/memory"
	"matchmaking-system/internal/pkg/flags"
	"matchmaking-system/internal/pkg/logging/applogger"
	"matchmaking-system/internal/pkg/logging/common"
	"matchmaking-system/internal/pkg/setting"
)

/*
处理外汇下单交易(订单状态:0-挂单(委托),1-持仓订单,2-已撤单,3-完成订单)
1>写入挂单缓存列表
2>监控挂单缓存列表
3>监控持仓缓存列表
4>处理完成订单
5>清理缓存列表
*/

// ForexTallyCache
// @Description:
type ForexTallyCache struct {
	UserId       int64                // 用户ID
	OrderId      string               // 订单ID
	Symbol       string               // 交易对
	Status       string               // 订单状态
	OpenPrice    string               // 开仓价格
	ClosingPrice string               // 平仓价格
	Order        structure.ForexOrder // 下单信息
}

// ForexCacheDeal
//
//	@Description:
//	@param ctx
//	@param userId
//	@param orderId
//	@param priceNew
//	@param order
//	@return string
//	@return *ForexTallyCache
//	@return error
func ForexCacheDeal(ctx context.Context, userId int64, orderId, priceNew string, order structure.ForexOrder) (string, *ForexTallyCache, error) {
	var marketStatus string
	tallyCache := &ForexTallyCache{
		UserId:  userId,        // 下单用户ID
		OrderId: orderId,       // 下单订单ID
		Symbol:  order.ForexId, // 下单交易对
		Status:  flags.Entrust, // 下单挂单状态
		Order:   order,         // 完整下单信息
	}

	switch order.DealType {
	case flags.DealTypeLimited: // 限价(买涨|买跌)
		marketStatus = setting.MarketForexEntrust
	case flags.DealTypeMarket: // 市价(买涨|买跌)
		tallyCache.OpenPrice = priceNew            // 市价下单开仓价格(price)
		tallyCache.Status = flags.Position         // 市价下单持仓状态(status)
		marketStatus = setting.MarketForexPosition // (挂单|持仓)缓存列表
	}

	return marketStatus, tallyCache, nil
}

// ForexSubMarketPrice
//
//	@Description: 下单订阅行情数据
//	@param ctx
//	@param subKey
//	@return string
//	@return error
func ForexSubMarketPrice(ctx context.Context, subKey string) (string, error) {
	price, err := memory.GetForexCache(subKey)
	if err != nil {
		return flags.SetNull, err
	}

	return string(price), nil
}

// ForexPushAddCache
//
//	@Description: 下单录入(挂单|持仓)缓存列表
//	@param red
//	@param cacheKey
//	@param tallyCache
//	@return error
func ForexPushAddCache(red *redis.Client, cacheKey string, tallyCache *ForexTallyCache) error {
	content, err := json.Marshal(tallyCache)
	if err != nil {
		return err
	}

	if err = red.HSet(context.Background(), cacheKey, tallyCache.OrderId, string(content)).Err(); err != nil {
		return err
	}

	return nil
}

// ForexHashSetOrderId
//
//	@Description: 录入订单ID-Hash缓存列表
//	@param red
//	@param cacheKey
//	@param order
//	@return error
func ForexHashSetOrderId(red *redis.Client, cacheKey string, order *ForexTallyCache) error {
	byteStr, err := json.Marshal(order)
	if err != nil {
		applogger.Error("%v ForexHashSetOrderId.Marshal:%v", common.ErrForex, err)
		return err
	}

	err = red.HSet(context.Background(), cacheKey, order.OrderId, string(byteStr)).Err()
	if err != nil {
		applogger.Error("%v ForexHashSetOrderId.HSet:%v", common.ErrForex, err)
		return err
	}

	return nil
}