package com.quantgroup.asset.distribution.service.route.impl;

import com.quantgroup.asset.distribution.model.entity.route.channelroute.*;
import com.quantgroup.asset.distribution.model.response.GlobalResponse;
import com.quantgroup.asset.distribution.service.jpa.entity.ChannelRuleEntity;
import com.quantgroup.asset.distribution.service.jpa.entity.FundProductEntity;
import com.quantgroup.asset.distribution.service.jpa.entity.QChannelRuleEntity;
import com.quantgroup.asset.distribution.service.jpa.repository.IChannelRuleRepository;
import com.quantgroup.asset.distribution.service.jpa.repository.IFundProductRepository;
import com.quantgroup.asset.distribution.service.route.IChannelRouteService;
import com.quantgroup.asset.distribution.util.AllRecords;
import com.querydsl.core.types.dsl.BooleanExpression;
import com.querydsl.core.types.dsl.Expressions;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
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 org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Service
@Slf4j
public class ChannelRouteServiceImpl implements IChannelRouteService {

    @Autowired
    IChannelRuleRepository channelRuleRepository;

    @Autowired
    IFundProductRepository fundProductRepository;

    @Override
    public AllRecords queryPage(ChannelRouteQueryVo channelRouteQueryVo) {
        //索引 和 每页大小   排序   条件
        BooleanExpression booleanExpression = Expressions.asBoolean(true).isTrue();

        if (Objects.nonNull(channelRouteQueryVo.getChannelId())){
            booleanExpression =  booleanExpression.and(QChannelRuleEntity.channelRuleEntity.channelId.like(String.valueOf(channelRouteQueryVo.getChannelId())));
        }
        if (Objects.nonNull(channelRouteQueryVo.getFundId())){
            booleanExpression =  booleanExpression.and(QChannelRuleEntity.channelRuleEntity.fundId.like(String.valueOf(channelRouteQueryVo.getFundId())));
        }
        if (!StringUtils.isEmpty(channelRouteQueryVo.getFundName())){
            booleanExpression =  booleanExpression.and(QChannelRuleEntity.channelRuleEntity.fundName.like(String.valueOf(channelRouteQueryVo.getFundName())));
        }
        if (Objects.nonNull(channelRouteQueryVo.getPublishStatus())){
            booleanExpression =  booleanExpression.and(QChannelRuleEntity.channelRuleEntity.publishStatus.eq(channelRouteQueryVo.getPublishStatus()));
        }
        //只查有效数据
        booleanExpression =  booleanExpression.and(QChannelRuleEntity.channelRuleEntity.enable.eq(Boolean.TRUE));

        //1.查询条件，2.索引和每页的大小，3.排序根据某个字段进行排序
        //查询总条数
        long count = channelRuleRepository.count(booleanExpression);
        //查询数据
        log.info("{},{},{}",channelRouteQueryVo.getOffset(),channelRouteQueryVo.getPageIndex(),channelRouteQueryVo.getPageSize());
        Page<ChannelRuleEntity> plantPage = channelRuleRepository.findAll(booleanExpression, new PageRequest(channelRouteQueryVo.getPageIndex()-1, channelRouteQueryVo.getPageSize(), new Sort(Sort.Direction.DESC, "createdAt")));
        List<ChannelRuleEntity> channelRuleEntities = new ArrayList<>();
        channelRuleEntities = plantPage.getContent();
        List<ChannelRouteResultVo> channelRouteResultVos = new ArrayList<>();
        channelRuleEntities.stream().forEach(channelRuleEntity -> {
            ChannelRouteResultVo channelRouteResultVo = new ChannelRouteResultVo();
            BeanUtils.copyProperties(channelRuleEntity, channelRouteResultVo);

            FundProductEntity one = fundProductRepository.findOne(channelRuleEntity.getFundProductId());
            if (Objects.nonNull(one)){
                channelRouteResultVo.setSystermType(one.getSystermType());
            }

            String userLevel = channelRouteResultVo.getUserLevel();
            if (!StringUtils.isEmpty(userLevel)){
                channelRouteResultVo.setUserLevel(userLevel.substring(1, userLevel.length() - 1));

            }
            String userTag = channelRouteResultVo.getUserTag();
            if (!StringUtils.isEmpty(userTag)){
                channelRouteResultVo.setUserTag(userTag.replace("[","").replace("]",""));
            }

            channelRouteResultVos.add(channelRouteResultVo);
        });

        AllRecords allRecords = new AllRecords();
        allRecords.setPageIndex(channelRouteQueryVo.getPageIndex());
        allRecords.setPageSize(channelRouteQueryVo.getPageSize());
        allRecords.setDataList(channelRouteResultVos);
        allRecords.setTotalNumber(count);
        allRecords.resetTotalNumber(count);
        return allRecords;
    }

    @Override
    public List<Long> queryConfigChannelIds() {
        List<ChannelRuleEntity> allByEnableEquals = channelRuleRepository.getAllByEnableEquals(Boolean.TRUE);
        List<Long> channelIds = new ArrayList<>();
        allByEnableEquals.stream().forEach(channelRuleEntity -> {
            if (!channelIds.contains(channelRuleEntity.getChannelId())){
                channelIds.add(channelRuleEntity.getChannelId());
            }
        });
        return channelIds;
    }

