package com.kcim.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.kcim.common.constants.NumberConstant;
import com.kcim.common.exception.CostException;
import com.kcim.common.util.BeanUtil;
import com.kcim.common.util.JacksonUtil;
import com.kcim.common.util.PageUtils;
import com.kcim.common.util.UserContext;
import com.kcim.dao.mapper.CostAccountShareMapper;
import com.kcim.dao.model.*;
import com.kcim.dao.model.dto.AccountShareCopyDto;
import com.kcim.dao.model.dto.CostAccountShareEditDto;
import com.kcim.dao.model.dto.CostAccountShareSaveDto;
import com.kcim.dao.model.dto.ShareParamEditDto;
import com.kcim.dao.repository.CostAccountShareDetailRepository;
import com.kcim.dao.repository.CostAccountShareParamRepository;
import com.kcim.dao.repository.CostAccountShareTargetRepository;
import com.kcim.service.*;
import com.kcim.vo.*;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

@Slf4j
@AllArgsConstructor
@Service("costAccountShareService")
public class CostAccountShareServiceImpl extends ServiceImpl<CostAccountShareMapper, CostAccountShare> implements CostAccountShareService {

    private final ResponsibilityService responsibilityService;

    private final AccountingService accountingService;

    private final CostShareLevelService costShareLevelService;

    private final CostShareParamService costShareParamService;

    private final CostAccountShareDetailRepository costAccountShareDetailRepository;
    private final CostAccountShareParamRepository costAccountShareParamRepository;
    private final CostAccountShareTargetRepository costAccountShareTargetRepository;


//    public CostAccountShareServiceImpl(CostAccountShareParamService costAccountShareParamService,CostAccountShareDetailService costAccountShareDetailService,ResponsibilityService responsibilityService, AccountingService accountingService, CostShareLevelService costShareLevelService, CostShareParamService costShareParamService) {
//        this.responsibilityService = responsibilityService;
//        this.accountingService = accountingService;
//        this.costShareLevelService = costShareLevelService;
//        this.costShareParamService = costShareParamService;
//        this.costAccountShareDetailService = costAccountShareDetailService;
//        this.costAccountShareParamService = costAccountShareParamService;
//    }

    /**
     * 分页查询责任中心成本对照相关数据
     *
     * @param current
     * @param pageSize
     * @param name
     * @return
     */
    @Override
    public PageUtils queryList(Integer current, Integer pageSize, String name, Long hospId) {
        Page<CostAccountShare> costAccountSharePage = new Page<>(current, pageSize);
        Page<CostAccountShare> pages = this.page(costAccountSharePage, new QueryWrapper<CostAccountShare>().lambda()
                .eq(!StringUtils.isEmpty(hospId), CostAccountShare::getHospId, hospId)
                .like(!StringUtils.isEmpty(name), CostAccountShare::getResponsibilityName, name)
                .orderByAsc(CostAccountShare::getShareLevel));
        List<CostAccountShare> costAccountShareList = pages.getRecords();


        List<Responsibility> responsibilities = responsibilityService.list(
                new LambdaQueryWrapper<Responsibility>()
                        .eq(Responsibility::getHospId, UserContext.getHospId())
                        .orderByDesc(Responsibility::getCreateTime)
        );

        Map<Long, String> map = new HashMap<>();
        if (!CollectionUtils.isEmpty(responsibilities)) {
            map = responsibilities.stream().collect(Collectors.toMap(Responsibility::getId, Responsibility::getShareName, (a, b) -> b));
        }

        List<CostAccountShareVO> costAccountShareVOList = BeanUtil.convertList(costAccountShareList, CostAccountShareVO.class);
        for (CostAccountShareVO i : costAccountShareVOList) {
            String accountingIds = i.getAccountingIds();
            if (StrUtil.isNotBlank(accountingIds)) {
                List<String> list = Arrays.asList(accountingIds.split(StrUtil.COMMA));
                i.setAccountingIdList(list);
            } else {
                i.setAccountingIdList(null);
            }
            if (!CollectionUtils.isEmpty(map)) {
                i.setShareName(map.get(i.getResponsibilityId()));
            }
            if (!StringUtils.isEmpty(i.getParamList())) {
                List<AccountShareVO> accountShareVOs = JacksonUtil.str2ObjList(i.getParamList(), List.class, AccountShareVO.class);
                if (!CollectionUtils.isEmpty(accountShareVOs)) {
                    StringBuilder shareParamBuilder = new StringBuilder();
                    for (AccountShareVO accountShareVO : accountShareVOs) {
                        shareParamBuilder.append(accountShareVO.getShareParamName()).append("x").append(accountShareVO.getShareParamPopout()).append("%").append("|");
                    }
                    i.setShareParamMap(org.apache.commons.lang3.StringUtils.removeEnd(shareParamBuilder.toString(), "|"));
                }
            }
        }
//        getMessage(hospId, costAccountShareVOList);
        PageUtils pageUtils = new PageUtils(pages);
        pageUtils.setList(costAccountShareVOList);
        return pageUtils;
    }

//    private void getMessage(Long hospId, List<CostAccountShareVO> costAccountShareList) {
//        // 设置责任中心的数据 与 会计科目的数据从对应的id里面获取
//        List<Responsibility> list = responsibilityService.list(new QueryWrapper<Responsibility>().lambda().eq(Responsibility::getHospId, hospId));
//        List<Accounting> accountingList = accountingService.list(new QueryWrapper<Accounting>().lambda().eq(Accounting::getHospId, hospId));
//        Map<Long, List<Responsibility>> resMap = list.stream().collect(Collectors.groupingBy(Responsibility::getId));
//        Map<Long, List<Accounting>> accountMap = accountingList.stream().collect(Collectors.groupingBy(Accounting::getId));
//        costAccountShareList.forEach(i->{
//            Long id = i.getResponsibilityId();
//            List<Responsibility> responsibilities = resMap.get(id);
//            if (!CollectionUtils.isEmpty(responsibilities)){
//                i.setResponsibilityId(id);
//                i.setResponsibilityName(responsibilities.get(0).getResponsibilityName());
//                i.setResponsibilityCode(responsibilities.get(0).getResponsibilityCode());
//
//            }
//            Long accountingId = i.getAccountingId();
//            if (accountingId>0){
//                List<Accounting> accountingList1 = accountMap.get(accountingId);
//                if (!CollectionUtils.isEmpty(accountingList1)){
//                    i.setAccountingId(accountingId);
//                    i.setAccountingName(accountingList1.get(0).getAccountingName());
//                    i.setAccountingCode(accountingList1.get(0).getAccountingCode());
//                    i.setAllParentIds(accountingList1.get(0).getAllParentIds());
//                }
//            }
//        });
//    }

