package com.cnooc.expert.external.file.sevice;

import com.cnooc.expert.external.common.AbstractRetrofitManager;
import com.cnooc.expert.external.common.model.response.ApiBaseResult;
import com.cnooc.expert.external.file.api.FileServiceApi;
import com.cnooc.expert.external.file.model.request.GeneratorDownloadInfoApiReq;
import com.cnooc.expert.external.file.model.request.GeneratorUploadInfoApiReq;
import com.cnooc.expert.external.file.model.response.DownLoadInfoApiResp;
import com.cnooc.expert.external.file.model.response.GeneratorUploadInfoApiResp;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.Retrofit;

import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Slf4j
@Service
public class FileServiceClient extends AbstractRetrofitManager {

    private final FileServiceApi fileServiceApi;

    public FileServiceClient(@Qualifier("retrofitFile") Retrofit retrofit) {
        this.fileServiceApi = retrofit.create(FileServiceApi.class);
    }

    public ApiBaseResult<GeneratorUploadInfoApiResp> generatorUploadInfo(GeneratorUploadInfoApiReq apiReq) {
        Call<ApiBaseResult<GeneratorUploadInfoApiResp>> call = fileServiceApi.generatorUploadInfoApi(apiReq);
        return this.getResponseBody(call, "generatorUploadInfo");
    }

    public boolean uploadFile(String url, Map<String, RequestBody> params, MultipartBody.Part file) {
        try {
            Call<ResponseBody> call = fileServiceApi.uploadFile(url, params, file);
            log.info("{}", call.request());

            Response response = call.execute();
            return response.isSuccessful();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }

    }

    public ApiBaseResult<List<DownLoadInfoApiResp>> generatorDownloadInfo(String pathId) {
        GeneratorDownloadInfoApiReq apiReq = GeneratorDownloadInfoApiReq.builder()
                .pathId(pathId)
                .build();
        Call<ApiBaseResult<List<DownLoadInfoApiResp>>> call = fileServiceApi.generatorDownloadInfoApi(apiReq);
        return this.getResponseBody(call, "generatorDownloadInfo");
    }

    public List<DownLoadInfoApiResp> putObject(MultipartFile mulFile, int fileType) throws IOException {
        // 生成上传信息
        GeneratorUploadInfoApiReq uploadInfoApiReq = GeneratorUploadInfoApiReq.builder()
                .fileType(fileType)
                .build();
        ApiBaseResult<GeneratorUploadInfoApiResp> uploadInfoApiResp = this.generatorUploadInfo(uploadInfoApiReq);

        GeneratorUploadInfoApiResp uploadInfoApiData = uploadInfoApiResp.getData();
        String pathId = uploadInfoApiData.getPathId();
        String url = uploadInfoApiData.getUrl();
        String pathPre = uploadInfoApiData.getPathPre();
        List<GeneratorUploadInfoApiResp.PostObjectFormDTO> formDataList = uploadInfoApiData.getFormDTOList();

        // 上传文件
        String originalFilename = mulFile.getOriginalFilename();
        Map<String, RequestBody> params = Maps.newHashMap();
        for (GeneratorUploadInfoApiResp.PostObjectFormDTO formData : formDataList) {
            params.put(formData.getKey(), RequestBody.create(formData.getValue(), MediaType.parse("text/plain")));
        }
        params.put("key", RequestBody.create(pathPre + originalFilename, MediaType.parse("text/plain")));

        MultipartBody.Part file = MultipartBody.Part.createFormData(
                "file",
                mulFile.getOriginalFilename(),
                RequestBody.create(
                        MediaType.parse(Objects.requireNonNull(mulFile.getContentType())),
                        mulFile.getBytes()
                )
        );

        boolean success = this.uploadFile(url, params, file);

        // 生成下载信息
        if (success) {
            ApiBaseResult<List<DownLoadInfoApiResp>> downloadInfoApiResp = this.generatorDownloadInfo(pathId);
            return downloadInfoApiResp.getData();
        }

        return Collections.emptyList();
    }
}
