package com.ruoyi.zzb.zyww.service;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.zzb.common.service.BaseService;
import com.ruoyi.zzb.common.domain.BaseFileInfo;
import com.ruoyi.zzb.zyww.domain.ZywwApplyInfo;
import com.ruoyi.zzb.common.domain.BaseApproveInfo;
import com.ruoyi.zzb.zyww.domain.ZywwFileSetDTO;
import com.ruoyi.zzb.common.mapper.BaseFileInfoMapper;
import com.ruoyi.zzb.zyww.mapper.ZywwApplyInfoMapper;
import com.ruoyi.zzb.common.mapper.BaseApproveInfoMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
@DataSource(value = DataSourceType.SLAVE)
public class ZywwService {

    @Autowired
    private ZywwApplyInfoMapper zywwApplyInfoMapper;
    @Autowired
    private BaseFileInfoMapper baseFileInfoMapper;
    @Autowired
    private BaseApproveInfoMapper baseApproveInfoMapper;
    @Autowired
    private BaseService baseService;

    /**
     * 完成【住院慰问】模块需进行文件上传字段项的上传处理逻辑，并组装批量插入这些记录到相关数据表的参数
     * @param
     */
    public List<BaseFileInfo> processUploadAndBuildParams(ZywwFileSetDTO zywwFileSetDTO, String moduleCode, String moduleName, String applyFormId, String fileStoragePath) throws IOException {
        List<BaseFileInfo> dataList = new ArrayList<>();
        MultipartFile[] zywwsqbFiles = zywwFileSetDTO.getZywwsqbFiles();
        List<BaseFileInfo> zywwsqbRowDataList = baseService.doProcessUploadAndBuildParams(zywwsqbFiles, moduleCode, moduleName, applyFormId, "住院慰问申请表", "zywwsqb", fileStoragePath);
        if(zywwsqbRowDataList.size() > 0){
            dataList.addAll(zywwsqbRowDataList);
        }
        MultipartFile[] zywwjhzsqbFiles = zywwFileSetDTO.getZywwjhzsqbFiles();
        List<BaseFileInfo> zywwjhzsqbRowDataList = baseService.doProcessUploadAndBuildParams(zywwjhzsqbFiles, moduleCode, moduleName, applyFormId, "住院慰问金汇总申请表", "zywwjhzsqb", fileStoragePath);
        if(zywwjhzsqbRowDataList.size() > 0){
            dataList.addAll(zywwjhzsqbRowDataList);
        }
        MultipartFile[] jcghwwjsbbFiles = zywwFileSetDTO.getJcghwwjsbbFiles();
        List<BaseFileInfo> jcghwwjsbbRowDataList = baseService.doProcessUploadAndBuildParams(jcghwwjsbbFiles, moduleCode, moduleName, applyFormId, "基层工会慰问金申报表", "jcghwwjsbb", fileStoragePath);
        if(jcghwwjsbbRowDataList.size() > 0){
            dataList.addAll(jcghwwjsbbRowDataList);
        }
        MultipartFile[] zzzmFiles = zywwFileSetDTO.getZzzmFiles();
        List<BaseFileInfo> zzzmRowDataList = baseService.doProcessUploadAndBuildParams(zzzmFiles, moduleCode, moduleName, applyFormId, "在职证明", "zzzm", fileStoragePath);
        if(zzzmRowDataList.size() > 0){
            dataList.addAll(zzzmRowDataList);
        }
        MultipartFile[] gsFiles = zywwFileSetDTO.getGsFiles();
        List<BaseFileInfo> gsRowDataList = baseService.doProcessUploadAndBuildParams(gsFiles, moduleCode, moduleName, applyFormId, "公示", "gs", fileStoragePath);
        if(gsRowDataList.size() > 0){
            dataList.addAll(gsRowDataList);
        }
        MultipartFile[] sfzfyjFiles = zywwFileSetDTO.getSfzfyjFiles();
        List<BaseFileInfo> sfzfyjRowDataList = baseService.doProcessUploadAndBuildParams(sfzfyjFiles, moduleCode, moduleName, applyFormId, "身份证复印件", "sfzfyj", fileStoragePath);
        if(sfzfyjRowDataList.size() > 0){
            dataList.addAll(sfzfyjRowDataList);
        }
        MultipartFile[] ghhykfyjFiles = zywwFileSetDTO.getGhhykfyjFiles();
        List<BaseFileInfo> ghhykfyjRowDataList = baseService.doProcessUploadAndBuildParams(ghhykfyjFiles, moduleCode, moduleName, applyFormId, "工会会员卡复印件", "ghhykfyj", fileStoragePath);
        if(ghhykfyjRowDataList.size() > 0){
            dataList.addAll(ghhykfyjRowDataList);
        }
        MultipartFile[] zybasyfyjFiles = zywwFileSetDTO.getZybasyfyjFiles();
        List<BaseFileInfo> zybasyfyjRowDataList = baseService.doProcessUploadAndBuildParams(zybasyfyjFiles, moduleCode, moduleName, applyFormId, "住院病案首页复印件", "zybasyfyj", fileStoragePath);
        if(zybasyfyjRowDataList.size() > 0){
            dataList.addAll(zybasyfyjRowDataList);
        }
        MultipartFile[] zdzmfyjFiles = zywwFileSetDTO.getZdzmfyjFiles();
        List<BaseFileInfo> zdzmfyjRowDataList = baseService.doProcessUploadAndBuildParams(zdzmfyjFiles, moduleCode, moduleName, applyFormId, "诊断证明复印件", "zdzmfyj", fileStoragePath);
        if(zdzmfyjRowDataList.size() > 0){
            dataList.addAll(zdzmfyjRowDataList);
        }
        MultipartFile[] gszmFiles = zywwFileSetDTO.getGszmFiles();
        List<BaseFileInfo> gszmRowDataList = baseService.doProcessUploadAndBuildParams(gszmFiles, moduleCode, moduleName, applyFormId, "工伤证明", "gszm", fileStoragePath);
        if(gszmRowDataList.size() > 0){
            dataList.addAll(gszmRowDataList);
        }
        MultipartFile[] ssjlFiles = zywwFileSetDTO.getSsjlFiles();
        List<BaseFileInfo> ssjlRowDataList = baseService.doProcessUploadAndBuildParams(ssjlFiles, moduleCode, moduleName, applyFormId, "手术记录", "ssjl", fileStoragePath);
        if(ssjlRowDataList.size() > 0){
            dataList.addAll(ssjlRowDataList);
        }
        return dataList;
    }


