package com.ruoyi.system.service.webOfficeImpl;


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.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.system.domain.loan.LoanApplicationFj;
import com.ruoyi.system.domain.webOffice.WebofficeFj;
import com.ruoyi.system.mapper.LoanApplicationFjMapper;
import com.ruoyi.system.mapper.WebofficeFjMapper;
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.*;
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;

    @Autowired
    private WebofficeFjMapper webofficeFjMapper;

    @Autowired
    private LoanApplicationFjMapper loanApplicationFjMapper;

    /**
     * 准备上传阶段
     *
     * @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);
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Map<String, String> map = new HashMap<>();
        map.put("X-WPS-USERID", String.valueOf(user.getUserId()));

        // 返回地址
        return FileUploadMultiPhase.FileUploadAddress.Response.builder()
                // 方法必须是PUT接口
                .method(FileUploadMultiPhase.FileUploadAddress.Response.Method.PUT)
                .extraHeaders(map)
                // 获取自定义上传接口方法
                // 这里的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，
        // --------------------------------
        LoanApplicationFj cacheObject = redisCache.getCacheObject(request.getFileId() + "info");
        String fileName = redisCache.getCacheObject(request.getFileId() + "fileName");
        System.out.println(fileName + "yyyyyyyyyyyyyyyyyyyyyyyyyyy");
        // 获取文件 并 返回文件信息
        WebofficeFj weboffice = webofficeFjServiceImpl.fetchFile(request.getFileId());
        int version = 1;
        LocalDateTime createTime = LocalDateTime.now();
        if (weboffice != null) {
            version = weboffice.getVersion() + 1;
            createTime = weboffice.getCreateTime();
        }
        WebofficeFj webofficeFj = new WebofficeFj();
        webofficeFj.setFjId(request.getFileId());
        webofficeFj.setVersion(version);
        webofficeFj.setUrl(fileName);
        webofficeFj.setCreateTime(createTime);
        webofficeFj.setUpdateTime(LocalDateTime.now());
        webofficeFj.setSize(Long.valueOf(request.getRequest().getSize()));
        webofficeFj.setName(com.ruoyi.common.utils.file.FileUtils.getName(fileName));
        webofficeFj.setCreateBy(user.getNickName());
        webofficeFj.setCreatorId(String.valueOf(user.getUserId()));
        webofficeFj.setModifierId(String.valueOf(user.getUserId()));
        webofficeFjMapper.insertWebofficeFj(webofficeFj);
        System.out.println(webofficeFj + "hhhhhhhhhhhhhhhhhhhhhhhhhhh");
        //数据库查询
        LoanApplicationFj applicationFj = new LoanApplicationFj();
        applicationFj.setLoanApplicationNumber(cacheObject.getLoanApplicationNumber());
        applicationFj.setBigType(cacheObject.getBigType());
        applicationFj.setType(cacheObject.getType());
        List<LoanApplicationFj> loanApplicationFjs = loanApplicationFjMapper.selectLoanApplicationFjList(applicationFj);
        if (loanApplicationFjs == null || loanApplicationFjs.size() <= 0) {
            //将文件存入loan_application_fj表
            LoanApplicationFj loanApplicationFj = new LoanApplicationFj();
            loanApplicationFj.setLoanApplicationId(cacheObject.getLoanApplicationId());
            loanApplicationFj.setLoanApplicationNumber(cacheObject.getLoanApplicationNumber());
            loanApplicationFj.setOldName(cacheObject.getName());
            loanApplicationFj.setName(com.ruoyi.common.utils.file.FileUtils.getName(fileName));
            loanApplicationFj.setUrl(fileName);
            loanApplicationFj.setBigType(cacheObject.getBigType());
            loanApplicationFj.setType(cacheObject.getType());
            loanApplicationFj.setCreateBy(user.getNickName());
            loanApplicationFj.setCreateTime(DateUtils.getNowDate());
            loanApplicationFjMapper.insertLoanApplicationFj(loanApplicationFj);
            System.out.println(loanApplicationFj.toString() + "888888888888888888888888888888");
        }


        return FileInfo.builder()
                .id(request.getFileId())
                .name(request.getRequest().getName())
                .version(version)
                .size(request.getRequest().getSize())
                .createTime(createTime)
                .modifyTime(LocalDateTime.now())
                .modifierId(String.valueOf(user.getUserId()))
                .creatorId(String.valueOf(user.getUserId()))
                .build();
    }
}