    /**
     * 保存成本参数对应成本对照表
     *
     * @param costAccountShareSaveDto {@link CostAccountShareSaveDto}
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void addCostAccountShare(CostAccountShareSaveDto costAccountShareSaveDto) {
        Long hospId = UserContext.getCurrentLoginHospId();
        // 检验输入的数据的合理性
        checkAccountShare(costAccountShareSaveDto, hospId,null);
        CostAccountShare costAccountShareRequest = BeanUtil.convertObj(costAccountShareSaveDto, CostAccountShare.class);
        costAccountShareRequest.setHospId(hospId);
        costAccountShareRequest.setCreateTime(System.currentTimeMillis());
        baseMapper.insert(costAccountShareRequest);
        //提交分摊设置对应的会计科目
        applyShareParamProportion(costAccountShareRequest.getId(),costAccountShareRequest.getAccountingCodes());
    }

    /**
     * 检验输入数据的合理性
     *
     * @param costAccountShareSaveDto
     * @param hospId
     */
    private void checkAccountShare(CostAccountShareSaveDto costAccountShareSaveDto, Long hospId,CostAccountShare oldCostAccountShare) {
        Long responsibilityId = costAccountShareSaveDto.getResponsibilityId();
        Responsibility responsibility = responsibilityService.getOne(new QueryWrapper<Responsibility>().lambda().eq(Responsibility::getHospId, hospId).eq(Responsibility::getId, responsibilityId));
        if (Objects.isNull(responsibility)) {
            throw new CostException(500, "输入的责任不存在");
        }
        costAccountShareSaveDto.setResponsibilityId(responsibilityId);
        costAccountShareSaveDto.setResponsibilityCode(responsibility.getResponsibilityCode());
        costAccountShareSaveDto.setResponsibilityName(responsibility.getResponsibilityName());
        costAccountShareSaveDto.setShareLevel(responsibility.getShareLevel());
        //获取责任中心的其他设置记录
        List<CostAccountShare> costAccountShareList = getResponsibilityOtherRecords(costAccountShareSaveDto,hospId,oldCostAccountShare);
        if (!StringUtils.isEmpty(costAccountShareSaveDto.getAccountingIds())) {
            // 这个责任中心允许输入会计科目
            List<Long> accountIdList = Arrays.stream(costAccountShareSaveDto.getAccountingIds().split(StrUtil.COMMA)).map(Long::valueOf).collect(Collectors.toList());
            List<Accounting> accountingList = accountingService.list(new QueryWrapper<Accounting>().lambda().eq(Accounting::getHospId, hospId).in(Accounting::getId, accountIdList).orderByDesc(Accounting::getCreateTime));
            if (CollectionUtils.isEmpty(accountingList)) {
                throw new CostException(500, "输入的会计科目不存在");
            } else {
                String accountIds = accountingList.stream().map(Accounting::getId).collect(Collectors.toList()).stream().map(String::valueOf).collect(Collectors.joining(StrUtil.COMMA));
                costAccountShareSaveDto.setAccountingIds(accountIds);
                String accountNames = accountingList.stream().map(Accounting::getAccountingName).map(String::valueOf).collect(Collectors.joining(StrUtil.COMMA));
                costAccountShareSaveDto.setAccountingNames(accountNames);
                String accountCodes = accountingList.stream().map(Accounting::getAccountingCode).map(String::valueOf).collect(Collectors.joining(StrUtil.COMMA));
                costAccountShareSaveDto.setAccountingCodes(accountCodes);
            }
//            Map<String, List<CostAccountShare>> costAccountMap = costAccountShareList.stream().collect(Collectors.groupingBy(CostAccountShare::getResponsibilityCode));
//            List<CostAccountShare> list = costAccountMap.get(costAccountShareSaveDto.getResponsibilityCode());
            if (!CollectionUtils.isEmpty(costAccountShareList)) {
                costAccountShareList.forEach(i -> {
                    String accountingIds = i.getAccountingIds();
                    Integer isShareCost = i.getIsShareCost();
                    List<Long> accountIdListRequest = Arrays.stream(accountingIds.split(StrUtil.COMMA)).map(Long::valueOf).collect(Collectors.toList());
                    if (!Collections.disjoint(accountIdListRequest, accountIdList)) {
                        throw new CostException(500, "存在相同的会计科目数据");
                    }
                    if (NumberConstant.ONE.equals(isShareCost) && NumberConstant.ONE.equals(costAccountShareSaveDto.getIsShareCost())) {
                        throw new CostException(500, "同个责任中心只允许一条设置包含分摊成本");
                    }
                });
            }
        } else {
            // 此时是
            // 责任中心只允许出现一次
            if (!CollectionUtils.isEmpty(costAccountShareList)) {
                throw new CostException(500, "该责任中心合并计算已存在");
            }
            if (!NumberConstant.ONE.equals(costAccountShareSaveDto.getIsShareCost())) {
                throw new CostException(500, "合并计算责任中心必须要设置成包含分摊参数");
            }
        }
        // 检验输入的这个责任中心是否允许输入会计科目
        Long shareId = responsibility.getShareId();
        CostShareLevel costShareLevel = costShareLevelService.getOne(new QueryWrapper<CostShareLevel>().lambda()
                .eq(CostShareLevel::getHospId, hospId).eq(CostShareLevel::getId, shareId));
        if (Objects.nonNull(costShareLevel)) {
            if ((!StringUtils.isEmpty(costAccountShareSaveDto.getAccountingIds())) && NumberConstant.ZERO.equals(costShareLevel.getCalcType())) {
                throw new CostException(500, "合并计算不允许选择会计科目");
            }
            if ((StringUtils.isEmpty(costAccountShareSaveDto.getAccountingIds())) && NumberConstant.ONE.equals(costShareLevel.getCalcType())) {
                throw new CostException(500, "分开计算的责任中心需要选择会计科目");
            }
        } else {
            throw new CostException(500, "对不起该责任中心没有对应分摊层级");
        }
        //合并计算的配置将责任中心名称作为会计科目名称(会计科目名称不能为空，不然后续报表会报错)
        if(NumberConstant.ZERO.equals(costShareLevel.getCalcType())){
            costAccountShareSaveDto.setAccountingCodes(costAccountShareSaveDto.getResponsibilityCode());
            costAccountShareSaveDto.setAccountingNames(costAccountShareSaveDto.getResponsibilityName());
        }
    }

