package com.bizzan.bitrade.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bizzan.bitrade.constant.CommonStatus;
import com.bizzan.bitrade.constant.TransactionType;
import com.bizzan.bitrade.constant.WalletType;
import com.bizzan.bitrade.entity.*;
import com.bizzan.bitrade.entity.transform.AuthMember;
import com.bizzan.bitrade.service.*;
import com.bizzan.bitrade.util.HttpClientUtil;
import com.bizzan.bitrade.util.HttpSend;
import com.bizzan.bitrade.util.MessageResult;
import com.sparkframework.lang.Convert;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import javax.persistence.EntityManager;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.bizzan.bitrade.constant.SysConstant.SESSION_MEMBER;

@Api(value = "AssetController" , tags = "用户资产接口")
@RestController
@RequestMapping("/asset")
@Slf4j
public class AssetController {
    @Autowired
    private MemberWalletService walletService;
    @Autowired
    private CoinService coinService;
    @Autowired
    private WalletTransRecordService walletTransRecordService;
    @Autowired
    private MemberTransactionService transactionService;
    @Value("${gcx.match.max-limit:1000}")
    private double gcxMatchMaxLimit;
    @Value("${gcx.match.each-limit:5}")
    private double gcxMatchEachLimit;
    @Autowired
    private KafkaTemplate kafkaTemplate;

    @Autowired
    private QuickExchangeService quickExchangeService;
    @Autowired
    private LocaleMessageSourceService sourceService;

    @Autowired
    private MemberService memberService;
    @Autowired
    private MemberWalletService memberWalletService;
    @Autowired
    private ExchangeWalletService exchangeWalletService;

    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private MemberDepositService memberDepositService;
    @Autowired
	private UserPurseService userPurseService;
    @Autowired
    private FollowWalletService followWalletService;
    @Autowired
	private RedisLock redisLock;
    @Autowired
    private RedissonClient redisson;
    @Autowired
    private EntityManager entityManager;
    @Autowired
    private SysConfigService sysConfigService;
    @Autowired
    private BalanceService balanceService;

    @Value("${swap.service.url:http://127.0.0.1:6012}")
    private String swapServiceUrl;

    /**
     * 用户钱包信息
     *
     * @param member
     * @return
     */
    @ApiOperation(value="获取所有资产账户钱包", notes="获取所有资产账户钱包")
    @PostMapping("wallet")
    public MessageResult findWallet(@SessionAttribute(SESSION_MEMBER) AuthMember member) {
    	/*String validateUrl = "http://127.0.0.1:6020/address/asset/wallet/li720d7e?memberId="+member.getId();
    	String response = HttpClientUtil.get(validateUrl, null, null);
    	log.info("validateUrl={}, response={}", validateUrl, response);
    	JSONObject json = JSON.parseObject(response, JSONObject.class);
    	final List<MemberWalletAddressBackup> addressList;
    	if(json.get("data")!=null) {
    		addressList = JSON.parseArray(json.get("data").toString(), MemberWalletAddressBackup.class);
    	} else {
    		addressList = null;
    	}*/
    	
        List<MemberWallet> wallets = walletService.findAllByMemberId(member.getId());
    	//List<MemberWallet> wallets = invokeUtil.listWallet(member.getId());
        List<MemberWallet> retList = new ArrayList<MemberWallet>();
        wallets.forEach(wallet -> {
        	if(wallet.getCoin()!=null && wallet.getCoin().getStatus() == CommonStatus.NORMAL)
        		retList.add(wallet);
        	
        	wallet.getCoin().setUsdRate(1.0);
            wallet.getCoin().setCnyRate(6.42);
            // 生成Memo
            //String address = this.getAddress(wallet.getCoin().getUnit(), addressList);
            //wallet.setAddress(address);
            //wallet.getCoin().setDepositAddress(address);
            wallet.getCoin().setColdWalletAddress(""); // 对前端隐藏冷钱包地址
        });
    	//List<MemberWallet> retList = InnerInvokeUtil.listWallet(member.getId());
        MessageResult mr = MessageResult.success("success");
        mr.setData(retList);
        return mr;
    }
    
