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

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.friday.custody.service.logicService.impl.DataDictionaryBasicServiceImpl;
import com.friday.custody.enums.DataDictionaryTypeEnum;
import com.friday.custody.enums.RetCodeEnum;
import com.friday.custody.exception.RRException;
import com.friday.custody.req.MjAccountSeqInfoReq;
import com.friday.custody.req.QueryDataReq;
import com.friday.custody.service.logicService.DataProcessService;
import com.friday.custody.utils.*;
import com.friday.custody.vo.MjAccountSeqInfoVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

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.dao.MjAccountSeqInfoDao;
import com.friday.custody.entity.MjAccountSeqInfoEntity;
import com.friday.custody.service.basicService.MjAccountSeqInfoService;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;


@Service("mjAccountSeqInfoService")
@Slf4j
public class MjAccountSeqInfoServiceImpl extends ServiceImpl<MjAccountSeqInfoDao, MjAccountSeqInfoEntity>
        implements MjAccountSeqInfoService, DataProcessService<MjAccountSeqInfoEntity> {

    @Autowired
    MjAccountSeqInfoDao mjAccountSeqInfoDao;
    @Autowired
    DataDictionaryBasicServiceImpl dataDictionaryBasicService;

    @Override
    public R saveData(String type, List<MjAccountSeqInfoEntity> datas) {
        int count = 0;
        String trustNo = null;
        for (MjAccountSeqInfoEntity entity : datas) {
            trustNo = entity.getTrustNo();
            try {
                //判断seqNo是否为空
                //1.如果不为空,根据admin,trustNo,seqNo查询是否已存在 如果已存在则不落库
                if (StringUtils.isNotBlank(entity.getSeqNo())) {
                    List<MjAccountSeqInfoEntity> mjAccountSeqInfoEntities = baseMapper.queryBySeqNo(entity.getSeqNo(), trustNo, entity.getAdmin());
                    if (!CollectionUtils.isEmpty(mjAccountSeqInfoEntities)) {
                        continue;
                    }
                    entity.setUniqueKey(entity.getAdmin() + entity.getTrustNo() + entity.getSeqNo());
                    baseMapper.insert(entity);
                    count++;
                }
                //2.如果为空, 根据【基金备案编码fundCode】、【对方账户opAccount】、【发生日期transferDate】、【发生时间tranferTime】、【银行摘要summary】查询是否已存在,如果已存在则不落库
                if (StringUtils.isBlank(entity.getSeqNo())) {
                    List<MjAccountSeqInfoEntity> mjAccountSeqInfoEntities = queryByEntity(entity);
                    if (!CollectionUtils.isEmpty(mjAccountSeqInfoEntities)) {
                        continue;
                    }
                    entity.setSeqNo(StrUtil.getRandomStr(32));
                    entity.setUniqueKey(entity.getAdmin() + entity.getFundCode() + entity.getOpAccount() + entity.getTransferDate() + entity.getTransferTime() + entity.getSummary());
                    baseMapper.insert(entity);
                    count++;
                }
            }catch (Exception e) {
                log.error("mjAccountSeqInfo保存数据失败!", e);
            }
        }
        log.info("trustNo ={}保存mjAccountSeqInfo数据{}条" , trustNo ,count);
        return R.ok();
    }

    private List<MjAccountSeqInfoEntity> queryByEntity(MjAccountSeqInfoEntity entity) {
        if (ObjectUtils.isEmpty(entity)) {
            return null;
        }
        LambdaQueryWrapper<MjAccountSeqInfoEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MjAccountSeqInfoEntity::getOpAccount, entity.getOpAccount());
        queryWrapper.eq(MjAccountSeqInfoEntity::getTransferDate, entity.getTransferDate());
        queryWrapper.eq(MjAccountSeqInfoEntity::getTransferTime, entity.getTransferTime());
        queryWrapper.eq(MjAccountSeqInfoEntity::getSummary, entity.getSummary());
        return baseMapper.selectList(queryWrapper);
    }

    @Override
    public R queryData(QueryDataReq vo) {
        try {
            log.info("开始查询募集户流水信息表...,租户信息为:{}", JSON.toJSONString(vo));
            //1 封装查询参数
            MjAccountSeqInfoReq mjAccountSeqInfoReq = JSON.parseObject(vo.getParams(), MjAccountSeqInfoReq.class);
            //1.1 封装分页查询参数
            Map<String, Object> pageParams = PageUtil.getPageParams(mjAccountSeqInfoReq);
            //1.2 封装查询参数
            QueryWrapper<MjAccountSeqInfoEntity> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("admin", vo.getTenantName());
            if (StringUtils.isNotBlank(mjAccountSeqInfoReq.getFundCode())) {
                queryWrapper.eq("fund_code", mjAccountSeqInfoReq.getFundCode());
            }
            if (StringUtils.isNotBlank(mjAccountSeqInfoReq.getAccount())) {
                queryWrapper.eq("account", mjAccountSeqInfoReq.getAccount());
            }
            if (StringUtils.isNotBlank(mjAccountSeqInfoReq.getInnerFundCode())){
                queryWrapper.eq("inner_fund_code",mjAccountSeqInfoReq.getInnerFundCode());
            }
            //（按本方银行账号account（若存在）、发生日期transferDate（若存在）、发生时间transferTime（若存在）、托管人编码trustNo逆序排列）
            queryWrapper.orderBy(true,false, "account","transfer_date","transfer_time","trust_no");

            //2 执行检索
            IPage<MjAccountSeqInfoEntity> page = this.page(
                    new Query<MjAccountSeqInfoEntity>().getPage(pageParams),
                    queryWrapper
            );
            //封装数据
            PageUtils pageUtils = new PageUtils(page);
            List<MjAccountSeqInfoEntity> entities = page.getRecords();
            //entities 转vo
            ArrayList<MjAccountSeqInfoVo> vos = new ArrayList<>();
            for (MjAccountSeqInfoEntity entity : entities) {
                vos.add(MjAccountSeqInfoVo.builder()
                        .id(entity.getId())
                        .seqNo(entity.getSeqNo())
                        .fundCode(entity.getFundCode())
                        .innerFundCode(entity.getInnerFundCode())
                        .fundName(entity.getFundName())
                        .transferInOut(entity.getTransferInOut())
                        .bankName(entity.getBankName())
                        .account(entity.getAccount())
                        .accountName(entity.getAccountName())
                        .opBankName(entity.getOpBankName())
                        .opAccount(entity.getOpAccount())
                        .opAccountName(entity.getOpAccountName())
                        .amount(entity.getAmount()==null?null:entity.getAmount().toString())
                        .balance(Objects.isNull(entity.getBalance())?null:entity.getBalance().toString())
                        .transferDate(Objects.isNull(entity.getTransferDate())?null:entity.getTransferDate().split(" ")[0].replace("-",""))
                        .transferTime(entity.getTransferTime())
                        .currency(entity.getCurrency())
                        .summary(entity.getSummary())
                        .remark(entity.getRemark())
                        .updateDate(entity.getUpdateDate())
                        .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 MjAccountSeqInfoServiceImpl RRException is :", rrException);
            return R.error(RetCodeEnum.OPERATION_ERROR.getCode(), rrException.getMsg());
        } catch (Exception e) {
            log.error("the QueryDataVo is :" + JSON.toJSONString(vo) + ".the MjAccountSeqInfoServiceImpl Exception is :", e);
            return R.error(RetCodeEnum.OPERATION_ERROR.getCode(), "查询数据失败!");
        }
    }

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

    public List<String> getBankAccoList(String trustNo,String admin){
        return mjAccountSeqInfoDao.getBankAccoList(trustNo,admin);
    }

    public List<String> getFundCodeList(String trustNo){
        return mjAccountSeqInfoDao.getFundCodeList(trustNo);
    }

    @Override
    public R tranferAndSaveDataBatch(List<MjAccountSeqInfoEntity> mjAccountSeqInfoEntities) {
        if (!CollectionUtils.isEmpty(mjAccountSeqInfoEntities)) {

            Optional<MjAccountSeqInfoEntity> optionalMjAccountSeqInfo = mjAccountSeqInfoEntities.stream().findAny();
            if (optionalMjAccountSeqInfo.isPresent()){
            String trustNo = optionalMjAccountSeqInfo.get().getTrustNo();
            //1、获取字典
            Map<String, String> paymentDirectionDic = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.PAYMENT_DIRECTION_SERVICE, trustNo);//收付方向
            Map<String, String> currencyDic = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.CURRENCY_SERVICE, trustNo);//币种
            //2.数据字典翻译
            List<MjAccountSeqInfoEntity> collect = null;
            if ("25".equals(trustNo)) {
                collect = mjAccountSeqInfoEntities.stream().map(item -> {
                    String transferInOut = MatchDataDictionaryKeyUtil.getKey(paymentDirectionDic, item.getTransferInOut());
                    log.info("getMjAccountSeqInfoData_transferInOut_原值={}，映射值={}", item.getTransferInOut(), transferInOut);
                    item.setTransferInOut(transferInOut);
                    String currency = MatchDataDictionaryKeyUtil.getKey(currencyDic, item.getCurrency());
                    log.info("getMjAccountSeqInfoData_currency_原值={}，映射值={}", item.getCurrency(), currency);
                    item.setCurrency(currency);
                    return item;
                }).collect(Collectors.toList());
            }
            if ("21".equals(trustNo)){
                collect = mjAccountSeqInfoEntities.stream().map(item -> {
                    String transferInOut = MatchDataDictionaryKeyUtil.getKey(paymentDirectionDic, item.getTransferInOut());
                    log.info("getMjAccountSeqInfoData_transferInOut_原值={}，映射值={}", item.getTransferInOut(), transferInOut);

                    Map<String, String> paymentDir = dataDictionaryBasicService.queryWithDetail(DataDictionaryTypeEnum.PAYMENT_DIRECTION_SERVICE, trustNo);
                    String directFlag = MatchDataDictionaryKeyUtil.getKey(paymentDir, item.getTransferInOut());
                    String opAccount = "";
                    String opAccountName = "";
                    String opBankName = "";
                    String account = "";
                    String accountName = "";
                    String bankName = "";
                    if("收".equals(directFlag)){
                        opAccount = item.getOpAccount();
                        opAccountName = item.getOpAccountName();
                        opBankName = item.getOpBankName();
                        account = item.getAccount();
                        accountName = item.getAccountName();
                        bankName = item.getBankName();
                    }else if("付".equals(directFlag)){
                        account = item.getOpAccount();
                        accountName = item.getOpAccountName();
                        bankName = item.getOpBankName();
                        opAccount = item.getAccount();
                        opAccountName = item.getAccountName();
                        opBankName = item.getBankName();
                    }

                    String bankJour = item.getSeqNo();
                    if(StringUtils.isNotBlank(bankJour) && bankJour.length()>32 ){
                        bankJour = bankJour.substring(0,32);
                    }
                    item.setOpAccount(opAccount);
                    item.setOpAccountName(opAccountName);
                    item.setOpBankName(opBankName);
                    item.setAccount(account);
                    item.setAccountName(accountName);
                    item.setBankName(bankName);

                    item.setTransferInOut(transferInOut);
                    return item;
                }).collect(Collectors.toList());
            }
            //3.保存
            this.saveData(null, collect);
            return R.ok();
        }
        }
        log.error("tranferAndSaveDataBatch:集合为空");
        return null;
    }
}