    /**
     * 获取责任中心的其他设置记录
     * @param costAccountShareSaveDto
     * @param hospId
     * @param oldCostAccountShare
     * @return
     */
    public List<CostAccountShare> getResponsibilityOtherRecords(CostAccountShareSaveDto costAccountShareSaveDto, Long hospId,CostAccountShare oldCostAccountShare){
        LambdaQueryWrapper<CostAccountShare> costAccountShareQuery = new QueryWrapper<CostAccountShare>().lambda().eq(CostAccountShare::getHospId, hospId).eq(CostAccountShare::getResponsibilityId, costAccountShareSaveDto.getResponsibilityId());
        //修改时需排除掉自己
        if(!ObjectUtils.isEmpty(oldCostAccountShare)){
            costAccountShareQuery=costAccountShareQuery.ne(CostAccountShare::getId,oldCostAccountShare.getId());
        }
        List<CostAccountShare> costAccountShareList = baseMapper.selectList(costAccountShareQuery);
        return costAccountShareList;
    }


    /**
     * 修改成本分摊参数对应表
     *
     * @param costAccountShareEditDto
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void updateByCostAccountShare(CostAccountShareEditDto costAccountShareEditDto) {
        Long hospId = UserContext.getCurrentLoginHospId();
        Long id = costAccountShareEditDto.getId();
        CostAccountShare costAccountShare = baseMapper.selectById(id);
        if (Objects.isNull(costAccountShare)) {
            throw new CostException(500, "成本分摊参数对应数据不存在");
        }
//        baseMapper.deleteById(id);
        // 新增责任中心成本对照数据
        CostAccountShareSaveDto costAccountShareSaveDto = BeanUtil.convertObj(costAccountShareEditDto, CostAccountShareSaveDto.class);
        // 检验输入的数据是否符合规则
        checkAccountShare(costAccountShareSaveDto, hospId,costAccountShare);
        CostAccountShareEditDto accountShareEditDto = BeanUtil.convertObj(costAccountShareSaveDto, CostAccountShareEditDto.class);
        BeanUtil.convertObj(accountShareEditDto, costAccountShare);
        costAccountShare.setId(costAccountShareEditDto.getId());
        baseMapper.updateById(costAccountShare);
        //提交分摊设置对应的会计科目
        applyShareParamProportion(costAccountShare.getId(),costAccountShare.getAccountingCodes());
    }

    /**
     * 提交分摊设置对应的会计科目
     * @param accountShareId
     * @param accountingCodes
     */
    public void applyShareParamProportion(Long accountShareId , String accountingCodes ){
        if(StringUtils.isEmpty(accountingCodes)){
            //先作废上次的数据
            costAccountShareDetailRepository.delCostAccountShareDetail(accountShareId);
            return;
        }
        List<String> accountingCodeList = Arrays.stream(accountingCodes.split(StrUtil.COMMA)).collect(Collectors.toList());
        applyAccountShareDetail(accountShareId,accountingCodeList);
    }


