package com.bizzan.bitrade.controller;

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

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

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Sort;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.SessionAttribute;
import org.springframework.web.client.RestTemplate;

import com.alibaba.druid.support.logging.Log;
import com.bizzan.bitrade.constant.PageModel;
import com.bizzan.bitrade.controller.screen.MemberContractPositionScreen;
import com.bizzan.bitrade.entity.ContractCoin;
import com.bizzan.bitrade.entity.ContractPositionStatus;
import com.bizzan.bitrade.entity.Member;
import com.bizzan.bitrade.entity.MemberContractPosition;
import com.bizzan.bitrade.entity.QMemberContractPosition;
import com.bizzan.bitrade.entity.transform.AuthMember;
import com.bizzan.bitrade.model.MemberContractPositionVo;
import com.bizzan.bitrade.service.ContractCoinService;
import com.bizzan.bitrade.service.MemberContractPositionService;
import com.bizzan.bitrade.service.MemberService;
import com.bizzan.bitrade.service.MemberWeightUpperService;
import com.bizzan.bitrade.util.MessageResult;
import com.bizzan.bitrade.util.PredicateUtils;
import com.bizzan.bitrade.vo.MemberContractPositionWithCut;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.BooleanExpression;

import ch.qos.logback.classic.Logger;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@Api(value = "MemberContractPositionController" , tags = "仓位接口")
@RestController
@RequestMapping("/swap/position")
public class MemberContractPositionController extends BaseController {
	@Autowired
	private MemberContractPositionService positionService;
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private ContractCoinService contractCoinService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private MemberWeightUpperService memberWeightUpperService;

	@ApiOperation(value="获取仓位", notes="获取当前仓位")
    @PostMapping("page-query")
	public MessageResult<Page<MemberContractPositionVo>> list(@SessionAttribute(SESSION_MEMBER) AuthMember user,
			PageModel pageModel,
            MemberContractPositionScreen screen) {
		String serviceName = "contract-swap-api";
        String marketUrl = "http://" + serviceName + "/swap/symbol-price";

        ParameterizedTypeReference<Map<String, BigDecimal>> typeRef = new ParameterizedTypeReference<Map<String, BigDecimal>>() {};
        ResponseEntity<Map<String, BigDecimal>> responseEntity = restTemplate.exchange(marketUrl, HttpMethod.POST, new HttpEntity<>(null), typeRef);
        Map<String, BigDecimal> priceList =responseEntity.getBody();
        
        if (pageModel.getDirection() == null && pageModel.getProperty() == null) {
            ArrayList<Sort.Direction> directions = new ArrayList<>();
            directions.add(Sort.Direction.DESC);
            pageModel.setDirection(directions);
            List<String> property = new ArrayList<>();
            property.add("memberId"); // 默认金额排序
            pageModel.setProperty(property);
        }
        
        Predicate predicate = getPredicate(screen, user.getId());
        
        Page<MemberContractPosition> positions = positionService.findAll(predicate, pageModel.getPageable());
		positionService.addCurrentPriceForPage(positions, priceList);
		List<MemberContractPosition> list = positions.getContent();
		List<MemberContractPositionVo> retList = new ArrayList<MemberContractPositionVo>();
		for(MemberContractPosition position :list) {
			MemberContractPositionVo vo = new MemberContractPositionVo();
			BeanUtils.copyProperties(position, vo);
			vo.setUsername(memberService.findUserNameById(position.getMemberId()));
        	retList.add(vo);
		}
		
		Page<MemberContractPositionVo> newAll = new PageImpl<MemberContractPositionVo>(retList, pageModel.getPageable(), positions.getTotalElements());
        MessageResult<Page<MemberContractPositionVo>> result = MessageResult.success("success");
        result.setData(newAll);
        return result;
	}
	
	private Predicate getPredicate(MemberContractPositionScreen screen, Long userId) {
		ArrayList<BooleanExpression> booleanExpressions = new ArrayList<>();
		QMemberContractPosition qMemberContractPosition = QMemberContractPosition.memberContractPosition;
		
		if (screen.getContractId() != null) {
            ContractCoin coin = contractCoinService.findOne(screen.getContractId());
            booleanExpressions.add(qMemberContractPosition.coin.eq(coin));
        }
        if(screen.getMemberId() != null) {
            booleanExpressions.add(qMemberContractPosition.memberId.eq(screen.getMemberId()));
        }
        if(StringUtils.isNotEmpty(screen.getPhone())) {
            Member member = memberService.findByPhone(screen.getPhone());
            booleanExpressions.add(qMemberContractPosition.memberId.eq(member.getId()));
        }
        if(StringUtils.isNotEmpty(screen.getEmail())) {
            Member member = memberService.findByEmail(screen.getEmail());
            booleanExpressions.add(qMemberContractPosition.memberId.eq(member.getId()));
        }
        if(StringUtils.isNotEmpty(screen.getUsername())) {
            Member member = memberService.findByUsername(screen.getUsername());
            booleanExpressions.add(qMemberContractPosition.memberId.eq(member.getId()));
        }
        if(screen.getStatus() != null && screen.getStatus()==1) {
        	booleanExpressions.add(qMemberContractPosition.status.ne(ContractPositionStatus.DONE));
        }
        List<Long> subIds = memberWeightUpperService.findMemberIdListByAllUppers(userId);
        subIds.add(userId);
        booleanExpressions.add(qMemberContractPosition.memberId.in(subIds));
		return PredicateUtils.getPredicate(booleanExpressions);
	}
}
