package com.bizzan.bitrade.service;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import com.bizzan.bitrade.dao.FundingRateHistoryDao;
import com.bizzan.bitrade.entity.ContractCoin;
import com.bizzan.bitrade.entity.ContractOrderEntrust;
import com.bizzan.bitrade.entity.FundingRateHistory;
import com.bizzan.bitrade.pagination.Criteria;
import com.bizzan.bitrade.pagination.Restrictions;
import com.bizzan.bitrade.util.RedisManager;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class FundingRateHistoryService {
	
	@Autowired
	private FundingRateHistoryDao dao;
	@Autowired
	private RedisManager redisManager;
	@Autowired
	private ContractCoinService contractCoinService;
	@Autowired
	private SysConfigService sysConfigService;

	public void save(Map<Integer, BigDecimal> fundingRateMap) {
		for(Integer contractId : fundingRateMap.keySet()) {
			FundingRateHistory fundingRateHistory = new FundingRateHistory();
			fundingRateHistory.setFundingRate(fundingRateMap.get(contractId));
			Date fundingTiem = new Date((new Date().getTime() / 3600000) * 3600000);
			fundingRateHistory.setFundingTime(fundingTiem);
			fundingRateHistory.setContractId(contractId.longValue());
			dao.save(fundingRateHistory);
		}
	}
	
	public Map<Integer, BigDecimal> getCurrentFundingRateMap() {
		Map<Integer, BigDecimal> currentFundingRateMap = redisManager.getFundingRateMap();
		if(currentFundingRateMap==null) {
			/*currentFundingRateMap = new HashMap<>();
			List<ContractCoin> coinList = contractCoinService.findAllEnabled();
			for(ContractCoin coin: coinList) {
				currentFundingRateMap.put(coin.getId(), coin.getFeePercent());
			}
			redisManager.saveFundingRateMap(currentFundingRateMap);*/
			currentFundingRateMap = generateNewRateMap();
		}
		//log.info("currentFundingRateMap={}", currentFundingRateMap);
		return currentFundingRateMap;
	}
	
	public Map<Integer, BigDecimal> generateNewRateMap() {
		Map<Integer, BigDecimal> currentFundingRateMap = new HashMap<>();
		List<ContractCoin> coinList = contractCoinService.findAllEnabled();
		for(ContractCoin coin: coinList) {
			BigDecimal feePercent = coin.getFeePercent();
			if (feePercent == null || feePercent.compareTo(BigDecimal.ZERO) == 0) {
				feePercent = BigDecimal.valueOf(sysConfigService.get().getOvernightRate() / 100000);
			}
			//BigDecimal randomPer = BigDecimal.valueOf(Math.random() * 100 / 1000);
			//currentFundingRateMap.put(coin.getId().intValue(), coin.getFeePercent().add(coin.getFeePercent().multiply(randomPer)).setScale(6, BigDecimal.ROUND_UP));
			currentFundingRateMap.put(coin.getId().intValue(), coin.getFeePercent().setScale(6, BigDecimal.ROUND_UP));
		}
		redisManager.saveFundingRateMap(currentFundingRateMap);
		return currentFundingRateMap;
	}
	
	public Page<FundingRateHistory> queryPageByContractId(Long contractId, Date startDate, Date endDate, int pageNo, int pageSize) {
		Sort orders = new Sort(new Sort.Order(Sort.Direction.DESC, "id"));
		Criteria<FundingRateHistory> specification = new Criteria<FundingRateHistory>();
        PageRequest pageRequest = new PageRequest(pageNo - 1, pageSize, orders);
        specification.add(Restrictions.eq("contractId", contractId, false));
        if(startDate!=null) {
        	specification.add(Restrictions.gte("fundingTime", startDate, false));
        }
        if(endDate!=null) {
        	specification.add(Restrictions.lt("fundingTime", endDate, false));
        }

        return dao.findAll(specification, pageRequest);
	}
}
