package com.cslg.ppa.service.commom;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cslg.ppa.dto.FMSDeleteFileDTO;
import com.cslg.ppa.entity.commom.SystemFile;
import com.google.gson.Gson;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

import static cn.hutool.core.io.FileUtil.getMimeType;

/**
 * Okhttp调用FMS上传文件接口
 *
 * @Author xiexiang
 * @Date 2023/8/10
 */
@RequiredArgsConstructor
@Slf4j
@Service
public class FileManagerService {
    @Value("${FMSUrl}")
    private String FMSUrl;
    @Value("${FileSource}")
    private String FileSource;
    /**
     * 调用文件系统上传文件接口
     *
     * @param multipartFiles 文件
     */
    public String uploadFile(List<MultipartFile> multipartFiles) throws IOException {
        List<File> files = new ArrayList<>();
        for (MultipartFile multipartFile : multipartFiles) {
            File file = new File(multipartFile.getOriginalFilename());
            FileCopyUtils.copy(multipartFile.getBytes(), file);
            files.add(file);
        }
        MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM);
        for (File file : files) {
            //根据文件名获取文件的MIME类型
            String mimeType = getMimeType(file.getPath());
            multipartBodyBuilder.addFormDataPart("files", file.getName(), RequestBody.create(MediaType.parse(mimeType), file));
        }
        RequestBody requestBody = multipartBodyBuilder
                .addFormDataPart("sourceId", String.valueOf(FileSource))
                .build();
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .build();
        Request request = new Request.Builder()
                .url(FMSUrl + "/fileManager/uploadNormalFile")
                .post(requestBody)
                .build();
        Response response = null;
        response = okHttpClient.newCall(request).execute();
        // 最后记得删除临时文件
        for (File file : files) {
            FileUtils.deleteQuietly(file);
        }
        return Objects.requireNonNull(response.body()).string();
    }

    public List<String> uploadFileGetGuid(List<MultipartFile> multipartFiles) throws IOException {
        String res = this.uploadFile(multipartFiles);
        JSONObject jsonObject = JSONObject.parseObject(res);
        List<String> guids = JSONArray.parseArray(jsonObject.get("data").toString(), String.class);
        return guids;
    }

    /**
     * 调用文件系统取出文件接口（获得文件流）
     * @param fieldId 文件id
     */
    public byte[] downloadSystemFileFromFMS(String fieldId) throws IOException {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(60000, TimeUnit.SECONDS)
                .writeTimeout(60000, TimeUnit.SECONDS)
                .readTimeout(60000, TimeUnit.SECONDS)
                .build();
        Request request = new Request.Builder()
                .url(FMSUrl + "/fileManager/downloadFile?fileId=" + fieldId)
                .get()
                .build();
        return Objects.requireNonNull(okHttpClient.newCall(request).execute().body()).bytes();
    }

    /**
     * 调用文件系统获取文件信息接口
     *
     * @param fileIds 文件ids
     */
    public String getSystemFileFromFMS(List<String> fileIds) throws IOException {
        String param = new Gson().toJson(fileIds);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), param);
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .build();
        Request request = new Request.Builder()
                .url(FMSUrl + "/fileManager/getFileData")
                .post(requestBody)
                .build();
        return Objects.requireNonNull(okHttpClient.newCall(request).execute().body()).string();
    }

    /**
     * 调用文件系统删除文件接口
     *
     * @param ids 需要删除的文件ids
     */
    public String deleteFileFromFMS(List<String> ids) throws IOException {
        FMSDeleteFileDTO fmsDeleteFileDTO = new FMSDeleteFileDTO();
        fmsDeleteFileDTO.setGuids(ids);
        fmsDeleteFileDTO.setType(2);
        String param = new Gson().toJson(fmsDeleteFileDTO);
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), param);
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .build();
        Request request = new Request.Builder()
                .url(FMSUrl + "/fileManager/deleteSystemFile")
                .post(requestBody)
                .build();
        return Objects.requireNonNull(okHttpClient.newCall(request).execute().body()).string();
    }

    public String uploadFileWithGuid(File file, String guid) throws IOException {
        MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM);
        //根据文件名获取文件的MIME类型
        String mimeType = getMimeType(file.getPath());
        multipartBodyBuilder.addFormDataPart("file", file.getName(), RequestBody.create(MediaType.parse(mimeType), file));
        RequestBody requestBody = multipartBodyBuilder
                .addFormDataPart("sourceId", String.valueOf(FileSource))
                .addFormDataPart("fileGuid", guid)
                .build();
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .build();
        Request request = new Request.Builder()
                .url(FMSUrl + "/fileManager/replaceFile")
                .post(requestBody)
                .build();
        Response response = null;
        response = okHttpClient.newCall(request).execute();
        // 最后记得删除临时文件