    @Override
    public GlobalResponse queryConfigChannelInfo(Long channelId) {
        List<ChannelConfigInfoVo> channelConfigInfoVos = new ArrayList<>();
        List<ChannelRuleEntity> allByChannelIdEqualsaAndEnableEquals = channelRuleRepository.getAllByChannelIdEqualsAndEnableEquals(channelId, Boolean.TRUE);
        if (CollectionUtils.isEmpty(allByChannelIdEqualsaAndEnableEquals)){
            return GlobalResponse.error("该渠道没有对应的路由配置信息");
        }else {
            allByChannelIdEqualsaAndEnableEquals.stream().forEach(channelRuleEntity -> {
                ChannelConfigInfoVo configInfoVo = new ChannelConfigInfoVo();
                BeanUtils.copyProperties(channelRuleEntity, configInfoVo);

                String userLevel = configInfoVo.getUserLevel();
                if (!StringUtils.isEmpty(userLevel)){
                    configInfoVo.setUserLevel(userLevel.substring(1, userLevel.length() - 1));
                }
                String userTag = configInfoVo.getUserTag();
                if (!StringUtils.isEmpty(userTag)){
                    configInfoVo.setUserTag(userTag.replace("[","").replace("]",""));
                }
                FundProductEntity one = fundProductRepository.findOne(channelRuleEntity.getFundProductId());
                if (Objects.nonNull(one)){
                    configInfoVo.setSystermType(one.getSystermType());
                    channelConfigInfoVos.add(configInfoVo);
                }
            });
            return GlobalResponse.success(channelConfigInfoVos);
        }
    }

    @Override
    public List<Long> getFundIds() {
        List<FundProductEntity> fundProductEntityList = fundProductRepository.getAllByEnableEquals(Byte.valueOf("1"));
        List<Long> fundIdList = new ArrayList<>();
        fundProductEntityList.stream().forEach(fundProductEntity -> {
            if (!fundIdList.contains(fundProductEntity.getFundId())){
                fundIdList.add(fundProductEntity.getFundId());
            }
        });
        return fundIdList;
    }

    @Override
    public List<Long> getFundCorpIdByFundId(Long fundId) {
        List<FundProductEntity> fundProductEntityList = fundProductRepository.getAllByFundIdEqualsAndEnableEquals(fundId,Byte.valueOf("1"));
        List<Long> fundCorpList = new ArrayList<>();
        fundProductEntityList.stream().forEach(fundProductEntity -> {
            if (!fundCorpList.contains(fundProductEntity.getFundProId())){
                fundCorpList.add(fundProductEntity.getFundProId());
            }
        });
        return fundCorpList;
    }

    @Override
    public FundProInfoVo getFundProductInfo(Long fundId, Long fundCorpId) {
        FundProductEntity fundProductEntity = fundProductRepository.getByFundIdEqualsAndFundProIdEqualsAndEnableEquals(fundId, fundCorpId, Byte.valueOf("1"));
        FundProInfoVo fundProInfoVo = new FundProInfoVo();
        BeanUtils.copyProperties(fundProductEntity,fundProInfoVo);
        return fundProInfoVo;
    }

    @Override
    @Transactional
    public void addChannelConfig(List<ChannelRouteSaveVo> channelRouteSaveVoList,Integer type) {
        /**
         * 编辑时要去掉所有该渠道有效性为0的其他配置（覆盖之前的未更新编辑信息）
         */
        if ( 0 != type ){
            channelRuleRepository.deleteAllByChannelIdEqualsAndEnableEquals(channelRouteSaveVoList.get(0).getChannelId(),Boolean.FALSE);
        }

        List<ChannelRuleEntity> channelRuleEntityList = getChannelRuleEntityList(channelRouteSaveVoList);

        channelRuleEntityList.stream().forEach(channelRuleEntity -> {
            FundProductEntity fundProductEntity = fundProductRepository.getByFundIdEqualsAndFundProIdEqualsAndEnableEquals(channelRuleEntity.getFundId(), channelRuleEntity.getFundProId(), Byte.valueOf("1"));
            if (Objects.nonNull(fundProductEntity)){
                channelRuleEntity.setFundProductId(fundProductEntity.getId());
                channelRuleEntity.setPublishStatus(0);
                if (0 == type){
                    channelRuleEntity.setEnable(true);
                }else {
                    channelRuleEntity.setEnable(false);
                }
                channelRuleEntity.setUserTag("["+channelRuleEntity.getUserTag()+"]");
                channelRuleEntity.setUserLevel("["+channelRuleEntity.getUserLevel()+"]");
                channelRuleRepository.save(channelRuleEntity);
            }
        });
    }

    private List<ChannelRuleEntity> getChannelRuleEntityList(List<ChannelRouteSaveVo> channelRouteSaveVoList){
        List<ChannelRuleEntity> channelRuleEntityList = new ArrayList<>();
        channelRouteSaveVoList.stream().forEach(channelRouteSaveVo -> {
            ChannelRuleEntity channelRuleEntity = new ChannelRuleEntity();
            BeanUtils.copyProperties(channelRouteSaveVo,channelRuleEntity);
            channelRuleEntityList.add(channelRuleEntity);
        });
        return channelRuleEntityList;
    }

    @Override
    public void publishChannelConfig(Long channelId) {
        List<ChannelRuleEntity> all = channelRuleRepository.getAllByChannelIdEqualsAndEnableEquals(channelId, Boolean.TRUE);

        all.stream().forEach(channelRuleEntity -> {
            channelRuleEntity.setPublishStatus(1);
            channelRuleRepository.save(channelRuleEntity);
        });
    }

    @Override
    @Transactional
    public void updateChannelConfig(Long channelId) {
        channelRuleRepository.deleteAllByChannelIdEqualsAndEnableEquals(channelId, Boolean.TRUE);
        List<ChannelRuleEntity> allByChannelIdEqualsAndEnableEquals = channelRuleRepository.getAllByChannelIdEqualsAndEnableEquals(channelId, Boolean.FALSE);
        allByChannelIdEqualsAndEnableEquals.stream().forEach(channelRuleEntity -> {
            channelRuleEntity.setEnable(true);
            channelRuleRepository.save(channelRuleEntity);
        });
    }
}
