package ink.wgink.module.form.service.onlyoffice.impl;

import com.alibaba.fastjson2.JSONObject;
import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.exceptions.ParamsException;
import ink.wgink.exceptions.SearchException;
import ink.wgink.module.file.enums.UploadTypeEnum;
import ink.wgink.module.file.pojo.dtos.v2.FileUploadSuccessDTO;
import ink.wgink.module.file.pojo.vos.v2.FileUpdateVO;
import ink.wgink.module.file.service.v2.IFileService;
import ink.wgink.module.form.pojo.dtos.onlyoffice.config.DocumentDTO;
import ink.wgink.module.form.pojo.dtos.onlyoffice.config.EditConfigDTO;
import ink.wgink.module.form.pojo.dtos.onlyoffice.config.PermissionsDTO;
import ink.wgink.module.form.pojo.vos.onlyoffice.OnlyOfficeSaveVO;
import ink.wgink.module.form.service.onlyoffice.IOnlyOfficeService;
import ink.wgink.pojo.bos.UserInfoBO;
import ink.wgink.pojo.pos.FilePO;
import ink.wgink.properties.onlyoffice.OnlyOfficeProperties;
import ink.wgink.util.UUIDUtil;
import ink.wgink.util.string.WStringUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

/**
 * @ClassName: OnlyOfficeServiceImpl
 * @Description: onlyoffice
 * @Author: wanggeng
 * @Date: 2022/7/24 15:33
 * @Version: 1.0
 */
@Service
public class OnlyOfficeServiceImpl extends DefaultBaseService implements IOnlyOfficeService {

    public static final String[] WORD_FILE_TYPE_ARRAY = new String[]{
            "doc", "docx", "docm", "docxf", "dot", "dotm", "dotx", "epub", "fodt", "fb2", "htm", "html", "mht", "odt",
            "oform", "ott", "oxps", "pdf", "rtf", "txt", "djvu", "xml", "xps"};
    public static final String[] CELL_FILE_TYPE_ARRAY = new String[]{
            "csv", "fods", "ods", "ots", "xls", "xlsb", "xlsm", "xlsx", "xlt", "xltm", "xltx"};
    public static final String[] SLIDE_FILE_TYPE_ARRAY = new String[]{
            "fodp", "odp", "otp", "pot", "potm", "potx", "pps", "ppsm", "ppsx", "ppt", "pptm", "pptx"};

    @Autowired
    private OnlyOfficeProperties onlyOfficeProperties;
    @Autowired
    private IFileService fileV2Service;


    @Override
    public void save(String formCode, Integer formVersion, String uid, String fileId, OnlyOfficeSaveVO onlyOfficeSaveVO) {
        FilePO filePO = fileV2Service.getPO(fileId);
        if (filePO == null) {
            throw new SearchException("文件不存在");
        }
        try {
            URL url = new URL(onlyOfficeSaveVO.getUrl());
            HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
            InputStream inputStream = httpURLConnection.getInputStream();
            FileUploadSuccessDTO uploadSuccessDTO = fileV2Service.uploadSingleByUserId(onlyOfficeSaveVO.getUsers().get(0), inputStream, UploadTypeEnum.FILE, filePO.getFileName());
            // 调换文件信息，保留原来的ID不变
            String newFileId = uploadSuccessDTO.getFileId();
            FilePO newFilePO = fileV2Service.getPO(newFileId);

            // 新文件信息 -> 旧文件
            FileUpdateVO fileUpdateVO = new FileUpdateVO();
            BeanUtils.copyProperties(newFilePO, fileUpdateVO);
            fileUpdateVO.setUploadPath(newFilePO.getFilePath());
            fileUpdateVO.setFileId(filePO.getFileId());
            fileV2Service.update(fileUpdateVO);

            // 旧的文件信息 -> 新文件
            BeanUtils.copyProperties(filePO, fileUpdateVO);
            fileUpdateVO.setUploadPath(filePO.getFilePath());
            fileUpdateVO.setFileId(newFilePO.getFileId());
            fileV2Service.update(fileUpdateVO);
        } catch (RuntimeException | IOException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public JSONObject getConfig(String formCode, Integer formVersion, String uid, String fileId) {
        FilePO filePO = fileV2Service.getPO(fileId);
        if (filePO == null) {
            throw new SearchException("文件不存在");
        }
        DocumentDTO documentDTO = new DocumentDTO();
        documentDTO.setFileType(filePO.getFileType());
        documentDTO.setTitle(filePO.getFileName());
        documentDTO.setKey(WStringUtil.randomSubStr(UUIDUtil.get32UUID(), 20));
        documentDTO.setUrl(onlyOfficeProperties.getCallbackUrl() + "/route/file/download/false/" + fileId);
        // 权限
        PermissionsDTO permissionsDTO = new PermissionsDTO();
        permissionsDTO.setChat(false);
        permissionsDTO.setComment(true);
        permissionsDTO.setCopy(true);
        permissionsDTO.setDeleteCommentAuthorOnly(false);
        permissionsDTO.setDownload(true);
        permissionsDTO.setEdit(true);
        permissionsDTO.setEditCommentAuthorOnly(false);
        permissionsDTO.setFillForms(true);
        permissionsDTO.setModifyContentControl(true);
        permissionsDTO.setModifyFilter(true);
        permissionsDTO.setPrint(true);
        permissionsDTO.setProtect(true);
        permissionsDTO.setReview(true);
        documentDTO.setPermissionsDTO(permissionsDTO);
        // 编辑配置
        EditConfigDTO editConfigDTO = new EditConfigDTO();
        editConfigDTO.setCallbackUrl(String.format("%s/app/only-office/save-release/code/%s/version/%d/uid/%s/file-id/%s",
                onlyOfficeProperties.getCallbackUrl(),
                formCode,
                formVersion,
                uid,
                fileId));
        // 菜单语言
        editConfigDTO.setLang("zh");
        // 文档语言
        editConfigDTO.setRegion("zh-CN");

        EditConfigDTO.User user = new EditConfigDTO.User();
        UserInfoBO currentUser = securityComponent.getCurrentUser();
        user.setId(currentUser.getUserId());
        user.setName(currentUser.getUserName());
        editConfigDTO.setUser(user);

        JSONObject config = new JSONObject();
        config.put("document", documentDTO);
        config.put("documentType", getDocumentType(filePO.getFileType()));
        config.put("editorConfig", editConfigDTO);
        return config;
    }

    /**
     * 获取文件类型
     *
     * @param fileType
     * @return
     */
    private String getDocumentType(String fileType) {
        // 打开excel时会有问题，目前只支持word
        for (String wordFileType : WORD_FILE_TYPE_ARRAY) {
            if (StringUtils.equals(fileType, wordFileType)) {
                return "word";
            }
        }
        for (String cellFileType : CELL_FILE_TYPE_ARRAY) {
            if (StringUtils.equals(fileType, cellFileType)) {
                return "cell";
            }
        }
        for (String slideFileType : SLIDE_FILE_TYPE_ARRAY) {
            if (StringUtils.equals(fileType, slideFileType)) {
                return "slide";
            }
        }
        throw new ParamsException("文件类型不支持");
    }

}
