package com.bizzan.bitrade.controller;

import com.bizzan.bitrade.constant.WalletType;
import com.bizzan.bitrade.engine.ContractCoinMatch;
import com.bizzan.bitrade.engine.ContractCoinMatchFactory;
import com.bizzan.bitrade.entity.*;
import com.bizzan.bitrade.entity.transform.AuthMember;
import com.bizzan.bitrade.service.*;
import com.bizzan.bitrade.util.MessageResult;
import com.bizzan.bitrade.vo.MemberContractWalletWithCut;

import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

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

//@Api(description="合约信息")
//@Slf4j
//@RestController
//@RequestMapping("/wallet")
public class MemberContractWalletController {
    @Autowired
    private MemberContractWalletService memberContractWalletService;

    @Autowired
    private LocaleMessageSourceService msService;

    @Autowired
    private MemberService memberService;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private ContractCoinService contractCoinService;

    @Autowired
    private ContractCoinMatchFactory contractCoinMatchFactory; // 合约引擎工厂

    @Autowired
    private ContractOrderEntrustService contractOrderEntrustService;

    /**
     * 查询所有合约账户
     *
     * @param authMember
     * @return
     */
    @RequestMapping("list")
    public MessageResult getWalletList(@SessionAttribute(SESSION_MEMBER) AuthMember authMember) {
        Member member = memberService.findOne(authMember.getId());
        if(member == null) {
            return MessageResult.error(500, msService.getMessage("ACCOUNT_NOT_EXIST"));
        }
        List<MemberContractWallet> list = memberContractWalletService.findAllByMemberId(authMember.getId());
        if(list == null) {
            return MessageResult.error(500, msService.getMessage("CONTRACT_ACCOUNT_NOT_EXIST"));
        }

        //String serviceName = "bitrade-market";
        //String url = "http://" + serviceName + "/market/exchange-rate/usd-cny";
        //ResponseEntity<MessageResult> retResult = restTemplate.getForEntity(url, MessageResult.class);
        BigDecimal rate = BigDecimal.valueOf(6.42);
        //if (retResult.getStatusCode().value() == 200 && retResult.getBody().getCode() == 0) {
        //    rate = new BigDecimal((Double) retResult.getBody().getData());
        //}

        List<MemberContractWallet> retList = new ArrayList<MemberContractWallet>();
        // 计算账户权益
        for (MemberContractWallet wallet : list) {
        	if (wallet==null || wallet.getContractCoin()==null || wallet.getContractCoin().getEnable()!=1)
        		continue;
        	ContractCoinMatch contractCoinMatch = contractCoinMatchFactory.getContractCoinMatch(wallet.getContractCoin().getSymbol());
            if (contractCoinMatch==null)
            	continue;
            
        	retList.add(wallet);
        	BigDecimal currentPrice = contractCoinMatch.getNowPrice();
            // 计算金本位权益（多仓 + 空仓）
            BigDecimal usdtTotalProfitAndLoss = BigDecimal.ZERO;
            // 多仓计算方法：（当前价格 / 开仓均价 - 1）* （可用仓位 + 冻结仓位） * 合约面值
            if(wallet.getUsdtBuyPrice().compareTo(BigDecimal.ZERO) > 0) {
                usdtTotalProfitAndLoss = usdtTotalProfitAndLoss.add(currentPrice.divide(wallet.getUsdtBuyPrice(), 8, BigDecimal.ROUND_HALF_DOWN).subtract(BigDecimal.ONE).multiply(wallet.getUsdtBuyPosition().add(wallet.getUsdtFrozenBuyPosition())).multiply(wallet.getUsdtShareNumber()));
            }

            // 空仓计算方法：（1 - 当前价格 / 开仓均价）* （可用仓位 + 冻结仓位） * 合约面值
            if(wallet.getUsdtSellPrice().compareTo(BigDecimal.ZERO) > 0) {
                usdtTotalProfitAndLoss = usdtTotalProfitAndLoss.add(BigDecimal.ONE.subtract(currentPrice.divide(wallet.getUsdtSellPrice(),8, BigDecimal.ROUND_HALF_DOWN)).multiply(wallet.getUsdtSellPosition().add(wallet.getUsdtFrozenSellPosition())).multiply(wallet.getUsdtShareNumber()));
            }

            wallet.setUsdtTotalProfitAndLoss(usdtTotalProfitAndLoss);
            wallet.getContractCoin().setCurrentPrice(currentPrice);
            wallet.getContractCoin().setUsdtRate(rate);
            wallet.getContractCoin().setName(wallet.getContractCoin().getCoinSymbol()+" "+msService.getMessage("SWAP_NAME"));
        }

        MessageResult result = MessageResult.success("success");
        result.setData(retList);
        return result;
    }
    
