package com.copy.trade.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.copy.trade.entity.po.Position;
import com.copy.trade.consumer.MarketListener;
import com.copy.trade.dao.CustomerMapper;
import com.copy.trade.dao.PositionMapper;
import com.copy.trade.entity.vo.FollowOrderVo;
import com.copy.trade.entity.vo.TraderVo;
import com.copy.trade.service.ICopiedTradeService;
import com.copy.trade.service.ICustomerService;
import com.copy.trade.service.IFollowService;
import com.copy.trade.service.IPositionService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * <p>
 * 跟单持仓表 服务实现类
 * </p>
 *
 * @author wz
 * @since 2022-11-17
 */
@Service
public class PositionServiceImpl extends ServiceImpl<PositionMapper, Position> implements IPositionService {
	
	@Autowired
	private ICopiedTradeService copiedTradeServiceImpl;
	
	@Autowired
	private ICustomerService customerServiceImpl;
	
    @Autowired
    private MarketListener marketListener;

    @Override
    public Page<FollowOrderVo> currentFollow(Long customerId, Page page) {
       List<FollowOrderVo> list = ((PositionMapper)baseMapper).currentFollow(page,customerId);
       addProfit(list);
       page.setRecords(list);
        return page;
    }

    @Override
    public Page<FollowOrderVo> historyFollow(Long customerId, Page page) {
        List<FollowOrderVo> list = ((PositionMapper)baseMapper).historyFollow(page,customerId);
        list.forEach(followOrderVo -> {
        	Long positionId = followOrderVo.getPositionId();
        	//根据仓位ID查询出平均开仓均价
        	BigDecimal openPrice = copiedTradeServiceImpl.getOpenPriceByPositionId(positionId);
        	if(openPrice != null ) {
        		followOrderVo.setOpenPrice(openPrice);
        	}
        	followOrderVo.setProfitRate(new BigDecimal(0));
        	if(followOrderVo.getProfit() != null && followOrderVo.getPrincipalAmount() != null) {
        		followOrderVo.setProfitRate((followOrderVo.getProfit().multiply(new BigDecimal(100))).divide(followOrderVo.getPrincipalAmount(),8, BigDecimal.ROUND_DOWN));
        	}
            TraderVo traderVo = customerServiceImpl.traderFollowInfo(followOrderVo.getTraderId());
            if(traderVo == null)
            	return;
            followOrderVo.setFollowing(traderVo.getFollowing());
            followOrderVo.setMaxFollow(traderVo.getMaxFollow());
        	
        	
        });
        page.setRecords(list);
        return page;
    }

    @Override
    public Page<FollowOrderVo> lead(Long traderId, Page page, String type) {
        List<FollowOrderVo> list = new ArrayList<>();
        TraderVo traderVo = customerServiceImpl.traderFollowInfo(traderId);

        switch (type){
            case "current":
                 list = ((PositionMapper)baseMapper).leadCurrent(page,traderId);
                 addProfit(list);
                break;
            case "history":
                list = ((PositionMapper)baseMapper).leadHistory(page,traderId);
                dealHistoryLead(list,traderVo);

                break;
        }
        page.setRecords(list);
        return page;
    }

	@Override
	public BigDecimal selectDividendFee(Position position) {
		return ((PositionMapper)baseMapper).selectDividendFee(position);
	}
	
	@Override
	public BigDecimal selectStudentProfit(Position position) {
		return ((PositionMapper)baseMapper).selectStudentProfit(position);
	}
	
    @Override
    public Integer getPositionCount(Long traderId) {
        QueryWrapper<Position> positionQueryWrapper = new QueryWrapper<>();
        positionQueryWrapper.eq("customer_id",traderId);
        positionQueryWrapper.ne("status",30);
        return count(positionQueryWrapper);
    }
    
    @Override
    public Integer getPositionCountForTeacherOrStudent(Long traderId,Long customerId) {
    	QueryWrapper<Position> positionQueryWrapper = new QueryWrapper<>();
    	positionQueryWrapper.eq("trader_id",traderId);
    	positionQueryWrapper.eq("customer_id",customerId);
    	positionQueryWrapper.ne("status",30);
    	return count(positionQueryWrapper);
    }
    
    private List<FollowOrderVo> addProfit(List<FollowOrderVo> list) {
    	list.forEach(followOrderVo -> {
       	   BigDecimal openPrice = followOrderVo.getOpenPrice();
       	   BigDecimal totalPosition = followOrderVo.getTotalPosition();
       	   Integer direction = followOrderVo.getDirection();
       	   Integer leverage = followOrderVo.getLeverage();
       	   String symbol = followOrderVo.getSymbol();
       	   BigDecimal currentPrice = marketListener.getCurrentPriceMap().get(symbol);
       	   followOrderVo.setCurrentPrice(currentPrice);
       	   if (currentPrice == null) {
       	       followOrderVo.setProfit(BigDecimal.ZERO);
       	       followOrderVo.setPrincipalAmount(BigDecimal.ZERO);
       	       followOrderVo.setProfitRate(BigDecimal.ZERO);
       	   } else {
       	       followOrderVo.setProfit((currentPrice.subtract(openPrice)).multiply(totalPosition).multiply(direction == 0 ? new BigDecimal(1) : new BigDecimal(-1)));
       	       followOrderVo.setPrincipalAmount(currentPrice.multiply(totalPosition).divide(new BigDecimal(leverage), BigDecimal.ROUND_CEILING));
       	       followOrderVo.setProfitRate((followOrderVo.getProfit().multiply(new BigDecimal(100))).divide(followOrderVo.getPrincipalAmount(), BigDecimal.ROUND_CEILING));
       	   }
          });
    	return list;
    }
    
    private List<FollowOrderVo> dealHistoryLead(List<FollowOrderVo> list,TraderVo traderVo) {
        list.forEach(followOrderVo -> {
        	Long positionId = followOrderVo.getPositionId();
        	//根据仓位ID查询出平均开仓均价
        	BigDecimal openPrice = copiedTradeServiceImpl.getOpenPriceByPositionId(positionId);
        	if(openPrice != null ) {
        		followOrderVo.setOpenPrice(openPrice);
        	}
        	followOrderVo.setProfitRate(new BigDecimal(0));
        	if(followOrderVo.getProfit() != null && followOrderVo.getPrincipalAmount() != null) {
        		followOrderVo.setProfitRate((followOrderVo.getProfit().multiply(new BigDecimal(100))).divide(followOrderVo.getPrincipalAmount(),8, BigDecimal.ROUND_DOWN));
        	}
            followOrderVo.setFollowing(traderVo.getFollowing());
            followOrderVo.setMaxFollow(traderVo.getMaxFollow());
        });
        return list;
    }
    
    
}
