package com.ruoyi.zzb.common.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.framework.config.ServerConfig;
import com.ruoyi.zzb.common.domain.BaseFileInfo;
import com.ruoyi.zzb.common.domain.BaseFileSetDTO;
import com.ruoyi.zzb.common.mapper.BaseFileInfoMapper;
import com.ruoyi.zzb.common.utils.CommonUtils;
import com.ruoyi.zzb.dbjz.mapper.DbjzApplyInfoMapper;
import com.ruoyi.zzb.hybz.mapper.HybzApplyInfoMapper;
import com.ruoyi.zzb.zyww.domain.ZywwFileSetDTO;
import com.ruoyi.zzb.zyww.mapper.ZywwApplyInfoMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

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

    @Autowired
    private BaseFileInfoMapper baseFileInfoMapper;
    @Autowired
    private ServerConfig serverConfig;
    @Autowired
    private JavaMailSender mailSender;
    @Value("${spring.mail.username}")
    private String from;
    @Autowired
    private ZywwApplyInfoMapper zywwApplyInfoMapper;
    @Autowired
    private DbjzApplyInfoMapper dbjzApplyInfoMapper;
    @Autowired
    private HybzApplyInfoMapper hybzApplyInfoMapper;

    /**
     * 发送一条带附件的邮件消息
     * @param to
     * @param subject
     * @param text
     * @param attachmentPath
     * @param files
     * @throws MessagingException
     * @throws UnsupportedEncodingException
     */
    public void sendEmail(String to, String subject, String text, String attachmentPath, File[] files) throws MessagingException, UnsupportedEncodingException {
        MimeMessage message = mailSender.createMimeMessage();
        //解决附件文件名称过长乱码问题
        System.setProperty("mail.mime.splitlongparameters", "false");
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
        helper.setFrom(from);
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(text);
        // 添加附件（多个）
        if(files != null && files.length > 0) {
            for (File file : files) {
                helper.addAttachment(MimeUtility.encodeWord(file.getName(), "utf-8", "B"), file);
            }
        }
        /*FileSystemResource file = new FileSystemResource(new File(attachmentPath));
        // 添加附件（单个）
        helper.addAttachment(file.getFilename(), file);*/
        mailSender.send(message);
    }


    /**
     * 根据申请单ID 删除与之关联的文件信息记录
     * @param applyFormId
     * @return
     */
    @Transactional
    public boolean delBaseFileInfosByApplyFormId(String applyFormId){
        QueryWrapper<BaseFileInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("APPLY_FORM_ID", applyFormId);
        int delRows = baseFileInfoMapper.delete(queryWrapper);
        if(delRows > 0){
            log.info("当前申请信息关联的文件信息删除成功  申请单ID：{}，删除的数据条数：{}", applyFormId, delRows);
            return true;
        } else {
            throw new RuntimeException("数据库申请信息对应的文件信息记录未删除或不存在  申请单ID：" + applyFormId);
        }
    }


    /**
     * 根据文件存储ID删除对应的文件信息记录
     * @param fileStorageId
     * @return
     */
    @Transactional
    public boolean delBaseFileInfosByFileStorageId(String fileStorageId){
        QueryWrapper<BaseFileInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("FILE_STORAGE_ID", fileStorageId);
        int delRows = baseFileInfoMapper.delete(queryWrapper);
        if(delRows > 0){
            log.info("文件信息删除成功  文件存储ID：{}，删除的数据条数：{}", fileStorageId, delRows);
            return true;
        } else {
            throw new RuntimeException("数据库文件信息记录未删除或不存在  文件存储ID：" + fileStorageId);
        }
    }


    /**
     * 功能描述: 业务模块处理文件上传并构建文件信息参数对象通用方法
     * @param: [baseFileSetDTO, moduleCode, moduleName, applyFormId, fileStoragePath]
     * @return: java.util.List<com.ruoyi.zzb.common.domain.BaseFileInfo>
     * @author: peifjFantasy
     * @Date: 2024/12/4 15:08
     */
    public List<BaseFileInfo> processUploadAndBuildParams(BaseFileSetDTO baseFileSetDTO, String moduleCode, String moduleName, String applyFormId, String fileStoragePath) throws IOException {
        List<BaseFileInfo> dataList = new ArrayList<>();
        if("zyww".equals(moduleCode)){   // 住院慰问
            MultipartFile[] zywwsqbFiles = baseFileSetDTO.getZywwsqbFiles();
            List<BaseFileInfo> zywwsqbRowDataList = doProcessUploadAndBuildParams(zywwsqbFiles, moduleCode, moduleName, applyFormId, "住院慰问申请表", "zywwsqb", fileStoragePath);
            if(zywwsqbRowDataList.size() > 0){
                dataList.addAll(zywwsqbRowDataList);
            }
            MultipartFile[] zywwjhzsqbFiles = baseFileSetDTO.getZywwjhzsqbFiles();
            List<BaseFileInfo> zywwjhzsqbRowDataList = doProcessUploadAndBuildParams(zywwjhzsqbFiles, moduleCode, moduleName, applyFormId, "住院慰问金汇总申请表", "zywwjhzsqb", fileStoragePath);
            if(zywwjhzsqbRowDataList.size() > 0){
                dataList.addAll(zywwjhzsqbRowDataList);
            }
            MultipartFile[] jcghwwjsbbFiles = baseFileSetDTO.getJcghwwjsbbFiles();
            List<BaseFileInfo> jcghwwjsbbRowDataList = doProcessUploadAndBuildParams(jcghwwjsbbFiles, moduleCode, moduleName, applyFormId, "基层工会慰问金申报表", "jcghwwjsbb", fileStoragePath);
            if(jcghwwjsbbRowDataList.size() > 0){
                dataList.addAll(jcghwwjsbbRowDataList);
            }
            MultipartFile[] zzzmFiles = baseFileSetDTO.getZzzmFiles();
            List<BaseFileInfo> zzzmRowDataList = doProcessUploadAndBuildParams(zzzmFiles, moduleCode, moduleName, applyFormId, "在职证明", "zzzm", fileStoragePath);
            if(zzzmRowDataList.size() > 0){
                dataList.addAll(zzzmRowDataList);
            }
            MultipartFile[] gsFiles = baseFileSetDTO.getGsFiles();
            List<BaseFileInfo> gsRowDataList = doProcessUploadAndBuildParams(gsFiles, moduleCode, moduleName, applyFormId, "公示", "gs", fileStoragePath);
            if(gsRowDataList.size() > 0){
                dataList.addAll(gsRowDataList);
            }
            MultipartFile[] ghhykfyjFiles = baseFileSetDTO.getGhhykfyjFiles();
            List<BaseFileInfo> ghhykfyjRowDataList = doProcessUploadAndBuildParams(ghhykfyjFiles, moduleCode, moduleName, applyFormId, "工会会员卡复印件", "ghhykfyj", fileStoragePath);
            if(ghhykfyjRowDataList.size() > 0){
                dataList.addAll(ghhykfyjRowDataList);
            }
            MultipartFile[] zybasyfyjFiles = baseFileSetDTO.getZybasyfyjFiles();
            List<BaseFileInfo> zybasyfyjRowDataList = doProcessUploadAndBuildParams(zybasyfyjFiles, moduleCode, moduleName, applyFormId, "住院病案首页复印件", "zybasyfyj", fileStoragePath);
            if(zybasyfyjRowDataList.size() > 0){
                dataList.addAll(zybasyfyjRowDataList);
            }
            MultipartFile[] zdzmfyjFiles = baseFileSetDTO.getZdzmfyjFiles();
            List<BaseFileInfo> zdzmfyjRowDataList = doProcessUploadAndBuildParams(zdzmfyjFiles, moduleCode, moduleName, applyFormId, "诊断证明复印件", "zdzmfyj", fileStoragePath);
            if(zdzmfyjRowDataList.size() > 0){
                dataList.addAll(zdzmfyjRowDataList);
            }
            MultipartFile[] gszmFiles = baseFileSetDTO.getGszmFiles();
            List<BaseFileInfo> gszmRowDataList = doProcessUploadAndBuildParams(gszmFiles, moduleCode, moduleName, applyFormId, "工伤证明", "gszm", fileStoragePath);
            if(gszmRowDataList.size() > 0){
                dataList.addAll(gszmRowDataList);
            }
            MultipartFile[] ssjlFiles = baseFileSetDTO.getSsjlFiles();
            List<BaseFileInfo> ssjlRowDataList = doProcessUploadAndBuildParams(ssjlFiles, moduleCode, moduleName, applyFormId, "手术记录", "ssjl", fileStoragePath);
            if(ssjlRowDataList.size() > 0){
                dataList.addAll(ssjlRowDataList);
            }
        } else if("dbjz".equals(moduleCode)){   // 大病救助
            MultipartFile[] dbjzsqbFiles = baseFileSetDTO.getDbjzsqbFiles();
            List<BaseFileInfo> dbjzsqbRowDataList = doProcessUploadAndBuildParams(dbjzsqbFiles, moduleCode, moduleName, applyFormId, "大病救助申请表", "dbjzsqb", fileStoragePath);
            if(dbjzsqbRowDataList.size() > 0){
                dataList.addAll(dbjzsqbRowDataList);
            }
            MultipartFile[] dbjlqzmFiles = baseFileSetDTO.getDbjlqzmFiles();
            List<BaseFileInfo> dbjlqzmRowDataList = doProcessUploadAndBuildParams(dbjlqzmFiles, moduleCode, moduleName, applyFormId, "低保金领取证明", "dbjlqzm", fileStoragePath);
            if(dbjlqzmRowDataList.size() > 0){
                dataList.addAll(dbjlqzmRowDataList);
            }
            MultipartFile[] yyfyjnmxzmFiles = baseFileSetDTO.getYyfyjnmxzmFiles();
            List<BaseFileInfo> yyfyjnmxzmRowDataList = doProcessUploadAndBuildParams(yyfyjnmxzmFiles, moduleCode, moduleName, applyFormId, "医药费用缴纳明细证明", "yyfyjnmxzm", fileStoragePath);
            if(yyfyjnmxzmRowDataList.size() > 0){
                dataList.addAll(yyfyjnmxzmRowDataList);
            }
            MultipartFile[] zdzmfyjFiles = baseFileSetDTO.getZdzmfyjFiles();
            List<BaseFileInfo> zdzmfyjRowDataList = doProcessUploadAndBuildParams(zdzmfyjFiles, moduleCode, moduleName, applyFormId, "诊断证明复印件", "zdzmfyj", fileStoragePath);
            if(zdzmfyjRowDataList.size() > 0){
                dataList.addAll(zdzmfyjRowDataList);
            }
            MultipartFile[] basyfyjFiles = baseFileSetDTO.getBasyfyjFiles();
            List<BaseFileInfo> basyfyjRowDataList = doProcessUploadAndBuildParams(basyfyjFiles, moduleCode, moduleName, applyFormId, "病案首页复印件", "basyfyj", fileStoragePath);
            if(basyfyjRowDataList.size() > 0){
                dataList.addAll(basyfyjRowDataList);
            }
            MultipartFile[] ryjlfyjFiles = baseFileSetDTO.getRyjlfyjFiles();
            List<BaseFileInfo> ryjlfyjRowDataList = doProcessUploadAndBuildParams(ryjlfyjFiles, moduleCode, moduleName, applyFormId, "入院记录复印件", "ryjlfyj", fileStoragePath);
            if(ryjlfyjRowDataList.size() > 0){
                dataList.addAll(ryjlfyjRowDataList);
            }
            MultipartFile[] cyjlfyjFiles = baseFileSetDTO.getCyjlfyjFiles();
            List<BaseFileInfo> cyjlfyjRowDataList = doProcessUploadAndBuildParams(cyjlfyjFiles, moduleCode, moduleName, applyFormId, "出院记录复印件", "cyjlfyj", fileStoragePath);
            if(cyjlfyjRowDataList.size() > 0){
                dataList.addAll(cyjlfyjRowDataList);
            }
            MultipartFile[] gsFiles = baseFileSetDTO.getGsFiles();
            List<BaseFileInfo> gsRowDataList = doProcessUploadAndBuildParams(gsFiles, moduleCode, moduleName, applyFormId, "公示", "gs", fileStoragePath);
            if(gsRowDataList.size() > 0){
                dataList.addAll(gsRowDataList);
            }
        } else {   // 会员保障
            MultipartFile[] ckhyspbFiles = baseFileSetDTO.getCkhyspbFiles();
            List<BaseFileInfo> ckhyspbRowDataList = doProcessUploadAndBuildParams(ckhyspbFiles, moduleCode, moduleName, applyFormId, "持卡会员审批表", "ckhyspb", fileStoragePath);
            if (ckhyspbRowDataList.size() > 0) {
                dataList.addAll(ckhyspbRowDataList);
            }
            MultipartFile[] hykfyjFiles = baseFileSetDTO.getHykfyjFiles();
            List<BaseFileInfo> hykfyjRowDataList = doProcessUploadAndBuildParams(hykfyjFiles, moduleCode, moduleName, applyFormId, "会员卡复印件", "hykfyj", fileStoragePath);
            if (hykfyjRowDataList.size() > 0) {
                dataList.addAll(hykfyjRowDataList);
            }
            MultipartFile[] zdzmyjFiles = baseFileSetDTO.getZdzmyjFiles();
            List<BaseFileInfo> zdzmyjRowDataList = doProcessUploadAndBuildParams(zdzmyjFiles, moduleCode, moduleName, applyFormId, "诊断证明原件", "zdzmyj", fileStoragePath);
            if (zdzmyjRowDataList.size() > 0) {
                dataList.addAll(zdzmyjRowDataList);
            }
            MultipartFile[] basyfyjFiles = baseFileSetDTO.getBasyfyjFiles();
            List<BaseFileInfo> basyfyjRowDataList = doProcessUploadAndBuildParams(basyfyjFiles, moduleCode, moduleName, applyFormId, "病案首页复印件", "basyfyj", fileStoragePath);
            if (basyfyjRowDataList.size() > 0) {
                dataList.addAll(basyfyjRowDataList);
            }
            MultipartFile[] ryjlfyjFiles = baseFileSetDTO.getRyjlfyjFiles();
            List<BaseFileInfo> ryjlfyjRowDataList = doProcessUploadAndBuildParams(ryjlfyjFiles, moduleCode, moduleName, applyFormId, "入院记录复印件", "ryjlfyj", fileStoragePath);
            if (ryjlfyjRowDataList.size() > 0) {
                dataList.addAll(ryjlfyjRowDataList);
            }
            MultipartFile[] ssjlfyjFiles = baseFileSetDTO.getSsjlfyjFiles();
            List<BaseFileInfo> ssjlfyjRowDataList = doProcessUploadAndBuildParams(ssjlfyjFiles, moduleCode, moduleName, applyFormId, "手术记录复印件", "ssjlfyj", fileStoragePath);
            if (ssjlfyjRowDataList.size() > 0) {
                dataList.addAll(ssjlfyjRowDataList);
            }
            MultipartFile[] cyjlfyjFiles = baseFileSetDTO.getCyjlfyjFiles();
            List<BaseFileInfo> cyjlfyjRowDataList = doProcessUploadAndBuildParams(cyjlfyjFiles, moduleCode, moduleName, applyFormId, "出院记录复印件", "cyjlfyj", fileStoragePath);
            if (cyjlfyjRowDataList.size() > 0) {
                dataList.addAll(cyjlfyjRowDataList);
            }
            MultipartFile[] blbgfyjFiles = baseFileSetDTO.getBlbgfyjFiles();
            List<BaseFileInfo> blbgfyjRowDataList = doProcessUploadAndBuildParams(blbgfyjFiles, moduleCode, moduleName, applyFormId, "病理报告复印件", "blbgfyj", fileStoragePath);
            if (blbgfyjRowDataList.size() > 0) {
                dataList.addAll(blbgfyjRowDataList);
            }
            MultipartFile[] jcbgfyjFiles = baseFileSetDTO.getJcbgfyjFiles();
            List<BaseFileInfo> jcbgfyjRowDataList = doProcessUploadAndBuildParams(jcbgfyjFiles, moduleCode, moduleName, applyFormId, "检查报告复印件", "jcbgfyj", fileStoragePath);
            if (jcbgfyjRowDataList.size() > 0) {
                dataList.addAll(jcbgfyjRowDataList);
            }
        }
        MultipartFile[] sfzfyjFiles = baseFileSetDTO.getSfzfyjFiles();
        List<BaseFileInfo> sfzfyjRowDataList = doProcessUploadAndBuildParams(sfzfyjFiles, moduleCode, moduleName, applyFormId, "身份证复印件", "sfzfyj", fileStoragePath);
        if(sfzfyjRowDataList.size() > 0){
            dataList.addAll(sfzfyjRowDataList);
        }
        return dataList;
    }


    /**
     * 统一处理业务模块文件上传，并构造对应数据对象
     * @param files
     * @param moduleCode
     * @param moduleName
     * @param applyFormId
     * @param fileTypeName
     * @param fileTypeCode
     * @param fileStoragePath
     * @return
     * @throws IOException
     */
    public List<BaseFileInfo> doProcessUploadAndBuildParams(MultipartFile[] files, String moduleCode, String moduleName, String applyFormId, String fileTypeName, String fileTypeCode, String fileStoragePath) throws IOException {
        List<BaseFileInfo> rowDataList = new ArrayList<>();
        if(null != files && files.length > 0){
            AtomicInteger fileOrder = new AtomicInteger(0);
            for (MultipartFile file : files) {
                if (!file.isEmpty()) {
                    // 原始文件名
                    String originalFilename = file.getOriginalFilename();
                    // 文件扩展名
                    String fileExtensions = CommonUtils.getFileExtension(originalFilename);
                    // 文件存储ID（MD5值）
                    String fileStorageId = CommonUtils.md5(originalFilename + new Date().getTime());
                    // 上传文件，并返回新的文件名称
                    String newFileName = FileUploadUtils.upload(fileStoragePath, file);
                    log.info("【{}】文件上传成功  申请单ID：{}，文件类型名称：{}，文件名称：{}", moduleName, applyFormId, fileTypeName, originalFilename);
                    // 文件HTTP请求路径
                    String fileRequestPath = serverConfig.getUrl() + newFileName;
                    BaseFileInfo baseFileInfo = new BaseFileInfo();
                    baseFileInfo.setModuleCode(moduleCode);
                    baseFileInfo.setApplyFormId(applyFormId);
                    baseFileInfo.setFileTypeName(fileTypeName);
                    baseFileInfo.setFileTypeCode(fileTypeCode);
                    baseFileInfo.setFileOrder(fileOrder.incrementAndGet());
                    baseFileInfo.setFileOriginalName(originalFilename);
                    baseFileInfo.setFileExtensions(fileExtensions);
                    baseFileInfo.setFileStorageId(fileStorageId);
                    baseFileInfo.setFileRequestPath(fileRequestPath);
                    baseFileInfo.setFileStoragePath(fileStoragePath);
                    baseFileInfo.setIsDelete(0);
                    rowDataList.add(baseFileInfo);
                }
            }
        }
        return rowDataList;
    }


    /**
     * 根据模块编码、申请单ID获取对应的申请信息记录
     * @param moduleCode
     * @param applyFormId
     * @return
     */
    public Object getDataByApplyFormId(String moduleCode, String applyFormId){
        if("zyww".equals(moduleCode)){
            return zywwApplyInfoMapper.selectById(applyFormId);
        }else if("dbjz".equals(moduleCode)){
            return dbjzApplyInfoMapper.selectById(applyFormId);
        }else {
            return hybzApplyInfoMapper.selectById(applyFormId);
        }
    }


    /**
     * 功能描述: 保存一条文件信息记录
     * @param: [baseFileInfo]
     * @return: boolean
     * @author: peifjFantasy
     * @Date: 2024/11/28 14:42
     */
    public boolean saveBaseFileInfo(BaseFileInfo baseFileInfo){
        if(baseFileInfo != null){
            int insertRows = baseFileInfoMapper.insert(baseFileInfo);
            return insertRows > 0? true : false;
        }
        return false;
    }

}
