package com.friday.custody.service.basicService.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.friday.custody.service.logicService.impl.DataDictionaryBasicServiceImpl;
import com.friday.custody.dao.InvestorBankInfoDao;
import com.friday.custody.entity.InvestorBankInfoEntity;
import com.friday.custody.enums.RetCodeEnum;
import com.friday.custody.exception.RRException;
import com.friday.custody.req.InvestorBankInfoReq;
import com.friday.custody.req.QueryDataReq;
import com.friday.custody.service.basicService.InvestorBankInfoService;
import com.friday.custody.service.logicService.DataProcessService;
import com.friday.custody.utils.PageUtil;
import com.friday.custody.utils.PageUtils;
import com.friday.custody.utils.Query;
import com.friday.custody.utils.R;
import com.friday.custody.vo.InvestorBankInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;


@Service("investorBankInfoService")
@Slf4j
public class InvestorBankInfoServiceImpl extends ServiceImpl<InvestorBankInfoDao, InvestorBankInfoEntity>
        implements InvestorBankInfoService , DataProcessService<InvestorBankInfoEntity> {

    @Autowired
    private DataDictionaryBasicServiceImpl dataDictionaryBasicService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public R saveData(String type, List<InvestorBankInfoEntity> datas) {
        if (CollectionUtils.isEmpty(datas)){
            return R.ok();
        }
        List<InvestorBankInfoEntity> investorBankInfoEntities = new ArrayList<>();
        for (InvestorBankInfoEntity entity : datas) {
            entity.setUniqueKey(entity.getAdmin() + entity.getBankNo() + entity.getTrustNo());
            if (StringUtils.isBlank(entity.getBankNo())){
                continue;
            }
            //97 第一创业、39 中金公司  若trade_acco为空，则该记录不落库
            if(("39".equals(entity.getTradeAcco()) || ("97".equals(entity.getTradeAcco())))
                    && StringUtils.isBlank(entity.getTradeAcco())){
                continue;
            }
            investorBankInfoEntities.add(entity);
        }

        List<InvestorBankInfoEntity> uniqueInvestrBankInfoList = investorBankInfoEntities.stream().collect(Collectors.collectingAndThen
                (Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing
                        (InvestorBankInfoEntity::getUniqueKey))), ArrayList::new));

        List<String> rawUniqueKeyList = uniqueInvestrBankInfoList
                .stream()
                .map(InvestorBankInfoEntity::getUniqueKey)
                .collect(Collectors.toList());

        String ukList = String.join("--", rawUniqueKeyList);
        if (CollectionUtils.isNotEmpty(rawUniqueKeyList)) {
            Set<String> uniqueKeySet = baseMapper.queryUniqueKeyList(rawUniqueKeyList);
            if (CollectionUtils.isNotEmpty(uniqueKeySet)) {
                baseMapper.deleteByUniqueKeys(uniqueKeySet);
            }

        }
        boolean saveStatus = this.saveBatch(uniqueInvestrBankInfoList);
        if (!saveStatus) {
            log.error("保存 InvestorBankInfo失败:{}", ukList);
        }
        return R.ok();
    }

    @Override
    public R queryData(QueryDataReq vo) {
        try {
            log.info("开始查询基金出资人银行账户基本信息表...,租户信息为:{}", JSON.toJSONString(vo));
            //1 封装查询参数
            InvestorBankInfoReq req = JSON.parseObject(vo.getParams(), InvestorBankInfoReq.class);
            //1.1 封装分页查询参数
            Map<String, Object> pageParams = PageUtil.getPageParams(req);
            //1.2 封装查询参数
            QueryWrapper<InvestorBankInfoEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("admin", vo.getTenantName());
            if (StringUtils.isNotBlank(req.getFundAcco())) {
                queryWrapper.eq("fund_acco", req.getFundAcco());
            }
            if (StringUtils.isNotBlank(req.getTradeAcco())) {
                queryWrapper.eq("trade_acco", req.getTradeAcco());
            }
            if (StringUtils.isNotBlank(req.getBankNoType())&&StringUtils.isNotBlank(req.getBankNo())) {
                queryWrapper.eq("bank_no_type", req.getBankNoType());
                queryWrapper.eq("bank_no", req.getBankNo());
            }else if(StringUtils.isNotBlank(req.getBankNoType()) && StringUtils.isBlank(req.getBankNo())){
                return R.error(RetCodeEnum.PARAM_ERROR.getCode(),"银行卡号/账号不能为空");
            }else if(StringUtils.isBlank(req.getBankNoType()) && StringUtils.isNotBlank(req.getBankNo())){
                return R.error(RetCodeEnum.PARAM_ERROR.getCode(),"银行号码类型不能为空");
            }
            //按银行号码bankNo（若存在）、交易账号tradeAcco（若存在）、基金账号fundAcco（若存在）、托管人编码trustNo逆序排列
            queryWrapper.orderBy(true,false, "bank_no","trade_acco","fund_acco","trust_no");

            //2 执行检索
            IPage<InvestorBankInfoEntity> page = this.page(
                    new Query<InvestorBankInfoEntity>().getPage(pageParams),
                    queryWrapper
            );
            //封装数据
            PageUtils pageUtils = new PageUtils(page);
            List<InvestorBankInfoEntity> entities = page.getRecords();
            //entities 转vo
            ArrayList<InvestorBankInfoVo> vos = new ArrayList<>();
            for (InvestorBankInfoEntity entity : entities) {
                vos.add(InvestorBankInfoVo.builder()
                        .id(entity.getId())
                        .fundAcco(entity.getFundAcco())
                        .bankCode(entity.getBankCode())
                        .branchBankName(entity.getBranchBankName())
                        .bankNoType(entity.getBankNoType())
                        .bankNo(entity.getBankNo())
                        .nameInBank(entity.getNameInBank())
                        .tradeAcco(entity.getTradeAcco())
                        .bankProvince(entity.getBankProvince())
                        .bankCity(entity.getBankCity())
                        .trustNo(entity.getTrustNo())
                        .build());
            }
            pageUtils.setList(vos);
            log.info("基金出资人银行账户基本信息查询成功...");
            return R.ok("基金出资人银行账户基本信息询成功").put("data",pageUtils);
        } catch (RRException rrException) {
            log.error("the QueryDataVo is :" + JSON.toJSONString(vo) + ".the InvestBankInfoServiceImpl RRException is :", rrException);
            return R.error(RetCodeEnum.OPERATION_ERROR.getCode(), rrException.getMsg());
        } catch (Exception e) {
            log.error("the QueryDataVo is :" + JSON.toJSONString(vo) + ".the InvestBankInfoServiceImpl Exception is :", e);
            return R.error(RetCodeEnum.OPERATION_ERROR.getCode(), "查询数据失败!");
        }
    }

    @Override
    public R updateData(String type, List<InvestorBankInfoEntity> datas) {
        return null;
    }

}