package com.bizzan.bitrade.entity;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.swagger.annotations.ApiModelProperty;

public class FollowAccount extends FollowWallet implements Serializable {
	private static final Long serialVersionUID = 105L;
	
	private Map<String, BigDecimal> currentPriceMap;
	private int blastMarginRate;
	private List<MemberContractWallet> walletList = new ArrayList<MemberContractWallet>();
	
	public MemberContractWallet getWalletByContractId(Long contractId) {
		for(MemberContractWallet wallet: walletList) {
			if(wallet.getContractCoin().getId().longValue() == contractId.longValue())
				return wallet;
		}
		return null;
	}
	
	public BigDecimal sumCurrentMarginByContractId(long contractId) {
		BigDecimal currentContractMargin = BigDecimal.ZERO;
		for(MemberContractPosition position: this.getCurrentPositionList()) {
			if(position.getCoin().getId().longValue() == contractId)
				currentContractMargin = currentContractMargin.add(position.getCurrentMargin());
		}
		return currentContractMargin;
	}
	
	public BigDecimal sumCurrentMarginByContractIdAndFollowMemberId(long contractId, long followMemberId) {
		BigDecimal currentContractMargin = BigDecimal.ZERO;
		for(MemberContractPosition position: this.getCurrentPositionList()) {
			if(position.getCoin().getId().longValue() == contractId && position.getFollowMemberId().longValue() == followMemberId)
				currentContractMargin = currentContractMargin.add(position.getCurrentMargin());
		}
		return currentContractMargin;
	}

	public void setWalletList(List<MemberContractWallet> walletList) {
		this.walletList = walletList;
	}

	public void setCurrentPriceMap(Map<String, BigDecimal> currentPriceMap) {
		this.currentPriceMap = currentPriceMap;
		if(this.getCurrentPositionList()!=null) {
			for(MemberContractPosition position: this.getCurrentPositionList()) {
				position.setCurrentPrice(currentPriceMap.get(position.getCoin().getSymbol()));
			}
		}
	}
	
	public Map<String, BigDecimal> getCurrentPriceMap() {
		return this.currentPriceMap;
	}
	
	@ApiModelProperty("可用开仓余额 用于客户端计算可开张数")
    public BigDecimal getAvailableBalance() {
    	BigDecimal revenue = this.getCurrentRevenue();
    	BigDecimal currentBalance = this.getCurrentBalance();
    	//currentBalance = currentBalance.compareTo(this.getBalance())<0?currentBalance:this.getBalance();
    	if(revenue.compareTo(BigDecimal.ZERO)<0)
    		currentBalance = currentBalance.add(revenue);
    	if(currentBalance.compareTo(BigDecimal.ZERO)<0)
    		currentBalance = BigDecimal.ZERO;
    	return currentBalance;
    		//return this.getBalance().add(this.getFrozenBalance()).subtract(this.getCurrentMargin()).add(revenue);
    }
	
	@ApiModelProperty("可用开仓余额")
    public BigDecimal getAvailableBalanceForOpen() {
    	BigDecimal revenue = this.getCurrentRevenue();
    	//BigDecimal currentBalance = this.getCurrentBalance();
    	//currentBalance = currentBalance.compareTo(this.getBalance())<0?currentBalance:this.getBalance();
    	if(revenue.compareTo(BigDecimal.ZERO)>0)
    		return this.getBalance();
    	else
    		return this.getBalance().add(revenue);
    		//return this.getBalance().add(this.getFrozenBalance()).subtract(this.getCurrentMargin()).add(revenue);
    }
	
	@ApiModelProperty("账户当前收益")
    public BigDecimal getCurrentRevenue() {
    	BigDecimal revenue = BigDecimal.ZERO;
    	if(currentPriceMap == null || this.getCurrentPositionList()==null)
    		return revenue;
    	for(MemberContractPosition position : this.getCurrentPositionList()) {
    		revenue = revenue.add(position.getCurrentProfit());
    	}
    	return revenue;
    }
    
	@ApiModelProperty("账户当前权益")
    public BigDecimal getCurrentCapital() {
    	return this.getBalance().add(this.getFrozenBalance()).add(this.getFrozenMargin())
    			//.add(this.getSpecialBalance()).add(this.getSpecialFrozenBalance())
    			.add(this.getCurrentRevenue());
    }
	
	@ApiModelProperty("账户静态权益")
	public BigDecimal getStaticBalance() {
		return this.getBalance().add(this.getFrozenBalance()).add(this.getFrozenMargin());
	}
	
