package com.hotwj.platform.reportStatistics.integration;

import cn.hutool.core.io.resource.BytesResource;
import cn.hutool.core.io.resource.FileResource;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.exception.ServiceException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.File;
import java.nio.charset.StandardCharsets;

@Slf4j
@Component
public class GotenbergClient {
    @Value("${gotenberg.base-url:https://127.0.0.1:3000}")
    private String gotenbergBaseUrl;
    @Value("${gotenberg.connect-timeout-ms:10000}")
    private int connectTimeoutMs;
    @Value("${gotenberg.read-timeout-ms:300000}")
    private int readTimeoutMs;
    @Value("${gotenberg.retry-count:2}")
    private int retryCount;
    @Value("${gotenberg.retry-interval-ms:500}")
    private long retryIntervalMs;

    private String buildConvertUrl() {
        String base = gotenbergBaseUrl;
        if (base.endsWith("/")) {
            base = base.substring(0, base.length() - 1);
        }
        return base + "/forms/chromium/convert/html";
    }

    public byte[] convertHtmlToPdf(File htmlFile, String footerHtml) {
        return convertHtmlToPdf(htmlFile, footerHtml, false);
    }

    public byte[] convertHtmlToPdf(File htmlFile, String footerHtml, boolean landscape) {
        return executeWithRetry(() -> {
            HttpRequest req = HttpRequest.post(buildConvertUrl())
                    .setConnectionTimeout(connectTimeoutMs)
                    .setReadTimeout(readTimeoutMs)
                    .form("index.html", new FileResource(htmlFile) {
                        @Override
                        public String getName() {
                            return "index.html";
                        }
                    })
                .form("printBackground", "true")
                .form("landscape", String.valueOf(landscape));

            if (footerHtml != null) {
                req.form("footer.html", new BytesResource(footerHtml.getBytes(StandardCharsets.UTF_8), "footer.html"));
            }
            return executeAndValidate(req);
        });
    }

    public byte[] convertHtmlToPdf(String htmlContent) {
        return convertHtmlToPdf(htmlContent, null, false);
    }

    public byte[] convertHtmlToPdf(String htmlContent, String footerHtml, boolean landscape) {
        return executeWithRetry(() -> {
            HttpRequest req = HttpRequest.post(buildConvertUrl())
                    .setConnectionTimeout(connectTimeoutMs)
                    .setReadTimeout(readTimeoutMs)
                .form("index.html", new BytesResource(htmlContent.getBytes(StandardCharsets.UTF_8), "index.html"))
                .form("printBackground", "true")
                .form("landscape", String.valueOf(landscape));

            if (footerHtml != null) {
                req.form("footer.html", new BytesResource(footerHtml.getBytes(StandardCharsets.UTF_8), "footer.html"));
            }
            return executeAndValidate(req);
        });
    }

    private byte[] executeAndValidate(HttpRequest req) {
        try (HttpResponse response = req.execute()) {
            if (!response.isOk()) {
                String body = response.body();
                throw new ServiceException("Gotenberg 转换失败，HTTP状态码: " + response.getStatus()
                        + ", 响应: " + truncate(body, 300));
            }
            byte[] bytes = response.bodyBytes();
            if (bytes == null || bytes.length == 0) {
                throw new ServiceException("Gotenberg 转换失败：返回空PDF内容");
            }
            return bytes;
        }
    }

    private byte[] executeWithRetry(PdfRequestExecutor executor) {
        int maxAttempts = Math.max(1, retryCount + 1);
        Exception lastException = null;
        for (int attempt = 1; attempt <= maxAttempts; attempt++) {
            try {
                return executor.execute();
            } catch (Exception e) {
                lastException = e;
                if (attempt >= maxAttempts) {
                    break;
                }
                log.warn("Gotenberg 转换失败，准备重试。attempt={}/{}", attempt, maxAttempts, e);
                if (retryIntervalMs > 0) {
                    try {
                        Thread.sleep(retryIntervalMs);
                    } catch (InterruptedException interruptedException) {
                        Thread.currentThread().interrupt();
                        throw new ServiceException("Gotenberg 转换被中断");
                    }
                }
            }
        }

        if (lastException instanceof ServiceException serviceException) {
            throw serviceException;
        }
        throw new ServiceException("Gotenberg 转换失败: " + (lastException == null ? "未知异常" : lastException.getMessage()));
    }

    private String truncate(String text, int maxLength) {
        if (text == null || text.length() <= maxLength) {
            return text;
        }
        return text.substring(0, maxLength) + "...";
    }

    @FunctionalInterface
    private interface PdfRequestExecutor {
        byte[] execute();
    }
}
