package com.liangjian.dataplatform.member.service.impl;

import com.liangjian.dataplatform.member.dao.secondary.MemIngProductLevelRepository;
import com.liangjian.dataplatform.member.dao.secondary.MemIngProductRepository;
import com.liangjian.dataplatform.member.entity.po.secondary.*;
import com.liangjian.dataplatform.member.entity.po.secondary.WeixinUserInfo;
import com.liangjian.dataplatform.member.entity.token.WeixinJwtTokenGetter;
import com.liangjian.dataplatform.member.service.IMemIngProductService;
import com.liangjian.dataplatform.member.service.IUserGrowthLogService;
import com.liangjian.dataplatform.member.service.IUserLevelService;
import com.liangjian.dataplatform.member.service.IWeixinUserInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Path;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Author: 黄子奇
 * @Date: 2019/11/19
 */
@Service
public class MemIngProductService implements IMemIngProductService {
    @Autowired
    private IWeixinUserInfoService iWeixinUserInfoService;
    @Autowired
    private IUserGrowthLogService iUserGrowthLogService;
    @Autowired
    private IUserLevelService iUserLevelService;
    @Autowired
    private MemIngProductRepository memIngProductRepository;
    @Autowired
    private MemIngProductLevelRepository memIngProductLevelRepository;

    @Override
    public Page<MemIngProduct> queryProduct(String openid,Integer page, Integer size) {
        Optional<WeixinUserInfo> opt = iWeixinUserInfoService.findByOpenid(openid);
        if(opt.isPresent()) {
            return queryProductByPhone(opt.get().getSecretPhone(),page,size);
        } else {
            return queryProduct(page,size);
        }
    }

    @Override
    public Page<MemIngProduct> queryProduct(Integer page, Integer size) {
        Pageable pageable = PageRequest.of(page,size, Sort.Direction.DESC,"LastModified");
        Page<MemIngProduct> res = memIngProductRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
            var p1 = criteriaBuilder.equal(root.get("state"),1);
            var p2 = criteriaBuilder.equal(root.get("isDelete"),1);
            return criteriaBuilder.and(p1,p2);
        },pageable);
        res.getContent().forEach(i -> i.setProductLevel(Collections.emptySet()));
        return res;
    }

    @Override
    public Page<MemIngProduct> queryProductByPhone(String secretPhone,Integer page, Integer size) {
        Pageable pageable = PageRequest.of(page,size, Sort.Direction.DESC,"LastModified");
//        Integer growthBalance = iUserGrowthLogService.getPointBalance(secretPhone);
        Integer growthBalance = WeixinJwtTokenGetter.UserInfo.get().getObject().getGrowth();
        Optional<UserLevelUnit> levelUnit = iUserLevelService.getLevelIn(growthBalance);
        if(!levelUnit.isPresent()) {
            //查不到等级信息
            return queryProduct(page, size);
        }

        UserLevelUnit level = levelUnit.get();
        Page<MemIngProduct> productPage = memIngProductRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
            var p1 = criteriaBuilder.equal(root.get("state"),1);
            var p2 = criteriaBuilder.equal(root.get("isDelete"),1);
            return criteriaBuilder.and(p1,p2);
        },pageable);
        productPage = productPage.map(i -> {
            Set<MemIngProductLevel> levels = i.getProductLevel().stream()
                    .filter(l -> l.getLevel().getId().equals(level.getId()))
                    .collect(Collectors.toSet());
            i.setProductLevel(levels);
            return i;
        });
        return productPage;
    }

    @Override
    public Page<MemIngProduct> queryByLevel(String levelId, Integer page, Integer size) {
        List<String> productIds = memIngProductLevelRepository
                .findAll((root, criteriaQuery, criteriaBuilder) ->
                        criteriaBuilder.equal(root.get("levelId"),levelId))
                .stream().map(i -> i.getProductCode())
                .collect(Collectors.toList());

        Pageable pageable = PageRequest.of(page,size, Sort.Direction.DESC,"lastModified");
        Page<MemIngProduct> res = memIngProductRepository.findAll((root, criteriaQuery, criteriaBuilder) -> {
            Path<String> path = root.get("productCode");
            CriteriaBuilder.In<String> in = criteriaBuilder.in(path);
            in.value("first_key");
            productIds.forEach(i -> in.value(i));
            return in;
        }, pageable).map(i -> {
            i.setProductLevel(Collections.emptySet());
            return i;
        });

        return res;
    }
}