	@ApiModelProperty("账户当前保证金")
    public BigDecimal getCurrentMargin() {
    	BigDecimal margin = BigDecimal.ZERO;
    	if(currentPriceMap == null || this.getCurrentPositionList()==null)
    		return margin;
    	for(MemberContractPosition position : this.getCurrentPositionList()) {
    		margin = margin.add(position.getCurrentMargin());
    	}
    	return margin;
    }
	
	@ApiModelProperty("账户当前余额(调整保证金后)")
    public BigDecimal getCurrentBalance() {
    	return this.getBalance().add(this.getFrozenBalance()).subtract(getCurrentMargin());
    }
	
	@ApiModelProperty("账户风险度")
	public BigDecimal getRiskRate() {
		BigDecimal currentCapital = this.getCurrentCapital();
		if(currentCapital.compareTo(BigDecimal.ZERO) == 0)
			return BigDecimal.ZERO;
		return this.getFrozenBalance().divide(this.getCurrentCapital(), 4, BigDecimal.ROUND_DOWN);
	}
	
	
	@ApiModelProperty("账户仓位总市值 多单和空单")
	public BigDecimal[] getMaketValue() {
		BigDecimal buyMarketValue = BigDecimal.ZERO;
		BigDecimal sellMarketValue = BigDecimal.ZERO;
		if(currentPriceMap == null || this.getCurrentPositionList()==null)
    		return new BigDecimal[] {buyMarketValue, sellMarketValue};
    	for(MemberContractPosition position : this.getCurrentPositionList()) {
    		if(position.getDirection() == ContractOrderDirection.BUY)
    			buyMarketValue = buyMarketValue.add(position.getCurrentMarketValue());
    		else
    			sellMarketValue = sellMarketValue.add(position.getCurrentMarketValue());
    	}
		return new BigDecimal[] {buyMarketValue, sellMarketValue};
	}
	
	public Map<ContractCoin, BigDecimal> findMarginMap() {
		Map<ContractCoin, BigDecimal> marginMap = new HashMap<ContractCoin, BigDecimal>();
		if(currentPriceMap == null || this.getCurrentPositionList()==null)
			return marginMap;
		for(MemberContractPosition position : this.getCurrentPositionList()) {
			if(marginMap.containsKey(position.getCoin())) {
				marginMap.put(position.getCoin(), marginMap.get(position.getCoin()).add(position.getCurrentMargin()));
			} else
				marginMap.put(position.getCoin(), position.getCurrentMargin());
    	}
		return marginMap;
	}
	
	public Map<ContractCoin, BigDecimal> findMarketValueMap() {
		Map<ContractCoin, BigDecimal> marketValueMap = new HashMap<ContractCoin, BigDecimal>();
		if(currentPriceMap == null || this.getCurrentPositionList()==null)
			return marketValueMap;
		for(MemberContractPosition position : this.getCurrentPositionList()) {
			if(marketValueMap.containsKey(position.getCoin())) {
				marketValueMap.put(position.getCoin(), marketValueMap.get(position.getCoin()).add(position.getCurrentMarketValue()));
			} else
				marketValueMap.put(position.getCoin(), position.getCurrentMarketValue());
    	}
		return marketValueMap;
	}
	
	public BigDecimal getEstimatedBlastRate() {
    	if(this.getCurrentPositionList()==null || this.getCurrentPositionList().size()==0)
    		return BigDecimal.ZERO;
    	
    	BigDecimal[] marketValueArray = this.getMaketValue();
    	BigDecimal marketValue = marketValueArray[0].subtract(marketValueArray[1]);
    	if(marketValue.compareTo(BigDecimal.ZERO)==0)
    		return BigDecimal.ZERO; 
    	BigDecimal rate = this.getCurrentCapital().subtract(this.getCurrentMargin().multiply(BigDecimal.valueOf(blastMarginRate/100.0)))
    			.divide(marketValue, 8, BigDecimal.ROUND_HALF_UP);
    	return rate;
    }
	
	public void setBlastMarginRate(int blastMarginRate) {
		this.blastMarginRate = blastMarginRate;
	}
	
	@ApiModelProperty("用户名")
	private String username;
	
	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

	public BigDecimal getCashBalance() {
		return cashBalance;
	}

	public void setCashBalance(BigDecimal cashBalance) {
		this.cashBalance = cashBalance;
	}

	@ApiModelProperty("资金账户余额")
	private BigDecimal cashBalance;
}
