package com.jeeplus.test.reimbursement.reimbursementInfo.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jeeplus.core.query.QueryWrapperGenerator;
import com.jeeplus.flowable.model.Flow;
import com.jeeplus.flowable.service.FlowTaskService;
import com.jeeplus.sys.domain.Office;
import com.jeeplus.sys.mapper.OfficeMapper;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.sys.utils.DictUtils;
import com.jeeplus.sys.utils.StringUtils;
import com.jeeplus.sys.utils.UserUtils;
import com.jeeplus.test.cw.common.CommonApi;
import com.jeeplus.test.cw.projectRecords.domain.CwProjectRecords;
import com.jeeplus.test.cw.projectRecords.service.CwProjectRecordsService;
import com.jeeplus.test.cw.reimbursementApproval.approvalInfo.domain.*;
import com.jeeplus.test.manytomany.domain.Student;
import com.jeeplus.test.mould.service.SerialnumTplService;
import com.jeeplus.test.oss.domain.WorkAttachment;
import com.jeeplus.test.oss.mapper.OssServiceMapper;
import com.jeeplus.test.program.configuration.projectList.domain.ProgramProjectListInfo;
import com.jeeplus.test.program.configuration.projectList.domain.ProgramReportNo;
import com.jeeplus.test.program.configuration.projectList.mapper.ProgramReportNoMapper;
import com.jeeplus.test.program.configuration.projectList.mapper.ProjectListMapper;
import com.jeeplus.test.program.configuration.projectList.service.ProjectListService;
import com.jeeplus.test.projectRecords.domain.Project;
import com.jeeplus.test.projectRecords.service.ProjectService;
import com.jeeplus.test.reimbursement.reimbursementInfo.domain.*;
import com.jeeplus.test.reimbursement.reimbursementInfo.mapper.*;
import com.jeeplus.test.reimbursement.reimbursementInfo.service.dto.QueryListDto;
import com.jeeplus.test.reimbursement.reimbursementInfo.service.dto.RetureListDto;
import com.jeeplus.test.reimbursement.reimbursementInfo.service.dto.SaveInfoDto;
import com.jeeplus.test.reimbursement.reimbursementInfo.service.dto.TreeUserDto;
import com.jeeplus.test.workContract.service.WorkContractService;
import com.jeeplus.test.workContract.service.dto.WorkAttachmentDto;
import com.jeeplus.test.workContract.service.dto.WorkContractInfoDto;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class ReimbursementInfoService {

    @Resource
    private ReimbursementInfoMapper infoMapper;

    @Resource
    private ReimbursementDetailInfoMapper detailInfoMapper;

    @Resource
    private ReimbursementAmountInfoMapper amountInfoMapper;

    @Resource
    private OssServiceMapper ossServiceMapper;

    @Resource
    private SerialnumTplService serialnumTplService;

    @Resource
    private WorkContractService workContractService;

    @Autowired
    private OfficeMapper officeMapper;

    @Autowired
    private ReimbursementDetailInfoContractMapper reimbursementDetailInfoContractMapper;

    @Autowired
    private ReimbursementDetailInfoOtherMapper reimbursementDetailInfoOtherMapper;

    @Autowired
    private ReimbursementDetailInfoProcuredMapper reimbursementDetailInfoProcuredMapper;

    @Resource
    private FlowTaskService flowTaskService;

    @Autowired
    private CommonApi commonApi;

    @Autowired
    private TaskService taskService;

    @Resource
    private ProjectListMapper projectListMapper;

    @Resource
    private ProgramReportNoMapper programReportNoMapper;
    /**
     * 列表查询
     */
    public IPage<RetureListDto> list(Page<RetureListDto> page , QueryListDto dto) throws Exception{
        QueryWrapper<QueryListDto> queryWrapper = QueryWrapperGenerator.buildQueryCondition(dto, QueryListDto.class);
        /**
         * a表是reimbursementInfo
         * b表是reimbursementDetailInfo
         * c表是sysUser
         */
        queryWrapper.eq("a.del_flag", 0);
        // 报销项目
        if (StringUtils.isNotEmpty(dto.getProject())) {
            queryWrapper.apply("(b.project_id LIKE {0} OR b.project_name LIKE {1})", "%" + dto.getProject() + "%", "%" + dto.getProject() + "%");
            queryWrapper.or().apply("(b4.project_id = {0} OR b4.project_name LIKE {1})", dto.getProject(), "%" + dto.getProject() + "%");
            queryWrapper.or().apply("(b5.project_id = {0} OR b5.project_name LIKE {1})", dto.getProject(), "%" + dto.getProject() + "%");

        }
        // 报销时间
        if (dto.getDates() != null) {
            queryWrapper.between("a.reim_date", dto.getDates()[0], dto.getDates()[1]);
        }
        // 经办人
        if (StringUtils.isNotEmpty(dto.getHandled())) {
            queryWrapper.apply("(a.create_by = {0} OR c.name LIKE {1})", dto.getHandled(), "%" + dto.getHandled() + "%");
        }
        // 报销人
        if (StringUtils.isNotEmpty(dto.getReimBy())) {
            queryWrapper.apply("( b.user_id = {0} OR us.name LIKE {1} )", dto.getReimBy(), "%" + dto.getReimBy() + "%");
            queryWrapper.or().apply("( b2.user_id = {0} OR us2.name LIKE {1} )", dto.getReimBy(), "%" + dto.getReimBy() + "%");
            queryWrapper.or().apply("( b4.user_id = {0} OR us4.name LIKE {1} )", dto.getReimBy(), "%" + dto.getReimBy() + "%");
            queryWrapper.or().apply("( b5.user_id = {0} OR us5.name LIKE {1} )", dto.getReimBy(), "%" + dto.getReimBy() + "%");

        }
        // 报销状态
        if (StringUtils.isNotEmpty(dto.getType())) {
            queryWrapper.eq("a.type", dto.getType());
        }
        // 报销部门
        if (StringUtils.isNotEmpty(dto.getDepartment())) {
            queryWrapper.apply("( b.dept_id = {0} OR so.name LIKE {1} )", dto.getDepartment(), "%" + dto.getDepartment() + "%");
            queryWrapper.or().apply("( b2.dept_id = {0} OR so2.name LIKE {1} )", dto.getDepartment(), "%" + dto.getDepartment() + "%");
            queryWrapper.or().apply("( b4.dept_id = {0} OR so4.name LIKE {1} )", dto.getDepartment(), "%" + dto.getDepartment() + "%");
            queryWrapper.or().apply("( b5.dept_id = {0} OR so5.name LIKE {1} )", dto.getDepartment(), "%" + dto.getDepartment() + "%");

        }
        // 报销类别
        if (StringUtils.isNotEmpty(dto.getRemiType())) {
            queryWrapper.apply(" (b.type_id = {0} OR t.name LIKE {1}) ", dto.getRemiType(), "%" + dto.getRemiType() + "%");
            queryWrapper.or().apply(" (b2.type_id = {0} OR t2.name LIKE {1}) ", dto.getRemiType(), "%" + dto.getRemiType() + "%");
            queryWrapper.or().apply(" (b4.type_id = {0} OR t4.name LIKE {1}) ", dto.getRemiType(), "%" + dto.getRemiType() + "%");
            queryWrapper.or().apply(" (b5.type_id = {0} OR t5.name LIKE {1}) ", dto.getRemiType(), "%" + dto.getRemiType() + "%");

        }
        // 报销金额
        if (dto.getAmounts() != null) {
            if (StringUtils.isNotEmpty(dto.getAmounts()[0])) {
                queryWrapper.and(w->
                    w.ge("b.number", Double.parseDouble(dto.getAmounts()[0]))
                        .or().ge("b2.number", Double.parseDouble(dto.getAmounts()[0]))
                        .or().ge("b4.number", Double.parseDouble(dto.getAmounts()[0]))
                        .or().ge("b5.number", Double.parseDouble(dto.getAmounts()[0]))
                );
            }
            if (StringUtils.isNotEmpty(dto.getAmounts()[1])) {
                queryWrapper.and(w->
                        w.le("b.number", Double.parseDouble(dto.getAmounts()[1]))
                                .or().le("b2.number", Double.parseDouble(dto.getAmounts()[1]))
                                .or().le("b4.number", Double.parseDouble(dto.getAmounts()[1]))
                                .or().le("b5.number", Double.parseDouble(dto.getAmounts()[1]))
                );
            }
        }
        // 报告号
        if (StringUtils.isNotEmpty(dto.getReportNumber())) {
            queryWrapper.like("b.report_number", dto.getReportNumber());
            queryWrapper.or().like("b2.report_number", dto.getReportNumber());
            queryWrapper.or().like("b4.report_number", dto.getReportNumber());
            queryWrapper.or().like("b5.report_number", dto.getReportNumber());
        }
        // 报销类型
        if (StringUtils.isNotBlank(dto.getSourceType())) {
            queryWrapper.eq("a.source_type", dto.getSourceType());
        }
        IPage<RetureListDto> pageList = infoMapper.findList(page, queryWrapper);
        pageList.getRecords().stream().forEach(item -> {
            // 报销申请
            if (StringUtils.isNotBlank(item.getTaskId()) && StringUtils.isNotBlank(item.getType())) {
                if ("2".equals(item.getType())) { // “审核中”的数据要获取数据审核人
                    item.setAuditUserIds(flowTaskService.getTaskAuditUsers(item.getTaskId()));  // 获取数据审核人
                }
            }
            if (StringUtils.isNotBlank(item.getSourceType()) && "1".equals(item.getSourceType())) { //项目报销
                if (StringUtils.isNotBlank(item.getProjectId())) {
                    String proName = selectProjectByIds(item.getProjectId());
                    item.setProjectName(proName);
                    String reportNo = selectReportNoByIds(item.getProjectId());
                    item.setReportNumber(reportNo);
                }
            }
        });
        return pageList;
    }

    /**
     * 根据项目id查询项目名称
     * @param ids 以逗号分隔的多个项目id字符串
     * @return
     */
    public String selectProjectByIds(String ids) {
        String projectName = "";
        String[] split = ids.split(",");
        List<String> idList = Arrays.asList(split);
        List<ProgramProjectListInfo> list = projectListMapper.selectList(new LambdaQueryWrapper<ProgramProjectListInfo>().in(ProgramProjectListInfo::getId, idList));
        if (CollectionUtil.isNotEmpty(list)) {
            projectName = list.stream().map(ProgramProjectListInfo::getName).collect(Collectors.joining(","));
        }
        return projectName;
    }

    /**
     * 根据项目id查询报告号
     * @param ids 以逗号分隔的多个项目id字符串
     * @return
     */
    public String selectReportNoByIds(String ids) {
        List<String> reportNoList = new ArrayList<>();
        String reportNo = "";
        String[] split = ids.split(",");
        List<String> idList = Arrays.asList(split);
        List<ProgramProjectListInfo> list = projectListMapper.selectList(new LambdaQueryWrapper<ProgramProjectListInfo>().in(ProgramProjectListInfo::getId, idList));
        if (CollectionUtil.isNotEmpty(list)) {
            list.stream().forEach(item -> {
                ProgramReportNo programReportNo = programReportNoMapper.selectOne(new LambdaQueryWrapper<ProgramReportNo>().eq(ProgramReportNo::getProgramId, item.getId()));
                if (ObjectUtil.isNotEmpty(programReportNo) && StringUtils.isNotBlank(programReportNo.getReportNo())) {
                    reportNoList.add(programReportNo.getReportNo());
                } else {
                    reportNoList.add("无");
                }
            });
            if (CollectionUtil.isNotEmpty(reportNoList)) {
                reportNo = reportNoList.stream().collect(Collectors.joining(","));
            }
        }
        return reportNo;
    }

    public ReimbursementInfo save(SaveInfoDto dto) throws Exception{
        // 获取当前登录人信息
        UserDTO userDTO = UserUtils.getCurrentUserDTO();
        if (StringUtils.isNotEmpty(dto.getId())) {
            return update(dto, userDTO);
        } else {
            return add(dto, userDTO);
        }
    }

    public ReimbursementInfo add(SaveInfoDto dto, UserDTO userDTO) throws Exception{
        // 生成id
        String id = UUID.randomUUID().toString().replace("-", "");
        // 生成编号
        String no = serialnumTplService.genSerialNum(userDTO.getCompanyDTO().getId(), dto.BIZ_CODE);
        // 保存基础信息表信息
        ReimbursementInfo info = new ReimbursementInfo();
        BeanUtils.copyProperties(dto, info);
        info.setId(id);
        info.setNo(no);
        info.setCreateBy(userDTO.getId());
        info.setCreateDate(new Date());
        info.setUpdateBy(userDTO.getId());
        info.setUpdateDate(new Date());
        info.setDelFlag(0);
        infoMapper.insert(info);
        // 保存项目详情列表信息
        if (CollectionUtils.isNotEmpty(dto.getDetailInfos())) {
            int i = 0;
            for (ReimbursementDetailInfo detailInfo : dto.getDetailInfos()) {
                // 保存基础表信息主键值
                detailInfo.setInfoId(id);
                detailInfo.setSort(String.valueOf(i));
                detailInfoMapper.insert(detailInfo);
                i++;
            }
        }
        // 保存合同详情列表信息
        if (CollectionUtils.isNotEmpty(dto.getDetailInfoContracts())) {
            for (ReimbursementDetailInfoContract detailInfo : dto.getDetailInfoContracts()) {
                // 保存基础表信息主键值
                detailInfo.setInfoId(id);
                reimbursementDetailInfoContractMapper.insert(detailInfo);
            }
        }
        // 保存其他报销详情列表信息
        if (CollectionUtils.isNotEmpty(dto.getDetailInfoOthers())) {
            int i = 0;
            for (ReimbursementDetailInfoOther detailInfo : dto.getDetailInfoOthers()) {
                // 保存基础表信息主键值
                detailInfo.setInfoId(id);
                detailInfo.setSort(String.valueOf(i));
                reimbursementDetailInfoOtherMapper.insert(detailInfo);
                i++;
            }
        }
        // 保存采购报销详情列表信息
        if (CollectionUtils.isNotEmpty(dto.getDetailInfoProcured())) {
            for (ReimbursementDetailInfoProcured detailInfo : dto.getDetailInfoProcured()) {
                // 保存基础表信息主键值
                detailInfo.setInfoId(id);
                reimbursementDetailInfoProcuredMapper.insert(detailInfo);
            }
        }
        // 保存专用发票列表信息
        if (CollectionUtils.isNotEmpty(dto.getAmountInfos())) {
            for (ReimbursementAmountInfo amountInfo : dto.getAmountInfos()) {
                // 生成id
                String amountId = UUID.randomUUID().toString().replace("-", "");
                amountInfo.setId(amountId);
                amountInfo.setCreateBy(userDTO.getId());
                amountInfo.setCreateDate(new Date());
                amountInfo.setUpdateBy(userDTO.getId());
                amountInfo.setUpdateDate(new Date());
                amountInfo.setDelFlag(0);
                // 保存基础表信息主键值
                amountInfo.setInfoId(id);
                amountInfoMapper.insert(amountInfo);
            }
        }
        // 保存附件列表信息
        if (CollectionUtils.isNotEmpty(dto.getFiles())) {
            workContractService.saveFiles(dto.getFiles(), userDTO, id);
        }
        return info;
    }

    public ReimbursementInfo update(SaveInfoDto dto, UserDTO userDTO) {
        // 修改基础信息
        ReimbursementInfo info = new ReimbursementInfo();
        BeanUtils.copyProperties(dto, info);
        info.setUpdateBy(userDTO.getId());
        info.setUpdateDate(new Date());
        infoMapper.updateById(info);
        // 修改报销详情列表信息
        // 删除原有数据
        LambdaQueryWrapper<ReimbursementDetailInfo> detailWrapper = new LambdaQueryWrapper<>();
        detailWrapper.eq(ReimbursementDetailInfo::getInfoId, dto.getId());
        detailInfoMapper.delete(detailWrapper);
        // 删除合同列表
        LambdaQueryWrapper<ReimbursementDetailInfoContract> detailWrapperContract = new LambdaQueryWrapper<>();
        detailWrapperContract.eq(ReimbursementDetailInfoContract::getInfoId, dto.getId());
        reimbursementDetailInfoContractMapper.delete(detailWrapperContract);
        // 删除其他报销表
        LambdaQueryWrapper<ReimbursementDetailInfoOther> detailWrapperOthers = new LambdaQueryWrapper<>();
        detailWrapperOthers.eq(ReimbursementDetailInfoOther::getInfoId, dto.getId());
        reimbursementDetailInfoOtherMapper.delete(detailWrapperOthers);
        // 删除采购报销表
        LambdaQueryWrapper<ReimbursementDetailInfoProcured> detailWrapperProcured = new LambdaQueryWrapper<>();
        detailWrapperProcured.eq(ReimbursementDetailInfoProcured::getInfoId, dto.getId());
        reimbursementDetailInfoProcuredMapper.delete(detailWrapperProcured);

        // 保存项目详情列表信息
        if (CollectionUtils.isNotEmpty(dto.getDetailInfos())) {
            int i = 0;
            for (ReimbursementDetailInfo detailInfo : dto.getDetailInfos()) {
                // 保存基础表信息主键值
                detailInfo.setInfoId(dto.getId());
                detailInfo.setId("");
                detailInfo.setSort(String.valueOf(i));
                detailInfoMapper.insert(detailInfo);
                i++;
            }
        }
        // 保存合同详情列表信息
        if (CollectionUtils.isNotEmpty(dto.getDetailInfoContracts())) {
            for (ReimbursementDetailInfoContract detailInfo : dto.getDetailInfoContracts()) {
                // 保存基础表信息主键值
                detailInfo.setInfoId(dto.getId());
                detailInfo.setId("");
                reimbursementDetailInfoContractMapper.insert(detailInfo);
            }
        }
        // 保存其他报销详情列表信息
        if (CollectionUtils.isNotEmpty(dto.getDetailInfoOthers())) {
            int i = 0;
            for (ReimbursementDetailInfoOther detailInfo : dto.getDetailInfoOthers()) {
                // 保存基础表信息主键值
                detailInfo.setInfoId(dto.getId());
                detailInfo.setId("");
                detailInfo.setSort(String.valueOf(i));
                reimbursementDetailInfoOtherMapper.insert(detailInfo);
                i++;
            }
        }
        // 保存采购报销详情列表信息
        if (CollectionUtils.isNotEmpty(dto.getDetailInfoProcured())) {
            for (ReimbursementDetailInfoProcured detailInfo : dto.getDetailInfoProcured()) {
                // 保存基础表信息主键值
                detailInfo.setInfoId(dto.getId());
                detailInfo.setId("");
                reimbursementDetailInfoProcuredMapper.insert(detailInfo);
            }
        }
        // 修改专用发票信息列表
        // 删除原有数据
        LambdaQueryWrapper<ReimbursementAmountInfo> amountWrapper = new LambdaQueryWrapper<>();
        amountWrapper.eq(ReimbursementAmountInfo::getInfoId, dto.getId());
        amountInfoMapper.delete(amountWrapper);
        if (CollectionUtils.isNotEmpty(dto.getAmountInfos())) {
            for (ReimbursementAmountInfo amountInfo : dto.getAmountInfos()) {
                // 生成id
                String amountId = UUID.randomUUID().toString().replace("-", "");
                amountInfo.setId(amountId);
                amountInfo.setCreateBy(userDTO.getId());
                amountInfo.setCreateDate(new Date());
                amountInfo.setUpdateBy(userDTO.getId());
                amountInfo.setUpdateDate(new Date());
                amountInfo.setDelFlag(0);
                // 保存基础表信息主键值
                amountInfo.setInfoId(dto.getId());
                amountInfoMapper.insert(amountInfo);
            }
        }
        // 修改附件信息列表
        if (CollectionUtils.isNotEmpty(dto.getFiles())) {
            workContractService.updateFiles(dto.getFiles(), userDTO, dto.getId());
        }
        return info;
    }

    public String remove(String id) {
        // 删除基础信息表
        infoMapper.deleteById(id);
        // 删除详情列表
        LambdaQueryWrapper<ReimbursementDetailInfo> detailWrapper = new LambdaQueryWrapper<>();
        detailWrapper.eq(ReimbursementDetailInfo::getInfoId, id);
        detailInfoMapper.delete(detailWrapper);
        // 删除合同列表
        LambdaQueryWrapper<ReimbursementDetailInfoContract> detailWrapperContract = new LambdaQueryWrapper<>();
        detailWrapperContract.eq(ReimbursementDetailInfoContract::getInfoId, id);
        reimbursementDetailInfoContractMapper.delete(detailWrapperContract);
        // 删除其他报销列表
        LambdaQueryWrapper<ReimbursementDetailInfoOther> detailWrapperOther = new LambdaQueryWrapper<>();
        detailWrapperOther.eq(ReimbursementDetailInfoOther::getInfoId, id);
        reimbursementDetailInfoOtherMapper.delete(detailWrapperOther);
        // 删除采购报销列表
        LambdaQueryWrapper<ReimbursementDetailInfoProcured> detailWrapperProcured = new LambdaQueryWrapper<>();
        detailWrapperProcured.eq(ReimbursementDetailInfoProcured::getInfoId, id);
        reimbursementDetailInfoProcuredMapper.delete(detailWrapperProcured);
        // 删除专用发票信息列表
        LambdaQueryWrapper<ReimbursementAmountInfo> amountInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        amountInfoLambdaQueryWrapper.eq(ReimbursementAmountInfo::getInfoId, id);
        amountInfoMapper.delete(amountInfoLambdaQueryWrapper);
        // 删除附件信息
        LambdaQueryWrapper<WorkAttachment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(WorkAttachment::getAttachmentId, id);
        ossServiceMapper.delete(wrapper);
        return "操作成功";
    }

    public SaveInfoDto findById(String id) {
        SaveInfoDto dto = new SaveInfoDto();
        // 查询基础信息表
        ReimbursementInfo info = infoMapper.selectById(id);
        if (ObjectUtil.isNotEmpty(info)){
            BeanUtils.copyProperties(info, dto);
            if(StringUtils.isNotBlank(info.getDepartment())) {
                Office byId = officeMapper.selectById(info.getDepartment());
                if (ObjectUtil.isNotEmpty(byId)) {
                    dto.setDepartmentName(byId.getName());
                }
            }
            // 项目报销详情
            List<ReimbursementDetailInfo> detailList = infoMapper.getDetailList(id);
            detailList.stream().forEach(projectDetail -> {
                if (StringUtils.isNotBlank(projectDetail.getProjectId())) {
                    String proName = selectProjectByIds(projectDetail.getProjectId());
                    projectDetail.setProjectName(proName);
                    String reportNo = selectReportNoByIds(projectDetail.getProjectId());
                    projectDetail.setReportNumber(reportNo);
                } else {
                    projectDetail.setProjectName("");
                    projectDetail.setReportNumber("");
                }
            });
            dto.setDetailInfos(detailList);
            // 合同报销详情
            dto.setDetailInfoContracts(infoMapper.getContractDetailList(id));
            // 其他报销
            dto.setDetailInfoOthers(infoMapper.getOtherDetailList(id));
            // 采购报销
            dto.setDetailInfoProcured(infoMapper.getProcuredDetailList(id));
            // 查询专用发票信息列表
            LambdaQueryWrapper<ReimbursementAmountInfo> amountInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
            amountInfoLambdaQueryWrapper.eq(ReimbursementAmountInfo::getInfoId, id);
            List<ReimbursementAmountInfo> amountInfos = amountInfoMapper.selectList(amountInfoLambdaQueryWrapper);
            dto.setAmountInfos(amountInfos);
            // 查询附件信息
            List<WorkAttachmentDto> files = infoMapper.findFiles(id);
            if (CollectionUtils.isNotEmpty(files)) {
                for (WorkAttachmentDto i : files) {
                    i.setCreateBy(UserUtils.get(i.getBy()));
                }
            }
            dto.setFiles(files);
        }
        return dto;
    }

    public Boolean checkNumber(String number) {
        LambdaQueryWrapper<ReimbursementAmountInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(ReimbursementAmountInfo::getNumber, number);
        List<ReimbursementAmountInfo> infos = amountInfoMapper.selectList(wrapper);
        if (CollectionUtils.isNotEmpty(infos)) {
            return true;
        }
        return false;
    }

    public void updateStatusById(RetureListDto dto) {
        infoMapper.updateStatusById(dto.getId(), dto.getType());
    }

    //用户树形
    public List<TreeUserDto> userTree(String name) {
        List<TreeUserDto> list = new ArrayList<>();
        // 查询部门
        List<TreeUserDto> officeList = infoMapper.findOfficeList();
        List<TreeUserDto> filterList = new ArrayList<>();
        if (UserUtils.getCurrentUserDTO ().isAdmin ()) {
            filterList = officeList;
        } else {
            String parentIds = officeMapper.selectById(UserUtils.getCurrentUserDTO().getOfficeDTO().getId()).getParentIds();
            String[] split = parentIds.split(",");
            if(split.length>2){
                // 公司id
                String companyId = split[2];
                // 过滤出登录人所属公司和集团
                List<TreeUserDto> finalFilterList5 = filterList;
                officeList.stream().forEach(o -> {
                    if (split[2].equals(o.getId())) {
                        finalFilterList5.add(o);
                    } else if(split[1].equals(o.getId())) {
                        finalFilterList5.add(o);
                    }
                });
                // 根据公司id找到其下部门
                List<Office> oList = officeMapper.selectList(new QueryWrapper<Office>().lambda().eq(Office::getParentId, companyId));
                // 过滤出这些部门
                List<TreeUserDto> finalFilterList4 = filterList;
                oList.stream().forEach(item -> {
                    officeList.stream().forEach(o -> {
                        if (item.getId().equals(o.getId())) {
                            finalFilterList4.add(o);
                        }
                    });
                });
                // 找到所有的公有部门
                List<Office> publicOfficeList = officeMapper.selectList(new QueryWrapper<Office>().lambda().eq(Office::getIsPublic, "1"));
                // 过滤出这些部门
                List<TreeUserDto> finalFilterList3 = filterList;
                publicOfficeList.stream().forEach(item -> {
                    officeList.stream().forEach(o -> {
                        if (item.getId().equals(o.getId())) {
                            finalFilterList3.add(o);
                        }
                    });
                });
            }else{
                // 私有的
                if ("0".equals(UserUtils.getCurrentUserDTO().getOfficeDTO().getIsPublic())) {
                    // 公司id
                    String companyId = UserUtils.getCurrentUserDTO().getOfficeDTO().getId();
                    // 过滤出登录人所属公司和集团
                    List<TreeUserDto> finalFilterList2 = filterList;
                    officeList.stream().forEach(o -> {
                        if (companyId.equals(o.getId())) {
                            finalFilterList2.add(o);
                        } else if(split[1].equals(o.getId()) && !split[1].equals(companyId)) {
                            finalFilterList2.add(o);
                        }
                    });
                    // 根据公司id找到其下部门
                    List<Office> oList = officeMapper.selectList(new QueryWrapper<Office>().lambda().eq(Office::getParentId, companyId));
                    // 过滤出这些部门
                    List<TreeUserDto> finalFilterList1 = filterList;
                    oList.stream().forEach(item -> {
                        officeList.stream().forEach(o -> {
                            if (item.getId().equals(o.getId())) {
                                finalFilterList1.add(o);
                            }
                        });
                    });
                    // 找到所有的公有部门
                    List<Office> publicOfficeList = officeMapper.selectList(new QueryWrapper<Office>().lambda().eq(Office::getIsPublic, "1"));
                    // 过滤出这些部门
                    List<TreeUserDto> finalFilterList = filterList;
                    publicOfficeList.stream().forEach(item -> {
                        officeList.stream().forEach(o -> {
                            if (item.getId().equals(o.getId())) {
                                finalFilterList.add(o);
                            }
                        });
                    });
                } else {
                    filterList = officeList;
                }
            }
        }

        /*if (CollectionUtils.isNotEmpty(officeList)) {
            list.addAll(officeList);
        }*/

        // 查询用户
        List<TreeUserDto> userList = infoMapper.findUserList(name);
        /*if (CollectionUtils.isNotEmpty(userList)) {
            list.addAll(userList);
        }*/
        list = disposeUserTree(userList, filterList);
        for (TreeUserDto officeDto : officeList) {
            if("0".equals(officeDto.getParentId())){
                list.add(officeDto);
            }
        }
        //去重
        List<TreeUserDto> newList = list.stream().collect(Collectors.collectingAndThen(
                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(TreeUserDto::getId))), ArrayList::new)
        );
        return newList;
    }

    /**
     * 用户树形数据处理
     * @param userList
     * @param officeList
     * @return
     */
    public List<TreeUserDto> disposeUserTree(List<TreeUserDto> userList, List<TreeUserDto> officeList){
        List<TreeUserDto> list = new ArrayList<>();
        for (TreeUserDto userDto : userList) {

            for (TreeUserDto officeDto : officeList) {
                if(userDto.getParentId().equals(officeDto.getId())){
                    list.add(officeDto);
                    list.add(userDto);
                    List<TreeUserDto> treeUserDtos = disposeOfficeTree(officeDto, officeList);
                    if(null!= treeUserDtos && treeUserDtos.size()>0){
                        list.addAll(treeUserDtos);
                    }
                }
            }
        }
        return list;
    }

    /**
     * 用户树形数据处理
     * @param officeInfo
     * @param officeList
     * @return
     */
    public List<TreeUserDto> disposeOfficeTree(TreeUserDto officeInfo, List<TreeUserDto> officeList){
        List<TreeUserDto> listAll = Lists.newArrayList();
            for (TreeUserDto officeDto : officeList) {
                if(officeInfo.getParentId().equals(officeDto.getId())){
                    listAll.add(officeDto);
                    disposeOfficeTree(officeDto,officeList);
                }
            }
        return listAll;
    }

    /**
     * 下载列表查询
     */
    public List<RetureListDto> exportList(QueryListDto dto) throws Exception{
        QueryWrapper<QueryListDto> queryWrapper = QueryWrapperGenerator.buildQueryCondition(dto, QueryListDto.class);
        /**
         * a表是reimbursementInfo
         * b表是reimbursementDetailInfo
         * c表是sysUser
         */
        queryWrapper.eq("a.del_flag", 0);
        // 报销项目
        if (StringUtils.isNotEmpty(dto.getProject())) {
            queryWrapper.apply("(b.project_id = {0} OR p.project_name LIKE {1})", dto.getProject(), "%" + dto.getProject() + "%");
            queryWrapper.or().apply("(b4.project_id = {0} OR b4.project_name LIKE {1})", dto.getProject(), "%" + dto.getProject() + "%");
            queryWrapper.or().apply("(b5.project_id = {0} OR b5.project_name LIKE {1})", dto.getProject(), "%" + dto.getProject() + "%");

        }
        // 报销时间
        if (dto.getDates() != null) {
            queryWrapper.between("a.reim_date", dto.getDates()[0], dto.getDates()[1]);
        }
        // 经办人
        if (StringUtils.isNotEmpty(dto.getHandled())) {
            queryWrapper.apply("(a.create_by = {0} OR c.name LIKE {1})", dto.getHandled(), "%" + dto.getHandled() + "%");
        }
        // 报销人
        if (StringUtils.isNotEmpty(dto.getReimBy())) {
            queryWrapper.apply("( b.user_id = {0} OR us.name LIKE {1} )", dto.getReimBy(), "%" + dto.getReimBy() + "%");
            queryWrapper.or().apply("( b2.user_id = {0} OR us2.name LIKE {1} )", dto.getReimBy(), "%" + dto.getReimBy() + "%");
            queryWrapper.or().apply("( b4.user_id = {0} OR us4.name LIKE {1} )", dto.getReimBy(), "%" + dto.getReimBy() + "%");
            queryWrapper.or().apply("( b5.user_id = {0} OR us5.name LIKE {1} )", dto.getReimBy(), "%" + dto.getReimBy() + "%");
        }
        // 报销状态
        if (StringUtils.isNotEmpty(dto.getType())) {
            queryWrapper.eq("a.type", dto.getType());
        }
        // 报销部门
        if (StringUtils.isNotEmpty(dto.getDepartment())) {
            queryWrapper.apply("( b.dept_id = {0} OR so.name LIKE {1} )", dto.getDepartment(), "%" + dto.getDepartment() + "%");
            queryWrapper.or().apply("( b2.dept_id = {0} OR so2.name LIKE {1} )", dto.getDepartment(), "%" + dto.getDepartment() + "%");
            queryWrapper.or().apply("( b4.dept_id = {0} OR so4.name LIKE {1} )", dto.getDepartment(), "%" + dto.getDepartment() + "%");
            queryWrapper.or().apply("( b5.dept_id = {0} OR so5.name LIKE {1} )", dto.getDepartment(), "%" + dto.getDepartment() + "%");
        }
        // 报销类别
        if (StringUtils.isNotEmpty(dto.getRemiType())) {
            queryWrapper.apply(" (b.type_id = {0} OR t.name LIKE {1}) ", dto.getRemiType(), "%" + dto.getRemiType() + "%");
            queryWrapper.or().apply(" (b2.type_id = {0} OR t2.name LIKE {1}) ", dto.getRemiType(), "%" + dto.getRemiType() + "%");
            queryWrapper.or().apply(" (b4.type_id = {0} OR t4.name LIKE {1}) ", dto.getRemiType(), "%" + dto.getRemiType() + "%");
            queryWrapper.or().apply(" (b5.type_id = {0} OR t5.name LIKE {1}) ", dto.getRemiType(), "%" + dto.getRemiType() + "%");
        }
        // 报销金额
        if (dto.getAmounts() != null) {
            if (StringUtils.isNotEmpty(dto.getAmounts()[0])) {
                queryWrapper.and(w ->
                        w.ge("b.number", Double.parseDouble(dto.getAmounts()[0]))
                                .or().ge("b2.number", Double.parseDouble(dto.getAmounts()[0]))
                                .or().ge("b4.number", Double.parseDouble(dto.getAmounts()[0]))
                                .or().ge("b5.number", Double.parseDouble(dto.getAmounts()[0]))
                );
            }
            if (StringUtils.isNotEmpty(dto.getAmounts()[1])) {
                queryWrapper.and(w ->
                        w.le("b.number", Double.parseDouble(dto.getAmounts()[1]))
                                .or().le("b2.number", Double.parseDouble(dto.getAmounts()[1]))
                                .or().le("b4.number", Double.parseDouble(dto.getAmounts()[1]))
                                .or().le("b5.number", Double.parseDouble(dto.getAmounts()[1]))
                );
            }
        }
        // 报告号
        if (StringUtils.isNotEmpty(dto.getReportNumber())) {
            queryWrapper.like("b.report_number", dto.getReportNumber());
            queryWrapper.or().like("b2.report_number", dto.getReportNumber());
            queryWrapper.or().like("b4.report_number", dto.getReportNumber());
            queryWrapper.or().like("b5.report_number", dto.getReportNumber());
        }
        // 报销类型
        if (StringUtils.isNotBlank(dto.getSourceType())) {
            queryWrapper.eq("a.source_type", dto.getSourceType());
        }
        List<RetureListDto> exportList = infoMapper.findExportList(queryWrapper);
        if (CollectionUtils.isNotEmpty(exportList)) {
            for (RetureListDto retureListDto : exportList) {
                if ("1".equals(retureListDto.getType())) {
                    retureListDto.setType("暂存");
                }
                if ("2".equals(retureListDto.getType())) {
                    retureListDto.setType("审批中");
                }
                if ("3".equals(retureListDto.getType())) {
                    retureListDto.setType("撤回");
                }
                if ("4".equals(retureListDto.getType())) {
                    retureListDto.setType("驳回");
                }
                if ("5".equals(retureListDto.getType())) {
                    retureListDto.setType("已完成");
                }
                if (StringUtils.isNotBlank(retureListDto.getSourceType())) {
                    if ("2".equals(retureListDto.getSourceType())) {
                        retureListDto.setContractName(retureListDto.getProjectName());
                        retureListDto.setProjectName("");
                    }
                    retureListDto.setSourceType(DictUtils.getDictLabel(retureListDto.getSourceType(),"pg_reimbursement_source_type",""));
                }
            }
        }
        return exportList;
    }

    /**
     * 关联报销
     */
    public IPage<RetureListDto> relationReimbursementList(Page<RetureListDto> page, String id) {
        IPage<RetureListDto> iPage = infoMapper.relationReimbursementList(page, id);
        return iPage;
    }

    /**
     * 报销审核
     * @param saveInfoDto
     * @return
     */
    public Map<String,Object> auditFunc(SaveInfoDto saveInfoDto) {
        Map<String,Object> result = new HashMap<>();
        result.put("success", "false");
        result.put("message", "操作失败");
        if (Objects.nonNull(saveInfoDto) && StringUtils.isNotBlank(saveInfoDto.getId()) && StringUtils.isNotBlank(saveInfoDto.getFlag())) {
            String id = saveInfoDto.getId(); // 报销数据id
            String flag = saveInfoDto.getFlag(); // 审核标记  yes通过  no驳回
            SaveInfoDto reim = this.findById(id);
            if (Objects.nonNull(reim) && StringUtils.isNotBlank(reim.getType()) && "2".equals(reim.getType())) { // 确保当时数据处于“待审核”状态
                if ( StringUtils.isNotBlank(reim.getProcInsId())) {
                    try {
                        RetureListDto upStatusParam = new RetureListDto();
                        upStatusParam.setId(id);
                        if ("yes".equals(flag)) {
                            Task task = taskService.createTaskQuery().processInstanceId(reim.getProcInsId()).active().singleResult();
                            // task为null则审核节点为最后一个审核节点
                            if (Objects.nonNull(task)) {
                                upStatusParam.setType("2");
                            } else {
                                // 当前审核节点为最后节点
                                upStatusParam.setType("5"); // 审核状态设置为审核完成
                            }
                        } else {
                            upStatusParam.setType("4"); // 审核状态设置为审核驳回
                        }
                        this.updateStatusById(upStatusParam); // 修改数据的审核状态
                        flowTaskService.auditByProcInsIdAndFlag(reim.getProcInsId(), flag, null, saveInfoDto.getComment()); // 审核操作
                        result.put("success", "false");
                        result.put("message", "操作成功");
                    }catch (Exception e) {
                        e.printStackTrace();
                        result.put("success", "false");
                        result.put("message", "操作失败");
                    }
                }
            } else {
                result.put("success", "false");
                result.put("message", "操作失败，数据已发生改变或不存在，请刷新数据");
            }
        }
        return result;
    }

    public List<ProgramProjectListInfo> queryByProIds(String ids) {
        String[] split = ids.split(",");
        List<String> idList = Arrays.asList(split);
        List<ProgramProjectListInfo> list = projectListMapper.selectList(new LambdaQueryWrapper<ProgramProjectListInfo>().in(ProgramProjectListInfo::getId, idList));
        if (CollectionUtil.isNotEmpty(list)) {
            list.stream().forEach(item -> {
                ProgramReportNo programReportNo = programReportNoMapper.selectOne(new LambdaQueryWrapper<ProgramReportNo>().eq(ProgramReportNo::getProgramId, item.getId()));
                if (ObjectUtil.isNotEmpty(programReportNo) && StringUtils.isNotBlank(programReportNo.getReportNo())) {
                    item.setReportNo(programReportNo.getReportNo());
                } else {
                    item.setReportNo("无");
                }
            });
        }

        return list;
    }
}