    /**
     * 提交分摊设置对应的会计科目
     * @param accountShareId
     * @param accountingCodeList
     */
    public void applyAccountShareDetail(Long accountShareId , List<String> accountingCodeList){
        //先作废上次的数据
        costAccountShareDetailRepository.delCostAccountShareDetail(accountShareId);
        //保存新的分摊参数
        List<CostAccountShareDetail> costAccountShareDetailList = accountingCodeList.stream().map(accountingCode ->
                createCostAccountShareDetail(accountShareId,accountingCode)).collect(Collectors.toList());
        costAccountShareDetailRepository.saveBatch(costAccountShareDetailList);
    }


    /**
     * 修改成本分摊参数的设置
     *
     * @param shareParamEditDto
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void updateShareParam(ShareParamEditDto shareParamEditDto) {
        List<ShareParamProportionVO> shareParamProportionVOList1 = shareParamEditDto.getShareParamProportionVOList();
        Long hospId = UserContext.getHospId();
        Long id = shareParamEditDto.getId();
        CostAccountShare costAccountShare = baseMapper.selectOne(new QueryWrapper<CostAccountShare>().lambda()
                .eq(CostAccountShare::getHospId, hospId)
                .eq(CostAccountShare::getId, id));
        if (Objects.isNull(costAccountShare)) {
            throw new CostException(500, "分摊参数对应数据不存在");
        }
        if (!CollectionUtils.isEmpty(shareParamProportionVOList1)) {
            List<ShareParamProportionVO> shareParamProportionVOList = shareParamEditDto.getShareParamProportionVOList();
            // 检验输入的成本分摊参数是否存在
            List<CostShareParamVO> costShareParamServiceAll = costShareParamService.getAll(hospId);
            Map<Long, List<CostShareParamVO>> listMap = costShareParamServiceAll.stream().collect(Collectors.groupingBy(CostShareParamVO::getId));
            shareParamProportionVOList.forEach(i -> {
                if (CollectionUtils.isEmpty(listMap.get(i.getId()))) {
                    throw new CostException(500, "分摊名称:" + i.getShareParamName() + "未找到");
                }
            });
            // 检验输入的数据的和是否是100
            AtomicReference<BigDecimal> sum = new AtomicReference<>(new BigDecimal("0.00"));
            shareParamProportionVOList.forEach(i -> {
                sum.updateAndGet(v -> v.add(i.getShareParamPopout()));
            });
            if (sum.get().compareTo(new BigDecimal("100.00"))!=0) {
                throw new CostException(500, "分摊比例的和不是100");
            }

            // 判断添加的分摊是否存在一样的
            HashMap<Long, ShareParamProportionVO> hashMap = new HashMap<>();
            shareParamProportionVOList.forEach(i -> {
                Long paramId = i.getId();
                if (hashMap.containsKey(paramId)) {
                    throw new CostException(500, "不可以添加相同的分摊参数");
                }
                hashMap.put(paramId, i);
            });
            //
//            String paramList = JsonUtil.toJSONString(shareParamProportionVOList);
            String paramList = JacksonUtil.obj2StrPretty(shareParamProportionVOList);

            costAccountShare.setParamList(paramList);
            //提交分摊参数
            applyShareParamProportion(shareParamEditDto);
        } else {
            costAccountShare.setParamList(null);
        }

        baseMapper.updateById(costAccountShare);
    }

    /**
     * 提交分摊参数
     * @param shareParamEditDto
     */
    public void applyShareParamProportion(ShareParamEditDto shareParamEditDto){
        //先作废上次的数据
        costAccountShareParamRepository.delCostAccountParamDetail(shareParamEditDto.getId());
        //保存新的分摊参数
        List<ShareParamProportionVO> newShareParamList = shareParamEditDto.getShareParamProportionVOList();
        List<CostAccountShareParam> costAccountShareParamList = newShareParamList.stream().map(newShareParam ->
                createCostAccountShareParam(shareParamEditDto.getId(),newShareParam.getShareParamCode(),newShareParam.getShareParamPopout())).collect(Collectors.toList());
        costAccountShareParamRepository.saveBatch(costAccountShareParamList);
    }