    /**
     * 保存/修改一条【住院慰问】申请信息并且批量插入/修改与【住院慰问】申请信息相关联的文件信息
     * @return
     */
    @Transactional
    public void saveOrUpdateZywwApplyInfoAndBaseFileInfos(ZywwApplyInfo zywwApplyInfo, SysUser user, String applyFormId, List<BaseFileInfo> baseFileInfoList){
        // 如果当前申请信息对象zywwApplyInfo的申请单ID为空，代表是新增操作
        if(StringUtils.isBlank(zywwApplyInfo.getApplyFormId())){
            // 设置当前登录的用户信息
            zywwApplyInfo.setCreateUserId(String.valueOf(user.getUserId()));
            zywwApplyInfo.setCreateUserName(user.getNickName());
            zywwApplyInfo.setCreateUserPoliceNo(user.getPoliceNo());
            // 插入申请信息
            zywwApplyInfo.setApplyFormId(applyFormId);
            int insertRows = zywwApplyInfoMapper.insert(zywwApplyInfo);
            if(insertRows > 0){
                // 批量插入和申请信息关联的文件信息
                baseFileInfoMapper.batchInsertBaseFileInfos(baseFileInfoList);
                log.info("【住院慰问】申请信息、文件信息均保存成功  申请单ID：{}", applyFormId);
            } else {
                throw new RuntimeException("数据库【住院慰问】申请信息记录未插入  申请单ID：" + applyFormId);
            }
        } else {   // 修改操作
            // 根据申请单ID和zywwApplyInfo对象中的当前属性值去修改当前申请记录
            String applyFormIdExist = zywwApplyInfo.getApplyFormId();
            UpdateWrapper<ZywwApplyInfo> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("APPLY_FORM_ID", applyFormIdExist);
            int updateRows = zywwApplyInfoMapper.update(zywwApplyInfo, updateWrapper);
            if(updateRows > 0){
                // 批量修改和申请信息关联的文件信息
                // 1.先删除与当前申请记录相关联的全部原始文件记录
                baseService.delBaseFileInfosByApplyFormId(applyFormIdExist);
                // 2.再根据当前申请记录，批量插入新的文件记录，即可完成对文件信息的批量修改
                baseFileInfoMapper.batchInsertBaseFileInfos(baseFileInfoList);
                log.info("【住院慰问】申请信息、文件信息均修改成功  申请单ID：{}", applyFormIdExist);
            } else {
                throw new RuntimeException("数据库【住院慰问】申请信息记录未修改  申请单ID：" + applyFormIdExist);
            }
        }
    }

