package com.zt.plat.module.base.controller.admin.finereport;

import cn.hutool.core.util.StrUtil;
import com.zt.plat.framework.common.pojo.CommonResult;
import com.zt.plat.module.base.config.FineReportUploadProperties;
import com.zt.plat.module.base.controller.admin.finereport.vo.FineReportUploadRespVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotBlank;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.*;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import java.time.Duration;
import java.util.Map;

import static com.zt.plat.framework.common.pojo.CommonResult.error;
import static com.zt.plat.framework.common.pojo.CommonResult.success;

@Tag(name = "管理后台 - 帆软报表上传")
@RestController
@RequestMapping("/base/fine-report")
@Slf4j
public class FineReportUploadController {

    private final RestTemplate restTemplate;
    private final FineReportUploadProperties properties;

    public FineReportUploadController(RestTemplateBuilder builder,
                                      FineReportUploadProperties properties) {
        // 禁用分块传输，强制计算 Content-Length，避免 sidecar 返回 411
        this.restTemplate = builder
            .requestFactory(() -> {
                    SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
                factory.setOutputStreaming(false);
                return factory;
            })
            .setConnectTimeout(Duration.ofSeconds(5))
            .setReadTimeout(Duration.ofSeconds(30))
            .build();
        this.properties = properties;
    }

    @PostMapping("/upload")
    @Operation(summary = "上传帆软报表模板（透传到 sidecar）")
    @PreAuthorize("@ss.hasPermission('base:fine-report-template:upload')")
    public CommonResult<FineReportUploadRespVO> upload(@RequestParam("file") MultipartFile file,
                                                       @Parameter(description = "相对路径，可为空")
                                                       @RequestParam(value = "path", required = false) String path) {
        if (file == null || file.isEmpty()) {
            return error(400, "文件不能为空");
        }

        String uploadUrl = properties.getUrl();
        if (StrUtil.isBlank(uploadUrl)) {
            return error(500, "上传地址未配置");
        }

        try {
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);

            MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
            String filename = file.getOriginalFilename();
            ByteArrayResource resource = new ByteArrayResource(file.getBytes()) {
                @Override
                public String getFilename() {
                    return filename;
                }

                @Override
                public long contentLength() {
                    return file.getSize();
                }
            };
            body.add("file", resource);
            if (StrUtil.isNotBlank(path)) {
                body.add("path", path);
            }

            HttpEntity<MultiValueMap<String, Object>> requestEntity = new HttpEntity<>(body, headers);
            ResponseEntity<Map> response = restTemplate.postForEntity(uploadUrl, requestEntity, Map.class);

            FineReportUploadRespVO respVO = new FineReportUploadRespVO();
            respVO.setFilename(filename);
            respVO.setBytes(file.getSize());

            Map<?, ?> respBody = response.getBody();
            if (respBody != null) {
                Object targetPath = respBody.get("path");
                if (targetPath != null) {
                    respVO.setTargetPath(String.valueOf(targetPath));
                }
                Object status = respBody.get("status");
                if (status != null) {
                    respVO.setStatus(String.valueOf(status));
                }
            }

            return success(respVO);
        } catch (Exception ex) {
            log.error("Upload FineReport template failed, url={}, file={}", properties.getUrl(), file.getOriginalFilename(), ex);
            return error(500, "上传失败: " + ex.getMessage());
        }
    }
}
