package com.bizzan.bitrade.job;

import com.bizzan.bitrade.constant.TransactionType;
import com.bizzan.bitrade.dao.MemberDao;
import com.bizzan.bitrade.dao.MemberDepositDao;
import com.bizzan.bitrade.dao.WithdrawRecordDao;
import com.bizzan.bitrade.entity.*;
import com.bizzan.bitrade.service.*;
import com.bizzan.bitrade.service.SpotWalletSnapshotService;
import com.bizzan.bitrade.util.DateUtil;
import com.bizzan.bitrade.vo.TradingAccount;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Component
@Slf4j
public class MemberStatisticsJob {

    private static Logger logger = LoggerFactory.getLogger(MemberStatisticsJob.class);

    @Autowired
    private MemberDao memberDao ;
    @Autowired
    private MemberService memberService ;

    @Autowired
    private OrderService orderService;


    @Autowired
    private MemberDepositDao memberDepositDao ;

    @Autowired
    private WithdrawRecordDao withdrawRecordDao ;
    @Autowired
    private MemberTransactionService memberTransactionService;
    @Autowired
    private MemberHistoryService memberHistoryService;
    @Autowired
    private MemberWalletService memberWalletService;
    @Autowired
    private MemberContractWalletService memberContractWalletService;
    @Autowired
    private ContractOrderEntrustService contractOrderEntrustService;
    @Autowired
    private UserPurseService userPurseService;
    @Autowired
    private FollowWalletService followWalletService;
    @Autowired
    private BalanceService balanceService;
    @Autowired
    private AgentDailyInfoService agentDailyInfoService;
    @Autowired
    private MemberWeightUpperService memberWeightUpperService;
    @Autowired
    private SpotWalletSnapshotService spotWalletSnapshotService;


    @Scheduled(cron = "0 0 0 * * ?")
    public void agentActivityStatistics() {
    	int pageNo = 0;
    	int pageSize = 100;
    	while(true) {
    		logger.info("开始统计个人团队信息, pageNo={}", pageNo);
    		Page<Member> members = memberService.findAgentsByPage(pageNo, pageSize);
    		List<Member> all = members.getContent();

	        if (all != null && all.size() > 0) {
	        	for(Member member : all) {
		    		if(member.getId()==1)
		    			continue;
		    		
		    		List<MemberWeightUpper> subList = memberWeightUpperService.findAllByAllUppers(member.getId());
		            List<Long> subIds = new ArrayList<Long>();
		            for(MemberWeightUpper upper: subList)
		            	subIds.add(upper.getMemberId());
		            subIds.add(member.getId());
		    		
		            AgentDailyInfo agentDailyInfo = new AgentDailyInfo();
		            agentDailyInfo.setMemberId(member.getId());
		    		BigDecimal balance = balanceService.sumBalanceByMemberIds(subIds);
		    		agentDailyInfo.setBalance(balance);
		        	agentDailyInfoService.save(agentDailyInfo);
	        	}
	        	pageNo++;
	        }else {
	        	break;
	        }
    	}
    }
    
    @Scheduled(cron = "0 0 0 * * ?")
    public void transactionHistory() {
    	Calendar now = Calendar.getInstance();
    	memberHistoryService.startStat(now);
    	// 清理 30 天前的现货持仓快照（快照由 contract-swap-api SpotListener 写入）
    	try {
    		spotWalletSnapshotService.cleanOldSnapshots(30);
    	} catch (Exception e) {
    		logger.error("cleanOldSnapshots error", e);
    	}
    }

