package com.ruoyi.system.service.webOfficeImpl;


import cn.ljserver.tool.weboffice.v3.exception.FileUploadNotComplete;
import cn.ljserver.tool.weboffice.v3.exception.InvalidArgument;
import cn.ljserver.tool.weboffice.v3.model.DigestType;
import cn.ljserver.tool.weboffice.v3.model.FileInfo;
import cn.ljserver.tool.weboffice.v3.model.FileUploadMultiPhase;
import cn.ljserver.tool.weboffice.v3.service.MultiPhaseFileStorageService;
import cn.ljserver.tool.weboffice.v3.util.FileUtils;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.system.domain.webOffice.WebofficeFj;
import com.ruoyi.system.service.webService.WebofficeFjServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * 三阶段文件保存接口（复杂，建议用Single方式）
 * <br>
 * <a href="https://solution.wps.cn/docs/callback/save.html#%E4%B8%89%E9%98%B6%E6%AE%B5%E4%BF%9D%E5%AD%98">详见wps web office官网</a>
 */
@Service
public class MultiPhaseFileStorageServiceImpl implements MultiPhaseFileStorageService {

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private WebofficeFjServiceImpl webofficeFjServiceImpl;

    /**
     * 准备上传阶段
     *
     * @param s 文件id <br>
     *          <a href = "https://solution.wps.cn/docs/callback/save.html#准备上传阶段">-详见官方文档-</a>
     */
    @Override
    public List<DigestType> uploadPrepare(String s) {
        return Collections.singletonList(DigestType.SHA1);
    }

    /**
     * 获取上传地址
     *
     * @param request 上传的文件 <br>
     *                <a href = "https://solution.wps.cn/docs/callback/save.html#获取上传地址">-详见官方文档-</a>
     */
    @Override
    public FileUploadMultiPhase.FileUploadAddress.Response uploadAddress(FileUploadMultiPhase.FileUploadAddress.Request request) {
        // ATTENTION
        // ConsoleController.upload() handle the upload request
        // and store the new content of file, and create a new version of file
        // without invoke uploadComplete method
        // it is not good in the real world
        // ***************************************************************
        // ***************************************************************
        // 这一步建议将fileName获取到后，拿到文件后缀，然后存到redis，或者其它地方
        // ***************************************************************
        // ***************************************************************
        // 然后在调用 正真的 upload 方法的时候，需要确认当前的文件后缀
        // ***************************************************************
        // ***************************************************************

        // 这里简单的放内存
        String suffix = FileUtils.suffix(request.getName());
        redisCache.setCacheObject(request.getFileId(), suffix, 2, TimeUnit.HOURS);

        // 返回地址
        return FileUploadMultiPhase.FileUploadAddress.Response.builder()
                // 方法必须是PUT接口
                .method(FileUploadMultiPhase.FileUploadAddress.Response.Method.PUT)
                // 获取自定义上传接口方法
                // 这里的url是自定义的，需要开发者自己实现,也就是自己的回调地址
                .url(String.format("%s/prod-api/console/upload/" + request.getFileId(), "https://rzdb.qs163.cn", request.getFileId()))
                .build();
    }

    /**
     * 上传完成后，回调通知上传结果
     *
     * @param request 上传的文件 <br>
     *                <a href = "https://solution.wps.cn/docs/callback/save.html#上传完成后，回调通知上传结果">-详见官方文档-</a>
     */
    @Override
    public FileInfo uploadComplete(FileUploadMultiPhase.FileUploadComplete.Request request) {
        if (request == null) throw new InvalidArgument();

        // emm
        Optional.of(request)
                .map(FileUploadMultiPhase.FileUploadComplete.Request::getResponse)
                .filter(r -> r.getStatus() == HttpStatus.OK.value())
                .ifPresent(r -> {
                });

        // 获取当前用户,实际不是这么玩的，点进去看看
        //SysUser user = SecurityUtils.getLoginUser().getUser();
        // 回调中body返回的是url
        // --------------------------------
        // 这里不应该直接URL，而是不带domain的uri方便后续迁移等等
        // 为了方便，就这么弄了
        // --------------------------------
        String url = request.getResponse().getBody();

        // 获取文件 并 返回文件信息
        WebofficeFj webofficeFj = webofficeFjServiceImpl.fetchFile(request.getFileId());
        int version = 1;
        LocalDateTime createTime = LocalDateTime.now();
        if (webofficeFj != null) {
            version = webofficeFj.getVersion();
            createTime = webofficeFj.getCreateTime();
        }
        return FileInfo.builder()
                .id(request.getFileId())
                .name(request.getRequest().getName())
                .version(version)
                .size(request.getRequest().getSize())
                .createTime(createTime)
                .modifyTime(LocalDateTime.now())
                .build();
    }
}