    @RequestMapping("listWithCut")
    public MessageResult getWalletListWithCut(@SessionAttribute(SESSION_MEMBER) AuthMember authMember) {
        Member member = memberService.findOne(authMember.getId());
        if(member == null) {
            return MessageResult.error(500, msService.getMessage("ACCOUNT_NOT_EXIST"));
        }
        List<MemberContractWallet> list = memberContractWalletService.findAllByMemberId(authMember.getId());
        if(list == null) {
            return MessageResult.error(500, msService.getMessage("CONTRACT_ACCOUNT_NOT_EXIST"));
        }

        //String serviceName = "bitrade-market";
        //String url = "http://" + serviceName + "/market/exchange-rate/usd-cny";
        //ResponseEntity<MessageResult> retResult = restTemplate.getForEntity(url, MessageResult.class);
        BigDecimal rate = BigDecimal.valueOf(6.42);
        //if (retResult.getStatusCode().value() == 200 && retResult.getBody().getCode() == 0) {
        //    rate = new BigDecimal((Double) retResult.getBody().getData());
        //}

        List<MemberContractWalletWithCut> retList = new ArrayList<MemberContractWalletWithCut>();
        // 计算账户权益
        for (MemberContractWallet wallet : list) {
        	if (wallet==null || wallet.getContractCoin()==null || wallet.getContractCoin().getEnable()!=1)
        		continue;
        	ContractCoinMatch contractCoinMatch = contractCoinMatchFactory.getContractCoinMatch(wallet.getContractCoin().getSymbol());
            if (contractCoinMatch==null)
            	continue;
            
            MemberContractWalletWithCut walletWithCut = new MemberContractWalletWithCut();
            BeanUtils.copyProperties(wallet, walletWithCut);
        	retList.add(walletWithCut);
        	BigDecimal currentPrice = contractCoinMatch.getNowPrice();
            // 计算金本位权益（多仓 + 空仓）
            BigDecimal usdtTotalProfitAndLoss = BigDecimal.ZERO;
            // 多仓计算方法：（当前价格 / 开仓均价 - 1）* （可用仓位 + 冻结仓位） * 合约面值
            if(wallet.getUsdtBuyPrice().compareTo(BigDecimal.ZERO) > 0) {
                usdtTotalProfitAndLoss = usdtTotalProfitAndLoss.add(currentPrice.divide(wallet.getUsdtBuyPrice(), 8, BigDecimal.ROUND_HALF_DOWN).subtract(BigDecimal.ONE).multiply(wallet.getUsdtBuyPosition().add(wallet.getUsdtFrozenBuyPosition())).multiply(wallet.getUsdtShareNumber()));
            }

            // 空仓计算方法：（1 - 当前价格 / 开仓均价）* （可用仓位 + 冻结仓位） * 合约面值
            if(wallet.getUsdtSellPrice().compareTo(BigDecimal.ZERO) > 0) {
                usdtTotalProfitAndLoss = usdtTotalProfitAndLoss.add(BigDecimal.ONE.subtract(currentPrice.divide(wallet.getUsdtSellPrice(),8, BigDecimal.ROUND_HALF_DOWN)).multiply(wallet.getUsdtSellPosition().add(wallet.getUsdtFrozenSellPosition())).multiply(wallet.getUsdtShareNumber()));
            }

            walletWithCut.setUsdtTotalProfitAndLoss(usdtTotalProfitAndLoss);
            walletWithCut.getContractCoin().setCurrentPrice(currentPrice);
            walletWithCut.getContractCoin().setUsdtRate(rate);
            walletWithCut.getContractCoin().setName(wallet.getContractCoin().getCoinSymbol()+" "+msService.getMessage("SWAP_NAME"));
            
            if(wallet.getUsdtBuyPosition().add(wallet.getUsdtFrozenBuyPosition()).add(wallet.getUsdtSellPosition()).add(wallet.getUsdtFrozenSellPosition()).compareTo(BigDecimal.ZERO)>0)
	            walletWithCut.setCutList(contractOrderEntrustService.queryEntrustCutOrdersBySymbol(member.getId(), wallet.getContractCoin().getId()));
        }

        MessageResult result = MessageResult.success("success");
        result.setData(retList);
        return result;
    }