    //@Scheduled(cron = "0 0 3 * * ?")
    @Scheduled(fixedRate = 3600*1000)
    public void updateMemberBalance() throws ParseException {
    	logger.info("开始更新会员统计信息");
    	Long[] todayTime = DateUtil.getRealStartAndEndDate(0);
    	final long startTimeLong = todayTime[0];
    	final long endTimeLong = todayTime[1];
    	java.text.SimpleDateFormat sdf1 = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    	String startTimeStr = sdf1.format(new Date(startTimeLong));
    	String endTimeStr = sdf1.format(new Date(endTimeLong));
    	
    	int pageNo = 0;
    	int pageSize = 100;
    	while(true) {
    		logger.info("开始统计个人会员信息, pageNo={}", pageNo);
    		Page<Member> members = memberService.findByPage(pageNo, pageSize);
    		List<Member> all = members.getContent();

	        if (all != null && all.size() > 0) {
	        	for(Member member : all) {
		    		if(member.getId()==1)
		    			continue;
		    		
		    		TradingAccount tradingAccount = userPurseService.findOneVO(member.getId());
		    		FollowWallet followWallet = followWalletService.findOne(member.getId());
		    		BigDecimal followBalance = followWallet.getBalance().add(followWallet.getFrozenBalance());
		    		BigDecimal totalBalance = memberWalletService.sumBalanceByMemberId(member.getId()).add(tradingAccount.getCurrentCapital()).add(followBalance);
		    		BigDecimal totalProfit = memberTransactionService.sumAmountByMemberIdAndType(member.getId(), TransactionType.CONTRACT_PROFIT);
		        	BigDecimal totalLoss = memberTransactionService.sumAmountByMemberIdAndType(member.getId(), TransactionType.CONTRACT_LOSS);
		        	BigDecimal todayProfit = memberTransactionService.sumAmountByMemberIdAndTypeAndTime(startTimeStr, endTimeStr, member.getId(), TransactionType.CONTRACT_PROFIT);
		        	BigDecimal todayLoss = memberTransactionService.sumAmountByMemberIdAndTypeAndTime(startTimeStr, endTimeStr, member.getId(), TransactionType.CONTRACT_LOSS);
		        	BigDecimal totalFee = memberTransactionService.sumAmountByMemberIdAndType(member.getId(), TransactionType.CONTRACT_FEE);
		        	
		    		BigDecimal totalAward = memberTransactionService.sumAmountByMemberIdAndType(member.getId(), TransactionType.CONTRACT_AWARD);
		        	BigDecimal todayAward = memberTransactionService.sumAmountByMemberIdAndTypeAndTime(startTimeStr, endTimeStr, member.getId(), TransactionType.CONTRACT_AWARD);
		        	BigDecimal totalWithdraw = memberTransactionService.sumAmountByMemberIdAndType(member.getId(), TransactionType.WITHDRAW);
		        	BigDecimal totalRecharge = memberTransactionService.sumAmountByMemberIdAndType(member.getId(), TransactionType.RECHARGE);
		        	BigDecimal totalAdminRecharge = memberTransactionService.sumAmountByMemberIdAndType(member.getId(), TransactionType.ADMIN_RECHARGE);
		        	totalRecharge = totalRecharge.add(totalAdminRecharge);
		        	int todayOrder = (int)contractOrderEntrustService.countByMemberId(member.getId(), startTimeLong, endTimeLong);
		        	member.setTotalRecharge(totalRecharge);
		        	member.setTotalWithdraw(totalWithdraw);
		        	member.setTodayAward(todayAward);
		        	member.setTotalAward(totalAward);
		        	member.setTotalBalance(totalBalance);
		        	member.setTodayOrder(todayOrder);
		        	member.setTotalProfit(totalProfit);
		        	member.setTotalLoss(totalLoss);
		        	member.setTodayProfit(todayProfit);
		        	member.setTodayLoss(todayLoss);
		        	member.setTotalFee(totalFee);
		        	
		        	memberDao.saveAndFlush(member);
		    	}
	        	pageNo++;
	        }else {
	        	break;
	        }
    	}
    	pageNo = 0;
    	
    	while(true) {
    		logger.info("开始统计个人团队信息, pageNo={}", pageNo);
    		Page<Member> members = memberService.findByPage(pageNo, pageSize);
    		List<Member> all = members.getContent();

	        if (all != null && all.size() > 0) {
	        	for(Member member : all) {
		    		if(member.getId()==1)
		    			continue;
		    		
		    		if(member.getSuperPartner().equals("1")) {
			        	AgentVo agentVo = memberService.sumStatsByMemberId(member.getId());
			        	member.setAgentTotalBalance(agentVo.getTotalBalance());
			        	member.setAgentTotalRecharge(agentVo.getTotalRecharge());
			        	member.setAgentTotalWithdraw(agentVo.getTotalWithdraw());
			        	member.setAgentTotalAward(agentVo.getTotalAward());
			        	member.setAgentTotalFee(agentVo.getTotalFee());
			        	member.setAgentTotalProfit(agentVo.getTotalProfit());
			        	member.setAgentTotalLoss(agentVo.getTotalLoss());
			        	member.setAgentTotalCount(agentVo.getTotalCount());
			        	memberDao.saveAndFlush(member);
		        	}
		        	
	        	}
	        	pageNo++;
	        }else {
	        	break;
	        }
    	}
    	logger.info("完成更新会员统计信息");
    }

}