    /**
     * 获取责任中心成本表的分摊参数的集合
     *
     * @param id
     * @param hospId
     * @return
     */
    @Override
    public List<ShareParamProportionVO> selectShareParamById(Integer id, Long hospId) {
        CostAccountShare costAccountShare = baseMapper.selectOne(new QueryWrapper<CostAccountShare>().lambda()
                .eq(CostAccountShare::getHospId, hospId).eq(CostAccountShare::getId, id));
        if (Objects.isNull(costAccountShare)) {
            throw new CostException(500, "责任中心成本不存在");
        }
        String paramList = costAccountShare.getParamList();
//        return JsonUtil.toList(paramList, ShareParamProportionVO.class);
//        return JacksonUtil.string2ObjList(paramList, List.class, ShareParamProportionVO.class);
        return JacksonUtil.str2ObjList(paramList, new TypeReference<List<ShareParamProportionVO>>() {
        });
    }

    /**
     * 成本分摊参数中被分摊参数对应选中的状态
     *
     * @param id
     * @param hospId
     * @return
     */
    @Override
    public List<CostShareParamStatusVO> getAllShareParamStatusById(Integer id, Long hospId) {
        List<CostShareParamVO> costShareParamServiceAll = costShareParamService.getAll(hospId);
        CostAccountShare costAccountShare = baseMapper.selectById(id);
        if (Objects.isNull(costAccountShare)) {
            throw new CostException(500, "成本分摊对应数据不存在");
        }
        String paramList = costAccountShare.getParamList();
        List<CostShareParamStatusVO> costShareParamStatusVOList = BeanUtil.convertList(costShareParamServiceAll, CostShareParamStatusVO.class);
        if (!StringUtils.isEmpty(paramList)) {
//            List<ShareParamProportionVO> shareParamProportionVOList = JsonUtil.toList(paramList, ShareParamProportionVO.class);
            List<ShareParamProportionVO> shareParamProportionVOList = JacksonUtil.str2ObjList(paramList, new TypeReference<List<ShareParamProportionVO>>() {
            });
            Map<Long, List<ShareParamProportionVO>> map = shareParamProportionVOList.stream().collect(Collectors.groupingBy(ShareParamProportionVO::getId));
            costShareParamStatusVOList.forEach(i -> {
                Long paramId = i.getId();
                if (!CollectionUtils.isEmpty(map.get(paramId))) {
                    i.setShareParamStatus(NumberConstant.ONE);
                }
            });
        }
        return costShareParamStatusVOList;
    }