    /**
     * 保存/修改一条【住院慰问】申请信息
     * @return
     */
    @Transactional
    public boolean saveOrUpdateZywwApplyInfo(ZywwApplyInfo zywwApplyInfo, SysUser user){
        String applyFormId = zywwApplyInfo.getApplyFormId();
        QueryWrapper<ZywwApplyInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("APPLY_FORM_ID", applyFormId);
        ZywwApplyInfo dbZywwApplyInfo = zywwApplyInfoMapper.selectOne(queryWrapper);
        // 如果当前申请信息对象zywwApplyInfo的申请单ID在数据库中不存在（前端生成），代表是新增操作
        if(dbZywwApplyInfo == null){
            // 设置当前登录的用户信息
            zywwApplyInfo.setCreateUserId(String.valueOf(user.getUserId()));
            zywwApplyInfo.setCreateUserName(user.getNickName());
            zywwApplyInfo.setCreateUserPoliceNo(user.getPoliceNo());
            // 插入申请信息
            zywwApplyInfo.setApplyFormId(applyFormId);
            int insertRows = zywwApplyInfoMapper.insert(zywwApplyInfo);
            if(insertRows > 0){
                log.info("【住院慰问】申请信息保存成功  申请单ID：{}", applyFormId);
                return true;
            } else {
                throw new RuntimeException("数据库【住院慰问】申请信息记录未插入  申请单ID：" + applyFormId);
            }
        } else {   // 修改操作
            if("1".equals(dbZywwApplyInfo.getApproveStatusCode())){
                throw new RuntimeException("数据库【住院慰问】申请信息记录已通过审批，不支持修改  申请单ID：" + applyFormId);
            }
            // 根据申请单ID和zywwApplyInfo对象中的当前属性值去修改当前申请记录
            UpdateWrapper<ZywwApplyInfo> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("APPLY_FORM_ID", applyFormId);
            int updateRows = zywwApplyInfoMapper.update(zywwApplyInfo, updateWrapper);
            if(updateRows > 0){
                log.info("【住院慰问】申请信息修改成功  申请单ID：{}", applyFormId);
                return true;
            } else {
                throw new RuntimeException("数据库【住院慰问】申请信息记录未修改  申请单ID：" + applyFormId);
            }
        }
    }


    /**
     * 审批一条【住院慰问】申请信息，并插入一条审批记录
     * @return
     */
    @Transactional
    public boolean approveAndSaveApproveInfo(String applyFormId, String optFlag, SysUser user){
        // 审批一条【住院慰问】申请信息
        UpdateWrapper<ZywwApplyInfo> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("APPLY_FORM_ID", applyFormId);
        ZywwApplyInfo zywwApplyInfoDTO = new ZywwApplyInfo();
        zywwApplyInfoDTO.setApproveStatusCode(optFlag);
        String optDesc = "1".equals(optFlag)? "同意":"驳回";
        zywwApplyInfoDTO.setApproveStatusName(optDesc);
//        zywwApplyInfoDTO.setUpdateTime(new Date());
        int updateRows = zywwApplyInfoMapper.update(zywwApplyInfoDTO, updateWrapper);
        if(updateRows > 0){
            log.info("【住院慰问】申请信息已审批  申请单ID：{}，审批操作描述：{}", applyFormId, optDesc);
            // 插入一条审批记录
            BaseApproveInfo baseApproveInfo = new BaseApproveInfo();
            baseApproveInfo.setModuleCode("zyww");
            baseApproveInfo.setApplyFormId(applyFormId);
            QueryWrapper<ZywwApplyInfo> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("APPLY_FORM_ID", applyFormId);
            ZywwApplyInfo zywwApplyInfo = zywwApplyInfoMapper.selectOne(queryWrapper);
            baseApproveInfo.setCreateUserId(zywwApplyInfo.getCreateUserId());
            baseApproveInfo.setCreateUserName(zywwApplyInfo.getCreateUserName());
            baseApproveInfo.setCreateUserPoliceNo(zywwApplyInfo.getCreateUserPoliceNo());
            baseApproveInfo.setCreateTime(zywwApplyInfo.getCreateTime());
            baseApproveInfo.setApproveUserId(String.valueOf(user.getUserId()));
            baseApproveInfo.setApproveUserName(user.getNickName());
            baseApproveInfo.setApproveUserPoliceNo(user.getPoliceNo());
            baseApproveInfo.setApproveResultCode(optFlag);
            baseApproveInfo.setApproveResultDesc(optDesc);
            int insertRows = baseApproveInfoMapper.insert(baseApproveInfo);
            if(insertRows > 0){
                log.info("【住院慰问】审批信息保存成功  申请单ID：{}，审批人警号：{}，审批结果说明：{}", applyFormId, user.getPoliceNo(), optDesc);
                return true;
            }else {
                throw new RuntimeException("数据库【住院慰问】审批信息记录未插入");
            }
        }else {
            throw new RuntimeException("数据库【住院慰问】申请信息记录未更新或不存在");
        }

    }