    @ApiOperation(value="获取USDT钱包", notes="获取USDT钱包")
    @PostMapping("wallet/usdt")
    public MessageResult findUsdtWallet(@SessionAttribute(SESSION_MEMBER) AuthMember member) {
        MessageResult mr = MessageResult.success("success");
        mr.setData(balanceService.getMemberWalletVo(member.getId()));
        return mr;
    }

    /**
     * 查询特定类型的记录
     *
     * @param member
     * @param pageNo
     * @param pageSize
     * @param type
     * @return
     */
    //@PostMapping("transaction")
    public MessageResult findTransaction(@SessionAttribute(SESSION_MEMBER) AuthMember member, int pageNo, int pageSize, TransactionType type) {
        MessageResult mr = new MessageResult();
        mr.setData(transactionService.queryByMember(member.getId(), pageNo, pageSize, type));
        mr.setCode(0);
        mr.setMessage("success");
        return mr;
    }
    
    @ApiOperation(value="查询充提记录", notes="查询充提记录")
    @PostMapping("rechargeAndWithdraw")
    public MessageResult findRechargeAndWithdraw(@SessionAttribute(SESSION_MEMBER) AuthMember member, int pageNo, int pageSize) {
        MessageResult mr = new MessageResult();
        List<TransactionType> types = new ArrayList<>();
        types.add(TransactionType.RECHARGE);
        types.add(TransactionType.WITHDRAW);
        mr.setData(transactionService.queryByMemberAndTypes(member.getId(), pageNo, pageSize,types));
        mr.setCode(0);
        mr.setMessage("success");
        return mr;
    }
    
    @ApiOperation(value="获取充值列表", notes="获取充值列表")
    @GetMapping("recharge-list")
    public MessageResult findMemberDepositByMemberId(@SessionAttribute(SESSION_MEMBER) AuthMember member, int pageNo, int pageSize) {
    	MessageResult mr = new MessageResult();
    	mr.setData(memberDepositService.queryByMemberId(member.getId(), pageNo, pageSize));
    	mr.setCode(0);
        mr.setMessage("success");
        return mr;
    }
    
    @ApiOperation(value="获取充值明细", notes="获取充值明细")
    @ApiImplicitParams(value = {
    		@ApiImplicitParam(name = "id",value = "明细ID",required = true ,dataType = "long")
    })
    @GetMapping("recharge-detail")
    public MessageResult findMemberDepositById(@SessionAttribute(SESSION_MEMBER) AuthMember member, Long id) {
    	MessageResult mr = new MessageResult();
    	mr.setData(memberDepositService.findById(id));
    	mr.setCode(0);
        mr.setMessage("success");
        return mr;
    }
    
    private TransactionTypeVo getTransactionTypeVo(int index) {
    	TransactionTypeVo vo = new TransactionTypeVo();
        vo.setIndex(index);
        TransactionType transactionType = TransactionType.valueOfOrdinal(index);
        vo.setTypeName(transactionType.name());
        vo.setName(sourceService.getMessage("TRANSACTION_TYPE_"+transactionType.name()));
        return vo;
    }
    
    @ApiOperation(value="获取资金流水类型", notes="获取资金流水类型")
    @GetMapping("transaction/type")
    public MessageResult findTransactionType(@SessionAttribute(SESSION_MEMBER) AuthMember member) throws ParseException {
        MessageResult mr = new MessageResult();
        List<TransactionTypeVo> list = new ArrayList<>();
        list.add(getTransactionTypeVo(0));
        list.add(getTransactionTypeVo(1));
        list.add(getTransactionTypeVo(2));
        //list.add(getTransactionTypeVo(10));
        list.add(getTransactionTypeVo(19));
        list.add(getTransactionTypeVo(20));
        list.add(getTransactionTypeVo(21));
        list.add(getTransactionTypeVo(25));
        list.add(getTransactionTypeVo(26));
        list.add(getTransactionTypeVo(37));
        list.add(getTransactionTypeVo(38));
        list.add(getTransactionTypeVo(39));
        list.add(getTransactionTypeVo(40));
        list.add(getTransactionTypeVo(41));
        list.add(getTransactionTypeVo(42));
        list.add(getTransactionTypeVo(8));
        list.add(getTransactionTypeVo(47));
        SysConfig sysConfig = sysConfigService.get();
    	if(sysConfig.getEnableExchange() == 1) {
	        list.add(getTransactionTypeVo(43));
	        list.add(getTransactionTypeVo(44));
	        list.add(getTransactionTypeVo(45));
	        list.add(getTransactionTypeVo(46));
    	}
        mr.setCode(0);
        mr.setMessage("success");
        mr.setData(list);
        return mr;
    }
    