    /**
     * 拷贝
     *
     * @param accountShareCopyDto 赋值数据
     * @param hospId              医院Id
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void copyAccountShareData(AccountShareCopyDto accountShareCopyDto, Long hospId) {
        Long id = accountShareCopyDto.getId();
        CostAccountShare costAccountShare = this.getById(id);
        if (Objects.isNull(costAccountShare)) {
            throw new CostException(500, "成本分摊参数设置对应数据不存在");
        }
        List<CostAccountShare> accountShareList = new ArrayList<>();
        List<Long> responsibilityIds = accountShareCopyDto.getResponsibilityIds();
        Map<Long, Responsibility> responsibilityMap = responsibilityService.list(new QueryWrapper<Responsibility>().lambda()
                .eq(Responsibility::getHospId, hospId)).stream().collect(Collectors.toMap(Responsibility::getId, synOne -> synOne));
        long millis = System.currentTimeMillis();

        responsibilityIds.forEach(i -> {
            CostAccountShare accountShareRequest = BeanUtil.convertObj(costAccountShare, CostAccountShare.class);
            accountShareRequest.setId(null);
            accountShareRequest.setCreateTime(millis);
            Responsibility responsibility = responsibilityMap.get(i);
            accountShareRequest.setResponsibilityId(i);
            accountShareRequest.setResponsibilityCode(responsibility.getResponsibilityCode());
            accountShareRequest.setResponsibilityName(responsibility.getResponsibilityName());
            accountShareRequest.setShareLevel(responsibility.getShareLevel());
            accountShareList.add(accountShareRequest);
        });
        this.saveBatch(accountShareList);
        //主表向明细表同步
        synMainCostAccountShare(accountShareList);
        //复制目标责任中心设置
        copyCostAccountShareTarget(accountShareCopyDto,accountShareList);
    }

    /**
     * 获取指定类型的责任中心集合 分开计算还是合并计算
     *
     * @param accountShareId
     * @param hospId
     * @return
     */
    @Override
    public List<Responsibility> getResponsibilityCalType(Long accountShareId, Long hospId) {
        CostAccountShare costAccountShare = this.getById(accountShareId);
        if (Objects.isNull(costAccountShare)) {
            throw new CostException(500, "成本分摊参数设置对应数据不存在");
        }
        Long responsibilityId = costAccountShare.getResponsibilityId();
        Responsibility responsibility = responsibilityService.getById(responsibilityId);
        Long shareId = responsibility.getShareId();
        CostShareLevel costShareLevel = costShareLevelService.getById(shareId);
        Integer calcType = costShareLevel.getCalcType();
        // 分摊参数设置对饮的责任中心的id集合
//        List<Long> responsibilityIds = this.list(new QueryWrapper<CostAccountShare>().lambda().eq(CostAccountShare::getHospId, hospId)).stream().map(CostAccountShare::getResponsibilityId).distinct().collect(Collectors.toList());
        // 执行类型的分摊级别的Id的集合
        List<Long> costShareIds = costShareLevelService.list(new QueryWrapper<CostShareLevel>().lambda()
                        .eq(CostShareLevel::getHospId, hospId).eq(CostShareLevel::getCalcType, calcType))
                .stream().map(CostShareLevel::getId).distinct().collect(Collectors.toList());
        String accountingIds = costAccountShare.getAccountingIds();
//        List<Long> responsibilityIdList=null;
//        if (StrUtil.isNotBlank(accountingIds)){
//            List<String> accountIdList = Arrays.asList(accountingIds.split(StrUtil.COMMA));
//            responsibilityIdList= baseMapper.getResponsibilityIdsByAccountId(accountIdList);
//        }
        // 筛选指定类型的责任中心 并且当前没有设置的责任中心
//        List<Long> finalResponsibilityIdList = responsibilityIdList;
        List<Responsibility> responsibilityList = responsibilityService.list(new QueryWrapper<Responsibility>().lambda()
                        .eq(Responsibility::getHospId, hospId)
                        .ne(Responsibility::getShareId, NumberConstant.ZERO))
                .stream().filter(i -> costShareIds.contains(i.getShareId()) && !responsibilityId.equals(i.getId())).collect(Collectors.toList());
//        && (CollUtil.isNotEmpty(finalResponsibilityIdList) && !finalResponsibilityIdList.contains(i.getId()))
        return responsibilityList;
    }

    /**
     * 通过责任中心得到对应的成本分摊参数对应
     *
     * @param responsibilityCode 责任中心code
     * @param hospId             医院id
     * @return 成本分摊参数对应列表
     */
    @Override
    public List<CostAccountShare> getByResponsibility(String responsibilityCode, Long hospId) {
        List<CostAccountShare> list = this.list(
                new LambdaQueryWrapper<CostAccountShare>()
                        .eq(CostAccountShare::getResponsibilityCode, responsibilityCode)
                        .eq(CostAccountShare::getHospId, hospId)
        );
        return list;
    }

    @Override
    public List<CostAccountShare> getByShareLevelSort(List<Integer> levelSorts, Long hospId) {
        return this.list(
                new LambdaQueryWrapper<CostAccountShare>()
                        .eq(CostAccountShare::getHospId, hospId)
                        .in(CostAccountShare::getShareLevel, levelSorts)
        );
    }