    /**
     * 根据 审批状态 分页查询【住院慰问】申请信息
     * @param
     * @return
     */
    public Page<ZywwApplyInfo> getDataByPage(Integer approveStatus, String type, String optFlag, JSONObject reqBody){
        Integer pageIndex = reqBody.getInteger("pageIndex") == null? 1:reqBody.getInteger("pageIndex");
        Integer pageSize = reqBody.getInteger("pageSize") == null? 10:reqBody.getInteger("pageSize");
        String applyFormId = reqBody.getString("applyFormId");
        // 构造查询条件，支持多条件查询
        QueryWrapper<ZywwApplyInfo> queryWrapper = new QueryWrapper<>();
        // 1.查询当前用户能看到的整个系统中的全量"待审批"的记录，暂不考虑用户所属具体部门的因素
        if (approveStatus != null && approveStatus == 0 && "approve".equals(type)){
            // 匹配列表中的一条，对"待审批"的申请信息做数据回显及提供审批功能
            if(StringUtils.isNotBlank(applyFormId)){
                queryWrapper.eq("APPLY_FORM_ID", applyFormId);
            }
            queryWrapper.eq("APPROVE_STATUS_CODE", 0);
        }
        // 2.查询当前用户提交的全量"审批中"的申请记录（包含待审批记录、审批驳回记录）
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if (approveStatus != null && approveStatus == 3 && "apply".equals(type)){
            // 匹配列表中的一条，对"审批中"的申请信息做数据回显及提供修改功能
            if(StringUtils.isNotBlank(applyFormId)){
                queryWrapper.eq("APPLY_FORM_ID", applyFormId);
            }
            queryWrapper.eq("CREATE_USER_POLICE_NO", user.getPoliceNo());
            // 待审批和审批驳回（允许修改后继续提交）
            queryWrapper.and(qw -> qw.eq("APPROVE_STATUS_CODE", 0).or().eq("APPROVE_STATUS_CODE", 2));
        }
        // 3.查询当前用户提交的全量"已审批"的申请记录（只包含审批通过记录）
        if (approveStatus != null && approveStatus == 1 && "apply".equals(type)){
            // 匹配列表中的一条，对"已审批"的申请信息做数据回显
            if(StringUtils.isNotBlank(applyFormId)){
                queryWrapper.eq("APPLY_FORM_ID", applyFormId);
            }
            queryWrapper.eq("CREATE_USER_POLICE_NO", user.getPoliceNo());
            queryWrapper.eq("APPROVE_STATUS_CODE", 1);
        }
        queryWrapper.orderByDesc("CREATE_TIME");
        Page<ZywwApplyInfo> page = new Page<>(pageIndex, pageSize);
        Page<ZywwApplyInfo> pageDataList = zywwApplyInfoMapper.selectPage(page, queryWrapper);

        // 如果存在对应条件的用户申请记录，并且当前是修改数据前的数据回显操作，则继续查询该申请记录对应的文件信息记录，并返回给前端
        if(pageDataList != null && pageDataList.getTotal() > 0 && "update".equals(optFlag) && StringUtils.isNotBlank(applyFormId)){
            QueryWrapper<BaseFileInfo> qw = new QueryWrapper<>();
            qw.eq("APPLY_FORM_ID", applyFormId);
            List<BaseFileInfo> baseFileInfosList = baseFileInfoMapper.selectList(qw);
            // 将查询到的文件信息记录填充到对应的申请信息记录对象中，做数据回显使用
            if(baseFileInfosList != null && baseFileInfosList.size() > 0){
                ZywwApplyInfo zywwApplyInfo = pageDataList.getRecords().get(0);
                zywwApplyInfo.setBaseFileInfos(baseFileInfosList);
            }
        }
        return pageDataList;
    }

}
