package com.red.circle.console.adapter.app.party3rd;//package com.sugartime.app.server.api.app.external;

import com.red.circle.external.inner.endpoint.oss.OssServiceClient;
import com.red.circle.framework.core.asserts.ResponseAssert;
import java.util.Map;
import java.util.Objects;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

/**
 * 阿里云服务.
 */
@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping(value = "/ali-yun", produces = MediaType.APPLICATION_JSON_VALUE)
public class AliYunRestController {

  private final OssServiceClient ossServiceClient;
  @Value("${feign.external.url}")
  private String externalBaseUrl;

  /**
   * 阿里云sts.
   */
  @GetMapping("/oss/sts")
  public Object sts() {
    return ResponseAssert.requiredSuccess(ossServiceClient.sts());
  }

  @PostMapping(value = "/oss/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
  public Map<String, String> upload(
      @RequestParam("file") MultipartFile file,
      @RequestParam(value = "dir", required = false) String dir,
      @RequestParam(value = "filename", required = false) String filename) {
    try {
      HttpHeaders requestHeaders = new HttpHeaders();
      requestHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);

      HttpHeaders fileHeaders = new HttpHeaders();
      if (file.getContentType() != null) {
        fileHeaders.setContentType(MediaType.parseMediaType(file.getContentType()));
      }

      ByteArrayResource resource = new ByteArrayResource(file.getBytes()) {
        @Override
        public String getFilename() {
          return Objects.toString(file.getOriginalFilename(), "upload.bin");
        }
      };

      MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
      body.add("file", new HttpEntity<>(resource, fileHeaders));

      String uploadUrl = externalBaseUrl.replaceAll("/+$", "")
          + "/oss/upload/general?dir=" + encode(dir)
          + "&filename=" + encode(filename);
      ResponseEntity<Map> response = new RestTemplate().postForEntity(
          uploadUrl,
          new HttpEntity<>(body, requestHeaders),
          Map.class);
      Map<?, ?> responseBody = response.getBody();
      if (responseBody == null || !Boolean.TRUE.equals(responseBody.get("status"))) {
        String errorMsg = responseBody == null ? "upload failed"
            : Objects.toString(responseBody.get("errorMsg"), "upload failed");
        throw new IllegalStateException(errorMsg);
      }
      return Map.of("name", Objects.toString(responseBody.get("body"), ""));
    } catch (Exception e) {
      log.error("console upload proxy failed dir={} filename={}", dir, filename, e);
      throw new IllegalStateException("upload failed", e);
    }
  }

  private String encode(String value) {
    return java.net.URLEncoder.encode(Objects.toString(value, ""), java.nio.charset.StandardCharsets.UTF_8);
  }

}
