package cn.fateverse.workflow.service.impl;

import cn.fateverse.common.core.exception.CustomException;
import cn.fateverse.common.file.service.impl.FastDFSStoreService;
import cn.fateverse.workflow.entity.ProcessFile;
import cn.fateverse.workflow.entity.bpmn.Attachment;
import cn.fateverse.workflow.mapper.ProcessFileMapper;
import cn.fateverse.workflow.service.ProcessFileService;
import cn.fateverse.common.file.entity.FileInfo;
import cn.fateverse.common.file.service.FileStoreService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.Objects;

/**
 * @author Clay
 * @date 2023/1/10
 */
@Slf4j
@Service
public class ProcessFileServiceImpl implements ProcessFileService {

    private final FileStoreService fileStoreService;

    private final ProcessFileMapper processFileMapper;

    private final ThreadPoolTaskExecutor executor;


    public ProcessFileServiceImpl(FastDFSStoreService fileStoreService,
                                  ProcessFileMapper processFileMapper,
                                  ThreadPoolTaskExecutor taskExecuteExecutor) {
        this.fileStoreService = fileStoreService;
        this.processFileMapper = processFileMapper;
        this.executor = taskExecuteExecutor;
    }


    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public Attachment uploadFile(MultipartFile file) throws Exception {
        //调用oss上传文件
        FileInfo upload = fileStoreService.upload(file);
        ProcessFile processFile = new ProcessFile();
        BeanUtils.copyProperties(upload, processFile);
        //将文件信息落地到本地数据库,方便进行管理
        processFileMapper.insert(processFile);
        //返回前端需要的数据
        return Attachment.builder()
                .id(processFile.getId())
                .name(processFile.getOriginalFilename())
                .size(processFile.getSize())
                .isImage(processFile.getIsImage())
                .url(processFile.getUrl())
                .build();
    }

    @Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void deleteFile(Long fileId) {
        //从本地数据库中查询出流程文件对象
        ProcessFile processFile = processFileMapper.selectById(fileId);
        if (Objects.isNull(processFile)) {
            throw new CustomException("文件不存在");
        }
        //本地删除文件信息
        processFileMapper.delete(fileId);
        executor.execute(() -> {
            //在oss端删除文件
            fileStoreService.delete(processFile.getUri());
        });
    }
}
