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

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.jeeplus.core.query.QueryWrapperGenerator;
import com.jeeplus.sys.service.dto.UserDTO;
import com.jeeplus.sys.utils.StringUtils;
import com.jeeplus.sys.utils.UserUtils;
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.reimbursement.reimbursementInfo.domain.ReimbursementAmountInfo;
import com.jeeplus.test.reimbursement.reimbursementInfo.domain.ReimbursementDetailInfo;
import com.jeeplus.test.reimbursement.reimbursementInfo.domain.ReimbursementInfo;
import com.jeeplus.test.reimbursement.reimbursementInfo.mapper.ReimbursementAmountInfoMapper;
import com.jeeplus.test.reimbursement.reimbursementInfo.mapper.ReimbursementDetailInfoMapper;
import com.jeeplus.test.reimbursement.reimbursementInfo.mapper.ReimbursementInfoMapper;
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.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@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;

    /**
     * 列表查询
     */
    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 = {0} OR b.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 b.user_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 b.dept_name LIKE {1} )", dto.getDepartment(), "%" + dto.getDepartment() + "%");
        }
        // 报销类别
        if (StringUtils.isNotEmpty(dto.getRemiType())) {
            queryWrapper.apply(" (b.type_id = {0} OR b.type_name LIKE {1}) ", dto.getRemiType(), "%" + dto.getRemiType() + "%");
        }
        // 报销金额
        if (dto.getAmounts() != null) {
            if (StringUtils.isNotEmpty(dto.getAmounts()[0])) {
                queryWrapper.ge("b.number", Double.parseDouble(dto.getAmounts()[0]));
            }
            if (StringUtils.isNotEmpty(dto.getAmounts()[1])) {
                queryWrapper.le("b.number", Double.parseDouble(dto.getAmounts()[1]));
            }
        }
        // 报告号
        if (StringUtils.isNotEmpty(dto.getReportNumber())) {
            queryWrapper.like("b.report_number", dto.getReportNumber());
        }
        return infoMapper.findList(page, queryWrapper);
    }

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

    public String 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())) {
            for (ReimbursementDetailInfo detailInfo : dto.getDetailInfos()) {
                // 生成id
                String detailId = UUID.randomUUID().toString().replace("-", "");
                detailInfo.setId(detailId);
                detailInfo.setCreateBy(userDTO.getId());
                detailInfo.setCreateDate(new Date());
                detailInfo.setUpdateBy(userDTO.getId());
                detailInfo.setUpdateDate(new Date());
                detailInfo.setDelFlag(0);
                // 保存基础表信息主键值
                detailInfo.setInfoId(id);
                detailInfoMapper.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 id;
    }

    public String 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);
        if (CollectionUtils.isNotEmpty(dto.getDetailInfos())) {
            for (ReimbursementDetailInfo detailInfo : dto.getDetailInfos()) {
                // 生成id
                String detailId = UUID.randomUUID().toString().replace("-", "");
                detailInfo.setId(detailId);
                detailInfo.setCreateBy(userDTO.getId());
                detailInfo.setCreateDate(new Date());
                detailInfo.setUpdateBy(userDTO.getId());
                detailInfo.setUpdateDate(new Date());
                detailInfo.setDelFlag(0);
                // 保存基础表信息主键值
                detailInfo.setInfoId(dto.getId());
                detailInfoMapper.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 dto.getId();
    }

    public String remove(String id) {
        // 删除基础信息表
        infoMapper.deleteById(id);
        // 删除详情列表
        LambdaQueryWrapper<ReimbursementDetailInfo> detailInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        detailInfoLambdaQueryWrapper.eq(ReimbursementDetailInfo::getInfoId, id);
        detailInfoMapper.delete(detailInfoLambdaQueryWrapper);
        // 删除专用发票信息列表
        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);
        BeanUtils.copyProperties(info, dto);
        // 查询详情列表
        LambdaQueryWrapper<ReimbursementDetailInfo> detailInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
        detailInfoLambdaQueryWrapper.eq(ReimbursementDetailInfo::getInfoId, id);
        List<ReimbursementDetailInfo> detailInfos = detailInfoMapper.selectList(detailInfoLambdaQueryWrapper);
        dto.setDetailInfos(detailInfos);
        // 查询专用发票信息列表
        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();
        if (CollectionUtils.isNotEmpty(officeList)) {
            list.addAll(officeList);
        }
        // 查询用户
        List<TreeUserDto> userList = infoMapper.findUserList(name);
        if (CollectionUtils.isNotEmpty(userList)) {
            list.addAll(userList);
        }
        return list;
    }

    /**
     * 下载列表查询
     */
    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 b.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 b.user_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 b.dept_name LIKE {1} )", dto.getDepartment(), "%" + dto.getDepartment() + "%");
        }
        // 报销类别
        if (StringUtils.isNotEmpty(dto.getRemiType())) {
            queryWrapper.apply(" (b.type_id = {0} OR b.type_name LIKE {1}) ", dto.getRemiType(), "%" + dto.getRemiType() + "%");
        }
        // 报销金额
        if (dto.getAmounts() != null) {
            if (StringUtils.isNotEmpty(dto.getAmounts()[0])) {
                queryWrapper.ge("b.number", dto.getAmounts()[0]);
            }
            if (StringUtils.isNotEmpty(dto.getAmounts()[1])) {
                queryWrapper.le("b.number", dto.getAmounts()[1]);
            }
        }
        // 报告号
        if (StringUtils.isNotEmpty(dto.getReportNumber())) {
            queryWrapper.like("b.report_number", dto.getReportNumber());
        }
        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("已完成");
                }
            }
        }
        return exportList;
    }

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

}