    /**
     * 获取用户指定合约币种的钱包信息
     * @param authMember
     * @return
     */
    @RequestMapping("detail")
    public MessageResult getContractWallet(@SessionAttribute(SESSION_MEMBER) AuthMember authMember, Long contractCoinId) {
        ContractCoin coin = contractCoinService.findOne(contractCoinId);
        if(coin == null) {
            return MessageResult.error(500, msService.getMessage("CONTRACT_NOT_EXIST"));
        }
        Member member = memberService.findOne(authMember.getId());
        if(member == null) {
            return MessageResult.error(500, msService.getMessage("ACCOUNT_NOT_EXIST"));
        }
        MemberContractWallet wallet = memberContractWalletService.findByMemberIdAndContractCoin(authMember.getId(), coin);
        if(wallet == null) {
            return MessageResult.error(500, msService.getMessage("CONTRACT_ACCOUNT_NOT_EXIST"));
        }

        // 计算账户权益
        BigDecimal currentPrice = contractCoinMatchFactory.getContractCoinMatch(coin.getSymbol()).getNowPrice();

        // 计算金本位权益（多仓 + 空仓）
        BigDecimal usdtTotalProfitAndLoss = BigDecimal.ZERO;
        // 多仓计算方法：（当前价格 / 开仓均价 - 1）* （可用仓位 + 冻结仓位） * 合约面值
        if(wallet.getUsdtBuyPrice().compareTo(BigDecimal.ZERO) > 0) {
            usdtTotalProfitAndLoss = usdtTotalProfitAndLoss.add(currentPrice.divide(wallet.getUsdtBuyPrice(), 8, BigDecimal.ROUND_HALF_DOWN).subtract(BigDecimal.ONE).multiply(wallet.getUsdtBuyPosition().add(wallet.getUsdtFrozenBuyPosition())).multiply(wallet.getUsdtShareNumber()));
        }
        // 空仓计算方法：（1 - 当前价格 / 开仓均价）* （可用仓位 + 冻结仓位） * 合约面值
        if(wallet.getUsdtSellPrice().compareTo(BigDecimal.ZERO) > 0) {
            usdtTotalProfitAndLoss = usdtTotalProfitAndLoss.add(BigDecimal.ONE.subtract(currentPrice.divide(wallet.getUsdtSellPrice(), 8, BigDecimal.ROUND_HALF_DOWN)).multiply(wallet.getUsdtSellPosition().add(wallet.getUsdtFrozenSellPosition())).multiply(wallet.getUsdtShareNumber()));
        }

        wallet.setUsdtTotalProfitAndLoss(usdtTotalProfitAndLoss);
        wallet.getContractCoin().setCurrentPrice(currentPrice);

        MessageResult result = MessageResult.success("success");
        result.setData(wallet);
        return result;
    }

    /**
     * 资金划转
     * @param member
     * @param unit
     * @param from
     * @param to
     * @param amount
     * @return
     */
    //@RequestMapping("trans")
    public MessageResult transWallet(@SessionAttribute(SESSION_MEMBER) AuthMember member,
                                     @RequestParam(value = "unit") String unit,
                                     @RequestParam(value = "from") WalletType from,
                                     @RequestParam(value = "to") WalletType to,
                                     @RequestParam(value = "fromWalletId", required = false) Long fromWalletId,
                                     @RequestParam(value = "toWalletId", required = false) Long toWalletId,
                                     @RequestParam(value = "amount") BigDecimal amount
    ) {
        Member member1 = memberService.findOne(member.getId());
        if (member1 == null) {
            return MessageResult.error(msService.getMessage("REQUEST_OF_ILLEGAL"));
        }
        return memberContractWalletService.transWallet(member.getId(), unit, from, to, fromWalletId, toWalletId, amount);
    }

    @RequestMapping("all")
    public MessageResult getContractWallet(@SessionAttribute(SESSION_MEMBER) AuthMember authMember, String symbol) {
        List<MemberContractWallet> list = contractCoinMatchFactory.getContractCoinMatch(symbol).getMemberContractWalletList();
        MessageResult result = MessageResult.success("success");
        result.setData(list);
        return result;
    }

}