//        FileUtils.deleteQuietly(file);

        return Objects.requireNonNull(response.body()).string();
    }

    /**
     * 调用文件系统上传文件接口
     */
    public String uploadFile2(List<File> files) throws IOException {

        MultipartBody.Builder multipartBodyBuilder = new MultipartBody.Builder()
                .setType(MultipartBody.FORM);
        for (File file : files) {
            //根据文件名获取文件的MIME类型
            String mimeType = getMimeType(file.getPath());
            multipartBodyBuilder.addFormDataPart("files", file.getName(), RequestBody.create(MediaType.parse(mimeType), file));
        }
        RequestBody requestBody = multipartBodyBuilder
                .addFormDataPart("sourceId", String.valueOf(FileSource))
                .build();
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .build();
        Request request = new Request.Builder()
                .url(FMSUrl + "/fileManager/uploadNormalFile")
                .post(requestBody)
                .build();
        Response response = null;
        response = okHttpClient.newCall(request).execute();
        // 最后记得删除临时文件
        for (File file : files) {
//            FileUtils.deleteQuietly(file);
        }
        return Objects.requireNonNull(response.body()).string();
    }

    public List<String> uploadFileGetGuid2(List<File> files) throws IOException {
        String res = this.uploadFile2(files);
        JSONObject jsonObject = JSONObject.parseObject(res);
        List<String> guids = JSONArray.parseArray(jsonObject.get("data").toString(), String.class);
        return guids;
    }

    /**
     * 调用文件系统获得专利图片的guid
     *
     * @param appNo 申请号
     */
    public String getPatentPictureGuids(String appNo) throws IOException {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(60, TimeUnit.SECONDS)
                .writeTimeout(60, TimeUnit.SECONDS)
                .readTimeout(60, TimeUnit.SECONDS)
                .build();
        Request request = new Request.Builder()
                .url(FMSUrl + "/fileManager/getPatentPictureGuids?appNo=" + appNo)
                .get()
                .build();
        return Objects.requireNonNull(okHttpClient.newCall(request).execute().body()).string();
    }

    public  File getTempFileByGuid(String guid)throws IOException{
        String res = this.getSystemFileFromFMS(Arrays.asList(guid));
        List<SystemFile> systemFiles = JSONArray.parseArray(res, SystemFile.class);
        SystemFile systemFile = systemFiles.get(0);
        String suffix = systemFile.getFileName().substring(systemFile.getFileName().lastIndexOf("."));
        //调用文件系统取出文件接口，获得文件流
        byte[] bytes = this.downloadSystemFileFromFMS(guid);
        //创建临时文件tempFile，并将文件读取到tempFile
        File tempFile = File.createTempFile(systemFile.getFileName() + "temp", suffix);
        try (
                InputStream inputStream = new ByteArrayInputStream(bytes);
                FileOutputStream outputStream = new FileOutputStream(tempFile);
        ) {
            IOUtils.copy(inputStream, outputStream); // 将输入流复制到临时文件
        }
        return  tempFile;
    }
}