    @ApiOperation(value="获取资金流水币种", notes="获取资金流水币种")
    @GetMapping("transaction/coin")
    public MessageResult findTransactionCoin(@SessionAttribute(SESSION_MEMBER) AuthMember member) throws ParseException {
        MessageResult mr = new MessageResult();
        List<Coin> transactionAll = coinService.findTransactionAll();
        mr.setCode(0);
        mr.setMessage("success");
        mr.setData(transactionAll);
        return mr;
    }

    /**
     * 查询所有记录
     *
     * @param member
     * @param pageNo
     * @param pageSize
     * @return
     */
    /** 现货类流水类型（用于 excludeSpot 过滤） */
    private static final List<TransactionType> SPOT_TYPES = java.util.Arrays.asList(
        TransactionType.SPOT_PROFIT,
        TransactionType.SPOT_LOSS,
        TransactionType.SPOT_FEE,
        TransactionType.SPOT_AWARD,
        TransactionType.SPOT
    );

    @ApiOperation(value="查询资金流水", notes="查询资金流水")
    @ApiImplicitParams(value = {
    		@ApiImplicitParam(name = "startTime",value = "开始时间",required = false,dataType = "String"),
    		@ApiImplicitParam(name = "endTime",value = "结束时间",required = false,dataType = "String"),
    		@ApiImplicitParam(name = "symbol",value = "币种代码",required = false,dataType = "String"),
    		@ApiImplicitParam(name = "type",value = "流水类型",required = false,dataType = "String"),
    		@ApiImplicitParam(name = "excludeSpot",value = "是否过滤现货流水：1=过滤 0=不过滤（默认0）",required = false,dataType = "int")
    })
    @PostMapping("transaction/all")
    public MessageResult findTransaction(@SessionAttribute(SESSION_MEMBER) AuthMember member, HttpServletRequest request, int pageNo, int pageSize,
                                         @RequestParam(value = "startTime",required = false)  String startTime,
                                         @RequestParam(value = "endTime",required = false)  String endTime,
                                         @RequestParam(value = "symbol",required = false)  String symbol,
                                         @RequestParam(value = "type",required = false)  String type,
                                         @RequestParam(value = "excludeSpot",required = false,defaultValue = "0")  int excludeSpot) throws ParseException {
        MessageResult mr = new MessageResult();
        log.info("[transaction/all] type={} excludeSpot={} symbol={} startTime={} endTime={} pageNo={} pageSize={}", type, excludeSpot, symbol, startTime, endTime, pageNo, pageSize);
        TransactionType transactionType = null;
        if (StringUtils.isNotEmpty(type)) {
            int typeOrdinal = Convert.strToInt(type, -1);
            transactionType = typeOrdinal >= 0 ? TransactionType.valueOfOrdinal(typeOrdinal) : null;
            log.info("[transaction/all] typeOrdinal={} transactionType={}", typeOrdinal, transactionType);
        }
        // excludeSpot=1 时排除现货相关流水类型
        List<TransactionType> excludeTypes = (excludeSpot == 1) ? SPOT_TYPES : null;
        Page<MemberTransaction> page = transactionService.queryByMember(member.getId(), pageNo, pageSize, transactionType, startTime, endTime, symbol, excludeTypes);
        for(MemberTransaction memberTransaction : page.getContent()) {
        	int typeOrdinal = memberTransaction.getType().getOrdinal();
        	if((typeOrdinal>=19 && typeOrdinal<=26) || (typeOrdinal >= 37) || (typeOrdinal == 8)) {
        		memberTransaction.setSymbol(memberTransaction.getSymbol()+" 永续");
        	}
        }

        mr.setCode(0);
        mr.setMessage("success");
        mr.setData(page);
        return mr;
    }
    
