package shop.alien.store.util;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import shop.alien.util.ali.AliOSSUtil;
import shop.alien.util.common.RandomCreateUtil;
import shop.alien.util.file.FileUtil;
import shop.alien.util.pdf.ImageToPdfUtil;

import org.springframework.util.StringUtils;

import java.io.ByteArrayInputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Base64;
import java.util.List;
import java.util.Map;

/**
 * 图片转PDF并上传工具类
 * 接收前端上传的图片，转换为PDF后上传到OSS，返回PDF的线上URL
 *
 * @author system
 * @since 2026-01-05
 */
@Slf4j
@Component
@RefreshScope
@RequiredArgsConstructor
public class ImageToPdfUploadUtil {

    private final AliOSSUtil aliOSSUtil;

    /**
     * 支持的图片格式
     */
    private static final List<String> SUPPORTED_IMAGE_TYPES = Arrays.asList("jpg", "jpeg", "png", "bmp", "webp", "gif");

    /**
     * 将单张图片转换为PDF并上传到OSS（内存方式，不保存临时文件）
     *
     * @param imageFile 图片文件
     * @return PDF的线上URL，失败返回null
     */
    public String imageToPdfAndUpload(MultipartFile imageFile) {
        if (imageFile == null || imageFile.isEmpty()) {
            log.error("ImageToPdfUploadUtil.imageToPdfAndUpload ERROR: 图片文件为空");
            return null;
        }

        try {
            // 验证文件类型
            Map<String, String> fileNameAndType = FileUtil.getFileNameAndType(imageFile);
            String fileType = fileNameAndType.get("type").toLowerCase();
            if (!SUPPORTED_IMAGE_TYPES.contains(fileType)) {
                log.error("ImageToPdfUploadUtil.imageToPdfAndUpload ERROR: 不支持的图片格式: {}", fileType);
                return null;
            }

            // 直接从输入流读取图片并转换为PDF字节数组（内存方式）
            byte[] pdfBytes = ImageToPdfUtil.imageToPdfBytes(imageFile.getInputStream());
            if (pdfBytes == null || pdfBytes.length == 0) {
                log.error("ImageToPdfUploadUtil.imageToPdfAndUpload ERROR: 图片转PDF失败");
                return null;
            }

            // 生成OSS文件路径
            String fileName = fileNameAndType.get("name").replaceAll(",", "");
            String ossFilePath = "pdf/" + fileName + RandomCreateUtil.getRandomNum(6) + ".pdf";

            // 将PDF字节数组转换为输入流并上传到OSS
            ByteArrayInputStream pdfInputStream = new ByteArrayInputStream(pdfBytes);
            String pdfUrl = aliOSSUtil.uploadFile(pdfInputStream, ossFilePath);

            return pdfUrl;
        } catch (Exception e) {
            log.error("ImageToPdfUploadUtil.imageToPdfAndUpload ERROR: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 将多张图片合并为一个PDF并上传到OSS（内存方式，不保存临时文件）
     *
     * @param imageFiles 图片文件列表
     * @return PDF的线上URL，失败返回null
     */
    public String imagesToPdfAndUpload(List<MultipartFile> imageFiles) {
        if (imageFiles == null || imageFiles.isEmpty()) {
            log.error("ImageToPdfUploadUtil.imagesToPdfAndUpload ERROR: 图片文件列表为空");
            return null;
        }

        try {
            // 收集所有有效的图片输入流
            List<java.io.InputStream> imageStreams = new ArrayList<>();
            for (MultipartFile imageFile : imageFiles) {
                if (imageFile == null || imageFile.isEmpty()) {
                    continue;
                }

                // 验证文件类型
                Map<String, String> fileNameAndType = FileUtil.getFileNameAndType(imageFile);
                String fileType = fileNameAndType.get("type").toLowerCase();
                if (!SUPPORTED_IMAGE_TYPES.contains(fileType)) {
                    log.warn("ImageToPdfUploadUtil.imagesToPdfAndUpload WARN: 跳过不支持的图片格式: {}", fileType);
                    continue;
                }

                // 直接使用输入流（内存方式）
                imageStreams.add(imageFile.getInputStream());
            }

            if (imageStreams.isEmpty()) {
                log.error("ImageToPdfUploadUtil.imagesToPdfAndUpload ERROR: 没有有效的图片文件");
                return null;
            }

            // 将多张图片合并为一个PDF字节数组（内存方式）
            byte[] pdfBytes = ImageToPdfUtil.imagesToPdfBytes(imageStreams);
            if (pdfBytes == null || pdfBytes.length == 0) {
                log.error("ImageToPdfUploadUtil.imagesToPdfAndUpload ERROR: 图片转PDF失败");
                return null;
            }

            // 生成OSS文件路径
            String ossFilePath = "pdf/merged_" + RandomCreateUtil.getRandomNum(6) + ".pdf";

            // 将PDF字节数组转换为输入流并上传到OSS
            ByteArrayInputStream pdfInputStream = new ByteArrayInputStream(pdfBytes);
            String pdfUrl = aliOSSUtil.uploadFile(pdfInputStream, ossFilePath);

            return pdfUrl;
        } catch (Exception e) {
            log.error("ImageToPdfUploadUtil.imagesToPdfAndUpload ERROR: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 将单张图片转换为PDF（A4页面）并上传到OSS（内存方式，不保存临时文件）
     *
     * @param imageFile 图片文件
     * @return PDF的线上URL，失败返回null
     */
    public String imageToPdfA4AndUpload(MultipartFile imageFile) {
        if (imageFile == null || imageFile.isEmpty()) {
            log.error("ImageToPdfUploadUtil.imageToPdfA4AndUpload ERROR: 图片文件为空");
            return null;
        }

        try {
            // 验证文件类型
            Map<String, String> fileNameAndType = FileUtil.getFileNameAndType(imageFile);
            String fileType = fileNameAndType.get("type").toLowerCase();
            if (!SUPPORTED_IMAGE_TYPES.contains(fileType)) {
                log.error("ImageToPdfUploadUtil.imageToPdfA4AndUpload ERROR: 不支持的图片格式: {}", fileType);
                return null;
            }

            // 直接从输入流读取图片并转换为PDF字节数组（A4页面，内存方式）
            byte[] pdfBytes = ImageToPdfUtil.imageToPdfA4Bytes(imageFile.getInputStream());
            if (pdfBytes == null || pdfBytes.length == 0) {
                log.error("ImageToPdfUploadUtil.imageToPdfA4AndUpload ERROR: 图片转PDF失败");
                return null;
            }

            // 生成OSS文件路径
            String fileName = fileNameAndType.get("name").replaceAll(",", "");
            String ossFilePath = "pdf/" + fileName + RandomCreateUtil.getRandomNum(6) + ".pdf";

            // 将PDF字节数组转换为输入流并上传到OSS
            ByteArrayInputStream pdfInputStream = new ByteArrayInputStream(pdfBytes);
            String pdfUrl = aliOSSUtil.uploadFile(pdfInputStream, ossFilePath);

            return pdfUrl;
        } catch (Exception e) {
            log.error("ImageToPdfUploadUtil.imageToPdfA4AndUpload ERROR: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 将Base64编码的图片转换为PDF并上传到OSS（内存方式，不保存临时文件）
     *
     * @param base64Image Base64编码的图片字符串（支持带或不带data:image前缀）
     * @return PDF的线上URL，失败返回null
     */
    public String base64ToPdfAndUpload(String base64Image) {
        if (!StringUtils.hasText(base64Image)) {
            log.error("ImageToPdfUploadUtil.base64ToPdfAndUpload ERROR: Base64图片字符串为空");
            return null;
        }

        try {
            // 处理Base64字符串：移除可能的前缀（如 data:image/png;base64,）
            String base64Data = base64Image.trim();
            if (base64Data.contains(",")) {
                base64Data = base64Data.substring(base64Data.indexOf(",") + 1);
            }

            // 解码Base64为字节数组
            byte[] imageBytes;
            try {
                imageBytes = Base64.getDecoder().decode(base64Data);
            } catch (IllegalArgumentException e) {
                log.error("ImageToPdfUploadUtil.base64ToPdfAndUpload ERROR: Base64解码失败: {}", e.getMessage());
                return null;
            }

            if (imageBytes == null || imageBytes.length == 0) {
                log.error("ImageToPdfUploadUtil.base64ToPdfAndUpload ERROR: Base64解码后图片数据为空");
                return null;
            }

            // 将字节数组转换为输入流
            ByteArrayInputStream imageInputStream = new ByteArrayInputStream(imageBytes);

            // 转换为PDF字节数组（内存方式）
            byte[] pdfBytes = ImageToPdfUtil.imageToPdfBytes(imageInputStream);
            if (pdfBytes == null || pdfBytes.length == 0) {
                log.error("ImageToPdfUploadUtil.base64ToPdfAndUpload ERROR: 图片转PDF失败");
                return null;
            }

            // 生成OSS文件路径
            String ossFilePath = "pdf/base64_" + RandomCreateUtil.getRandomNum(6) + ".pdf";

            // 将PDF字节数组转换为输入流并上传到OSS
            ByteArrayInputStream pdfInputStream = new ByteArrayInputStream(pdfBytes);
            String pdfUrl = aliOSSUtil.uploadFile(pdfInputStream, ossFilePath);

            return pdfUrl;
        } catch (Exception e) {
            log.error("ImageToPdfUploadUtil.base64ToPdfAndUpload ERROR: {}", e.getMessage(), e);
            return null;
        }
    }
}