    /**
     * 删除成本分摊参数对应数据
     *
     * @param idList id集合
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public void deleteByIds(List<Long> idList) {
        this.removeByIds(idList);
        costAccountShareDetailRepository.delCostAccountShareDetailList(idList);
        costAccountShareParamRepository.delCostAccountShareParamList(idList);
    }

    @Override
    public List<CostAccountShare> getAll() {
        return this.list(
                new LambdaQueryWrapper<CostAccountShare>()
                        .eq(CostAccountShare::getHospId, UserContext.getHospId())
        );
    }

    /**
     *
     * @param direction 1主表向明细表同步 2明细表向主表同步
     * @param accountShareId
     */
    @Override
    @Transactional(rollbackFor = Throwable.class, propagation = Propagation.REQUIRED)
    public void synCostAccountShare(Integer direction, Long accountShareId) {
        if(NumberConstant.ONE.equals(direction)){
            synMainCostAccountShare(direction,accountShareId);
        }
    }

    /**
     * 主表向明细表同步
     * @param direction
     * @param accountShareId
     */
    public void synMainCostAccountShare(Integer direction, Long accountShareId) {
        List<CostAccountShare> costAccountShareList = getCostAccountShareList(accountShareId);
        if (CollectionUtils.isEmpty(costAccountShareList)) {
            return;
        }
        synMainCostAccountShare(costAccountShareList);
    }

    /**
     * 主表向明细表同步
     * @param costAccountShareList
     */
    public void synMainCostAccountShare(List<CostAccountShare> costAccountShareList){
        //生成分摊设置对应的会计科目对象
        List<CostAccountShareDetail> fullCostAccountShareDetailList=new ArrayList<>();
        //生成分摊设置对应的分摊参数对象
        List<CostAccountShareParam> fullCostAccountShareParamList=new ArrayList<>();
        //按主表的数据逐个转成会计科目对象和分摊参数对象
        costAccountShareList.stream().forEach(costAccountShare->{
            //处理会计科目
            String accountingCodes = costAccountShare.getAccountingCodes();
            if(!StringUtils.isEmpty(accountingCodes)){
                List<String> accountingCodeList = Arrays.stream(accountingCodes.split(StrUtil.COMMA)).collect(Collectors.toList());
                List<CostAccountShareDetail> costAccountShareDetailList = accountingCodeList.stream().map(accountingCode ->
                        createCostAccountShareDetail(costAccountShare.getId(),accountingCode)).collect(Collectors.toList());
                fullCostAccountShareDetailList.addAll(costAccountShareDetailList);
            }

            //处理分摊参数
            String paramList = costAccountShare.getParamList();
            if(!StringUtils.isEmpty(paramList)) {
                List<ShareParamProportionVO> shareParamProportionVOS = JacksonUtil.str2ObjList(paramList, new TypeReference<List<ShareParamProportionVO>>() {
                });
                List<CostAccountShareParam> costAccountShareParamList = shareParamProportionVOS.stream().map(shareParamProportion ->
                                createCostAccountShareParam(costAccountShare.getId(), shareParamProportion.getShareParamCode(), shareParamProportion.getShareParamPopout())).
                        collect(Collectors.toList());
                fullCostAccountShareParamList.addAll(costAccountShareParamList);
            }
        });
        //作废原来的数据
        List<Long> accountShareIdList = costAccountShareList.stream().map(CostAccountShare::getId).collect(Collectors.toList());
        costAccountShareDetailRepository.delCostAccountShareDetailList(accountShareIdList);
        costAccountShareParamRepository.delCostAccountShareParamList(accountShareIdList);
        //保存会计科目对象
        if (!CollectionUtils.isEmpty(fullCostAccountShareDetailList)) {
            costAccountShareDetailRepository.saveBatch(fullCostAccountShareDetailList,NumberConstant.ONE_HUNDRED);
        }
        //保存分摊参数对象
        if (!CollectionUtils.isEmpty(fullCostAccountShareParamList)) {
            costAccountShareParamRepository.saveBatch(fullCostAccountShareParamList,NumberConstant.ONE_HUNDRED);
        }
    }

    /**
     * 创建分摊设置对应的会计科目对象
     * @param accountShareId
     * @param accountingCode
     * @return
     */
    public CostAccountShareDetail createCostAccountShareDetail(Long accountShareId,String accountingCode){
        CostAccountShareDetail costAccountShareDetail = new CostAccountShareDetail();
        costAccountShareDetail.setHospId(UserContext.getHospId());
        costAccountShareDetail.setAccountShareId(accountShareId);
        costAccountShareDetail.setAccountingCode(accountingCode);
        costAccountShareDetail.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
        costAccountShareDetail.setCreateTime(new Date());
        return costAccountShareDetail;
    }