    @ApiOperation(value="获取划转记录", notes="获取划转记录")
    @ApiImplicitParams(value = {
    		@ApiImplicitParam(name = "startTime",value = "开始时间",required = true,dataType = "String"),
    		@ApiImplicitParam(name = "endTime",value = "结束时间",required = true ,dataType = "String"),
    		@ApiImplicitParam(name = "from",value = "钱包转出类型",required = true ,dataType = "String"),
    		@ApiImplicitParam(name = "to",value = "钱包转入类型",required = true ,dataType = "String")
    })
    @PostMapping("transfer/list")
    public MessageResult findWalletTrans(@SessionAttribute(SESSION_MEMBER) AuthMember member, HttpServletRequest request, int pageNo, int pageSize,
                                         @RequestParam(value = "startTime",required = false)  String startTime,
                                         @RequestParam(value = "endTime",required = false)  String endTime,
                                         @RequestParam(value = "from",required = false)  String from,
                                         @RequestParam(value = "to",required = false)  String to) throws ParseException {
        MessageResult mr = new MessageResult();
        WalletType fromWalletType = null;
        if (StringUtils.isNotEmpty(from)) {
        	fromWalletType = WalletType.valueOfStr(from);
        }
        WalletType toWalletType = null;
        if (StringUtils.isNotEmpty(to)) {
        	toWalletType = WalletType.valueOfStr(to);
        }
        mr.setCode(0);
        mr.setMessage("success");
        mr.setData(walletTransRecordService.queryByMember(member.getId(), pageNo, pageSize, fromWalletType, toWalletType, startTime, endTime));
        return mr;
    }

    @ApiOperation(value="获取单币种资产钱包", notes="获取单币种资产钱包信息")
    @PostMapping("wallet/{symbol}")
    public MessageResult findWalletBySymbol(@SessionAttribute(SESSION_MEMBER) AuthMember member, @PathVariable String symbol) {
        MessageResult mr = MessageResult.success("success");
        mr.setData(walletService.findByCoinUnitAndMemberId(symbol, member.getId()));
        //mr.setData(invokeUtil.fineWallet(member.getId(), symbol));
        return mr;
    }
    
    @ApiOperation(value="验证充值地址", notes="验证充值地址(已弃用)")
    @PostMapping("wallet/validate-address")
    public MessageResult validateWalletAddress(@SessionAttribute(SESSION_MEMBER) AuthMember member, String unit, String address) {
    	return MessageResult.success();
    }

    @ApiOperation(value="重置充值地址", notes="重置充值地址")
    @PostMapping("wallet/reset-address")
    public MessageResult resetWalletAddress(@SessionAttribute(SESSION_MEMBER) AuthMember member, String unit) {
    	//return MessageResult.error(500, "钱包系统升级中，暂停充币业务！");
    	
    	try {
        	if(unit.equals("USDT")) {
        		unit = "EUSDT";
        		MemberWallet mw = walletService.findByCoinUnitAndMemberId(unit, member.getId());
        		//MemberWallet mw = invokeUtil.fineWallet(member.getId(), unit);
            	//if(mw.getCoin().getAccountType() == 0 && StringUtils.isEmpty(mw.getAddress())) {
        		if(StringUtils.isEmpty(mw.getAddress())) {
    	            JSONObject json = new JSONObject();
    	            json.put("uid", member.getId());
    	            kafkaTemplate.send("reset-member-address", unit, json.toJSONString());
            	}
        		unit = "TUSDT";
        		MemberWallet mw1 = walletService.findByCoinUnitAndMemberId(unit, member.getId());
        		//MemberWallet mw = invokeUtil.fineWallet(member.getId(), unit);
            	//if(mw.getCoin().getAccountType() == 0 && StringUtils.isEmpty(mw.getAddress())) {
        		if(StringUtils.isEmpty(mw1.getAddress())) {
    	            JSONObject json = new JSONObject();
    	            json.put("uid", member.getId());
    	            kafkaTemplate.send("reset-member-address", unit, json.toJSONString());
            	}
            	unit = "USDT-BEP20";
        	}
        	MemberWallet mw = walletService.findByCoinUnitAndMemberId(unit, member.getId());
    		//MemberWallet mw = invokeUtil.fineWallet(member.getId(), unit);
        	//if(mw.getCoin().getAccountType() == 0 && StringUtils.isEmpty(mw.getAddress())) {
        	if(StringUtils.isEmpty(mw.getAddress())) {
	            JSONObject json = new JSONObject();
	            json.put("uid", member.getId());
	            kafkaTemplate.send("reset-member-address", unit, json.toJSONString());
	            return MessageResult.success();
        	}else {
        		return MessageResult.error(sourceService.getMessage("GET_ADDRESS_SUCCESS"));
        	}
        } catch (Exception e) {
            return MessageResult.error(sourceService.getMessage("UNKNOWN_ERROR"));
        }
    }
    