    /**
     * 创建分摊设置对应的分摊参数对象
     * @param accountShareId
     * @param shareParamCode
     * @param shareParamProportion
     * @return
     */
    public CostAccountShareParam createCostAccountShareParam(Long accountShareId,String shareParamCode,BigDecimal shareParamProportion) {
        CostAccountShareParam costAccountShareParam = new CostAccountShareParam();
        costAccountShareParam.setHospId(UserContext.getHospId());
        costAccountShareParam.setAccountShareId(accountShareId);
        costAccountShareParam.setShareParamCode(shareParamCode);
        costAccountShareParam.setShareParamProportion(shareParamProportion);
        costAccountShareParam.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
        costAccountShareParam.setCreateTime(new Date());
        return costAccountShareParam;
    }

    /**
     * 获取所有的分摊参数配置
     * @return
     */
    public  List<CostAccountShare> getCostAccountShareList(Long accountShareId){
        LambdaQueryWrapper<CostAccountShare> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CostAccountShare::getHospId, UserContext.getHospId());
        queryWrapper.eq(CostAccountShare::getDeleteTime, NumberConstant.ZERO);
        if(!ObjectUtils.isEmpty(accountShareId)){
            queryWrapper.eq(CostAccountShare::getId, accountShareId);
        }
        return baseMapper.selectList(queryWrapper);
    }

    /**
     * 复制目标责任中心设置
     * @param accountShareCopyDto
     * @param accountShareList
     */
    public void copyCostAccountShareTarget(AccountShareCopyDto accountShareCopyDto,List<CostAccountShare> accountShareList){
        //没有指定的复制目标
        if(CollectionUtils.isEmpty(accountShareList)){
            return;
        }
        List<CostAccountShareTarget> costAccountShareTargetList = costAccountShareTargetRepository.getCostAccountShareTarget(accountShareCopyDto.getId());
        //没有设置指定的分摊目标责任中心
        if(CollectionUtils.isEmpty(costAccountShareTargetList)){
            return;
        }
        //逐个分摊设置复制目标责任中心
        List<CostAccountShareTarget> copyCostAccountShareTargetList=new ArrayList<>();
        for (CostAccountShare costAccountShare : accountShareList) {
            List<CostAccountShareTarget> copyTargetList = costAccountShareTargetList.stream().map(target -> createCostAccountShareTarget(costAccountShare.getId(), target.getTargetResponsibilityCode())).collect(Collectors.toList());
            copyCostAccountShareTargetList.addAll(copyTargetList);
        }
        //保存复制的数据
        if(CollectionUtils.isEmpty(copyCostAccountShareTargetList)) {
            costAccountShareTargetRepository.saveBatch(copyCostAccountShareTargetList);
        }
    }

    @Override
    public void applyAccountShareTarget(ShareTargetMapVo shareTargetMapVo) {
        applyAccountShareTarget(shareTargetMapVo.getAccountShareId(),shareTargetMapVo.getTargetRespCodeList());
    }
    /**
     * 提交分摊设置对应的目标责任中心
     * @param accountShareId
     * @param respCodeList
     */
    public void applyAccountShareTarget(Long accountShareId , List<String> respCodeList){
        //先作废上次的数据
        costAccountShareTargetRepository.delCostAccountShareTarget(accountShareId);
        //没有新的目标责任中心时不用处理
        if(CollectionUtils.isEmpty(respCodeList)){
            return;
        }
        //保存新的目标责任中心
        List<CostAccountShareTarget> costAccountShareTargetList = respCodeList.stream().map(respCode ->
                createCostAccountShareTarget(accountShareId, respCode)).collect(Collectors.toList());
        costAccountShareTargetRepository.saveBatch(costAccountShareTargetList);
    }

    /**
     * 生成分摊设置对应的目标责任中心对象
     * @param accountShareId
     * @param targetResponsibilityCode
     * @return
     */
    public CostAccountShareTarget createCostAccountShareTarget(Long accountShareId,String targetResponsibilityCode) {
        CostAccountShareTarget costAccountShareTarget = new CostAccountShareTarget();
        costAccountShareTarget.setHospId(UserContext.getHospId());
        costAccountShareTarget.setAccountShareId(accountShareId);
        costAccountShareTarget.setTargetResponsibilityCode(targetResponsibilityCode);
        costAccountShareTarget.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
        costAccountShareTarget.setCreateTime(new Date());
        return costAccountShareTarget;
    }

}