    @ApiOperation(value="重置充值地址", notes="重置充值地址")
    @PostMapping("wallet/address")
    public MessageResult walletAddress(@SessionAttribute(SESSION_MEMBER) AuthMember member, String unit, javax.servlet.http.HttpServletRequest request) {
    	//return MessageResult.error(500, "钱包系统升级中，暂停充币业务！");
    	List<MemberWallet> rechargeWallets = walletService.findRechargeByMemberId(member.getId());

    	boolean success = true;
    	
    	for (MemberWallet wallet : rechargeWallets) {
    		if (wallet.getAddress() == null || wallet.getAddress().trim().length() == 0) {
    			JSONObject json = new JSONObject();
	            json.put("uid", member.getId());
	            kafkaTemplate.send("reset-member-address", wallet.getCoin().getName(), json.toJSONString());
	            success = false;
    		}
    	}
    	
    	int counter = 0;
    	while (!success && counter<5) {
    		success = true;
    		counter ++;
    		try {
				Thread.sleep(1000L);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    		entityManager.clear();
    		rechargeWallets = walletService.findRechargeByMemberId(member.getId());
    		for (MemberWallet wallet : rechargeWallets) {
    			if (wallet.getAddress() == null || wallet.getAddress().trim().length() == 0) {
    				success = false;
    			}
    		}
    	}
    	MessageResult<List<MemberWallet>> mr = MessageResult.success("success");
        mr.setData(rechargeWallets);
        return mr;
    	
    }
    
    
    public MessageResult<BigDecimal> getCurrectBalance(@SessionAttribute(SESSION_MEMBER) AuthMember member, HttpServletRequest request) {
    	MemberWallet memberWallet = walletService.findByCoinAndMemberId(coinService.findByUnit("USDT"), member.getId());
    	BigDecimal totalBalance = memberWallet.getBalance().add(memberWallet.getFrozenBalance());
    	
    	String authToken = request.getHeader("x-auth-token");
    	String serviceName = "contract-swap-api";
        String swapUrl = "http://" + serviceName + "/swap/wallet-new/get?x-auth-token="+authToken;

        log.info("swapUrl={}", swapUrl);
        
        String response = HttpClientUtil.get(swapUrl, null, null);
        log.info("response={}", response);
		JSONObject json = JSON.parseObject(response);
		BigDecimal swapBalance = json.getJSONObject("data").getBigDecimal("currentBalance");
        log.info("swapBalance={}", swapBalance);
        totalBalance = totalBalance.add(swapBalance);
        
        String followUrl = "http://" + serviceName + "/swap/follow-wallet/get?x-auth-token="+authToken;

        response = HttpClientUtil.get(followUrl, null, null);
        log.info("response={}", response);
		JSONObject followJson = JSON.parseObject(response);
		BigDecimal followBalance = followJson.getJSONObject("data").getBigDecimal("currentBalance");
        log.info("followBalance={}", followBalance);
        totalBalance = totalBalance.add(followBalance);
    	
    	MessageResult<BigDecimal> mr = MessageResult.success("success");
        mr.setData(totalBalance);
        return mr;
    }
    
    @ApiOperation(value="获取钱包列表", notes="获取钱包列表")
    @GetMapping("wallets")
    public MessageResult<List<WalletVo>> get(@SessionAttribute(SESSION_MEMBER) AuthMember member) {
    	List<WalletVo> list = new ArrayList<WalletVo>();
    	
    	MemberWallet memberWallet = walletService.findByCoinAndMemberId(coinService.findByUnit("USDT"), member.getId());
    	WalletVo cashVo = new WalletVo();
    	cashVo.setWalletType(WalletType.SPOT);
    	cashVo.setName(sourceService.getMessage("CASH_ACCOUNT_NAME"));
    	cashVo.setBalance(memberWallet.getBalance());
    	list.add(cashVo);

    	UserPurse userPurse = userPurseService.findOne(member.getId());
    	WalletVo tradingVo = new WalletVo();
    	tradingVo.setWalletType(WalletType.SWAP);
    	tradingVo.setName(sourceService.getMessage("TRADING_ACCOUNT_NAME"));
    	tradingVo.setBalance(userPurse.getBalance());
    	list.add(tradingVo);

    	FollowWallet followWallet = followWalletService.findOne(member.getId());
    	WalletVo followVo = new WalletVo();
    	followVo.setWalletType(WalletType.FOLLOW);
    	followVo.setName(sourceService.getMessage("FOLLOW_ACCOUNT_NAME"));
    	followVo.setBalance(followWallet.getBalance());
    	list.add(followVo);

    	SysConfig sysConfig = sysConfigService.get();
    	if(sysConfig.getEnableExchange() == 1) {
	    	ExchangeWallet exchangeWallet = exchangeWalletService.findUsdtWallet(member.getId());
	    	WalletVo exchangewVo = new WalletVo();
	    	exchangewVo.setWalletType(WalletType.EXCHANGE);
	    	exchangewVo.setName(sourceService.getMessage("EXCHANGE_ACCOUNT_NAME"));
	    	exchangewVo.setBalance(exchangeWallet.getBalance());
	    	list.add(exchangewVo);
    	}
    	
    	MessageResult<List<WalletVo>> mr = MessageResult.success("success");
        mr.setData(list);
        return mr;
    }
    
    @ApiOperation(value="划转资金", notes="划转资金")
	@ApiImplicitParams(value = {
    		@ApiImplicitParam(name = "from",value = "钱包转出类型",required = true ,dataType = "String"),
    		@ApiImplicitParam(name = "to",value = "钱包转入类型",required = true ,dataType = "String"),
    		@ApiImplicitParam(name = "amount",value = "划转金额",required = true ,dataType = "float")
    })
	@PostMapping("transfer")
	public MessageResult transfer(@SessionAttribute(SESSION_MEMBER) AuthMember authMember,
			@RequestHeader("x-auth-token")String token,
			@RequestHeader("lang")String lang,
			@RequestHeader(value = "x-app-version", required = false) String appVersion,
			@RequestHeader(value = "x-app-platform", required = false) String appPlatform,
			@RequestParam(value = "from") WalletType from,// 从那个类型的钱包转出
            @RequestParam(value = "to") WalletType to,// 转入那个类型的钱包
            @RequestParam(value = "amount") BigDecimal amount) {
		Member member = memberService.findOne(authMember.getId());
		if(member == null) {
            return MessageResult.error(sourceService.getMessage("REQUEST_OF_ILLEGAL"));
        }
		if(amount.compareTo(BigDecimal.ZERO)<=0)
			return MessageResult.error(sourceService.getMessage("REQUEST_OF_ILLEGAL"));

		if(from == WalletType.SWAP || to == WalletType.SWAP) {
	        String marketUrl = swapServiceUrl + "/swap/wallet-new/transfer";

	        Map<String, String> params = new HashMap<>();
        	params.put("x-auth-token", token);
        	params.put("lang", lang);
        	if(appVersion != null) params.put("x-app-version", appVersion);
        	if(appPlatform != null) params.put("x-app-platform", appPlatform);
        	params.put("amount", amount.toString());
        	if(from == WalletType.SPOT && to == WalletType.SWAP) {
        		params.put("type", "0");
	        } else {
	        	params.put("type", "1");
	        }
        	String result = HttpSend.post(marketUrl, params);
        	MessageResult messageResult = new MessageResult(JSONObject.parseObject(result));
        	return messageResult;
	        /*if(from == WalletType.SPOT && to == WalletType.SWAP) {// 从 币币钱包 划转到 合约钱包
	        	if(!redisLock.waitTradingAccountLock(member.getId()))
	        		return MessageResult.error(sourceService.getMessage("TRANSFER_FAILED"));
	        	
	        	try {
		            MemberWallet oriWalletFrom = walletService.findByCoinUnitAndMemberId("USDT", member.getId());
		        	//MemberWallet walletFrom = invokeUtil.fineWallet(member.getId(), "USDT");
		        	//MemberContractWallet walletTo = memberContractWalletService.findOne(toWalletId);
		
		            if(oriWalletFrom.getBalance().compareTo(amount) < 0) {
		                return MessageResult.error(sourceService.getMessage("WALLET_NOT_AMOUNT_OUT"));
		            }
		            walletService.deductBalance(oriWalletFrom, amount);
		            userPurseService.transferIn(member.getId(), amount);
	        	} catch (Exception e) {
					//log.error(e.getMessage(), e);
				} finally {
					redisLock.unlockTradingAccount(member.getId());
				}
	
	            //通知钱包变更
	            kafkaTemplate.send("trading-account-change", member.getId()+"");
	
	        }else if(from == WalletType.SWAP && to == WalletType.SPOT) {// 从 合约钱包 划转到 币币钱包
	        	UserPurse userPurse = userPurseService.findOne(member.getId());
	        	if(userPurse.getCurrentPositionList().size()>0) {
	            	return MessageResult.error(sourceService.getMessage("TRANSFER_WITH_POSITION"));
	            }
	            MemberWallet walletTo = walletService.findByCoinUnitAndMemberId("USDT", member.getId());
	            
	            if (userPurse.getBalance().compareTo(amount) < 0) {
	                return MessageResult.error(sourceService.getMessage("WALLET_NOT_AMOUNT_OUT"));
	            }
	            if(userPurseService.transferOut(member.getId(), amount))
	            	walletService.increaseBalance(walletTo.getId(), amount);
	                
	            //通知钱包变更
	            
	            kafkaTemplate.send("trading-account-change", member.getId()+"");
	
	        }*/
		} else if(from == WalletType.FOLLOW || to == WalletType.FOLLOW) {
			String marketUrl = swapServiceUrl + "/swap/follow-wallet/";

	        Map<String, String> params = new HashMap<>();
        	params.put("x-auth-token", token);
        	params.put("lang", lang);
        	if(appVersion != null) params.put("x-app-version", appVersion);
        	if(appPlatform != null) params.put("x-app-platform", appPlatform);
        	params.put("amount", amount.toString());
        	if(from == WalletType.SPOT) {
        		marketUrl += "transfer-in";
	        } else {
	        	marketUrl += "transfer-out";
	        }
        	String result = HttpSend.post(marketUrl, params);
	        log.info(result);
	        MessageResult messageResult = new MessageResult(JSONObject.parseObject(result));
        	return messageResult;
			/*if(from == WalletType.SPOT && to == WalletType.FOLLOW) {
	        	MemberWallet oriWalletFrom = walletService.findByCoinUnitAndMemberId("USDT", member.getId());
	        	
	            if(oriWalletFrom.getBalance().compareTo(amount) < 0) {
	                return MessageResult.error(sourceService.getMessage("WALLET_NOT_AMOUNT_OUT"));
	            }
	            walletService.deductBalance(oriWalletFrom, amount);
	            followWalletService.transferIn(member.getId(), amount);
	            
	            kafkaTemplate.send("follow-account-change", member.getId()+"");
	            kafkaTemplate.send("trading-account-change", member.getId()+"");
	        }else if(from == WalletType.FOLLOW && to == WalletType.SPOT) {
	        	FollowWallet gollowWallet = followWalletService.findOne(member.getId());
	        	if(gollowWallet.getCurrentPositionList().size()>0) {
	            	return MessageResult.error(sourceService.getMessage("TRANSFER_WITH_POSITION"));
	            }
	        	
	            MemberWallet walletTo = walletService.findByCoinUnitAndMemberId("USDT", member.getId());
	            
	            if (gollowWallet.getBalance().compareTo(amount) < 0) {
	                return MessageResult.error(sourceService.getMessage("WALLET_NOT_AMOUNT_OUT"));
	            }
	            if(followWalletService.transferOut(member.getId(), amount))
	            	walletService.increaseBalance(walletTo.getId(), amount);
	            kafkaTemplate.send("follow-account-change", member.getId()+"");
	            kafkaTemplate.send("trading-account-change", member.getId()+"");
	        }*/
		}else if(from == WalletType.EXCHANGE || to == WalletType.EXCHANGE) {
			String lockKey = member.getId() + "_USDT-updateWallet";
			RLock lock = redisson.getLock(lockKey);
			lock.lock(3, TimeUnit.SECONDS);
			//if(!redisLock.lockBySeconds(lockKey, 3)) {
			//	return error(sourceService.getMessage("FREQUENTLY_REQUEST"));
			//}
			if(from == WalletType.SPOT && to == WalletType.EXCHANGE) {
	        	MemberWallet oriWalletFrom = walletService.findByCoinUnitAndMemberId("USDT", member.getId());
	        	
	            if(oriWalletFrom.getBalance().compareTo(amount) < 0) {
	                return MessageResult.error(sourceService.getMessage("WALLET_NOT_AMOUNT_OUT"));
	            }
	            if(walletService.deductBalance(oriWalletFrom, amount)>0) {
	            	ExchangeWallet exchangeWallet = exchangeWalletService.findUsdtWallet(member.getId());
	            	exchangeWalletService.transferIn(exchangeWallet.getId(), amount);
		            kafkaTemplate.send("trading-account-change", member.getId()+"");
		            kafkaTemplate.send("exchange-account-change", member.getId()+"");
	            }
	            
	        }else if(from == WalletType.EXCHANGE && to == WalletType.SPOT) {
	        	ExchangeWallet exchangeWallet = exchangeWalletService.findUsdtWallet(member.getId());
	        	
	            MemberWallet walletTo = walletService.findByCoinUnitAndMemberId("USDT", member.getId());
	            
	            if (exchangeWallet.getBalance().compareTo(amount) < 0) {
	                return MessageResult.error(sourceService.getMessage("WALLET_NOT_AMOUNT_OUT"));
	            }
	            if(exchangeWalletService.transferOut(exchangeWallet.getId(), amount))
	            	walletService.increaseBalance(walletTo.getId(), amount);
	            kafkaTemplate.send("trading-account-change", member.getId()+"");
	            kafkaTemplate.send("exchange-account-change", member.getId()+"");
	        }
			lock.unlock();
			WalletTransRecord record = new WalletTransRecord();
	        record.setAmount(amount);
	        record.setUnit("USDT");
	        record.setSource(from);
	        record.setTarget(to);
	        record.setMemberId(member.getId());
	        walletTransRecordService.save(record);
			MessageResult result = MessageResult.success("success");
	        return result;
		}else{
            return MessageResult.error(sourceService.getMessage("NO_IN_OUT_WALLET"));
        }
	}
    
    @ApiOperation(value="卖币", notes="卖币")
	@ApiImplicitParams(value = {
    		@ApiImplicitParam(name = "amount",value = "金额",required = true ,dataType = "float")
    })
	//@PostMapping("sell")
	public MessageResult sell(@SessionAttribute(SESSION_MEMBER) AuthMember authMember,
			@RequestParam(value = "amount") BigDecimal amount) {
		Member member = memberService.findOne(authMember.getId());
		if(member == null) {
            return MessageResult.error(sourceService.getMessage("REQUEST_OF_ILLEGAL"));
        }
		if(amount.compareTo(BigDecimal.ZERO)<=0)
			return MessageResult.error(sourceService.getMessage("REQUEST_OF_ILLEGAL"));
		
		MemberWallet memberWallet = memberWalletService.findByMemberId(authMember.getId());
		MessageResult result = memberWalletService.freezeBalance(memberWallet, amount);
        if (result.getCode() != 0) {
        	return MessageResult.error(sourceService.getMessage("INSUFFICIENT_BALANCE"));
        }
		
        return MessageResult.success();
    }
}
