package com.njcn.gather.aireport.testdevice.component;

import cn.hutool.core.util.StrUtil;
import com.njcn.common.pojo.enums.response.CommonResponseEnum;
import com.njcn.common.pojo.exception.BusinessException;
import com.njcn.gather.aireport.common.constant.AiReportFileConst;
import com.njcn.gather.aireport.common.constant.AiReportFileExtensionConst;
import com.njcn.gather.aireport.common.storage.AiReportMinioStorageService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.Locale;

@Component
@RequiredArgsConstructor
public class TestDeviceReportStorageService {

    private static final long MAX_REPORT_SIZE = 10L * 1024L * 1024L;
    private static final int MAX_ORIGINAL_NAME_LENGTH = 80;

    private final AiReportMinioStorageService minioStorageService;

    public String save(MultipartFile reportFile) {
        if (reportFile == null || reportFile.isEmpty()) {
            throw new BusinessException(CommonResponseEnum.FAIL, "校准报告不能为空");
        }
        validatePdf(reportFile.getOriginalFilename(), reportFile.getSize());
        return minioStorageService.saveMultipartFile(
                AiReportFileConst.BIZ_DIR_TEST_DEVICE, null, reportFile, false).getObjectName();
    }

    public String savePdf(String originalFilename, InputStream inputStream, long size) {
        validatePdf(originalFilename, size);
        return minioStorageService.saveInputStream(AiReportFileConst.BIZ_DIR_TEST_DEVICE, null,
                trimFileName(originalFilename), inputStream, size, "application/pdf", false).getObjectName();
    }

    public AiReportMinioStorageService.StoredObject getObject(String storedPath) {
        return minioStorageService.getObject(storedPath);
    }

    public String resolveDownloadFileName(String storedPath) {
        if (StrUtil.isBlank(storedPath)) {
            return "校准报告.pdf";
        }
        int slashIndex = storedPath.lastIndexOf('/');
        String fileName = slashIndex >= 0 ? storedPath.substring(slashIndex + 1) : storedPath;
        int separatorIndex = fileName.indexOf('-');
        return separatorIndex >= 0 && separatorIndex + 1 < fileName.length() ? fileName.substring(separatorIndex + 1) : fileName;
    }

    public void deleteQuietly(String storedPath) {
        minioStorageService.deleteQuietly(storedPath);
    }

    private void validatePdf(String originalFilename, long size) {
        String fileName = trimFileName(originalFilename);
        if (StrUtil.isBlank(fileName)) {
            throw new BusinessException(CommonResponseEnum.FAIL, "校准报告文件名不能为空");
        }
        String extension = resolveExtension(fileName);
        if (!AiReportFileExtensionConst.PDF_EXTENSIONS.contains(extension)) {
            throw new BusinessException(CommonResponseEnum.FAIL, "校准报告仅支持PDF文件");
        }
        if (size > MAX_REPORT_SIZE) {
            throw new BusinessException(CommonResponseEnum.FAIL, "校准报告不能超过10MB");
        }
    }

    private String trimFileName(String originalFilename) {
        String fileName = originalFilename == null ? null : originalFilename.trim();
        if (StrUtil.isBlank(fileName)) {
            return fileName;
        }
        int slashIndex = Math.max(fileName.lastIndexOf('/'), fileName.lastIndexOf('\\'));
        String normalizedName = slashIndex >= 0 ? fileName.substring(slashIndex + 1) : fileName;
        String sanitized = normalizedName.replaceAll("[\\\\/:*?\"<>|]", "_");
        if (sanitized.length() > MAX_ORIGINAL_NAME_LENGTH) {
            String suffix = sanitized.toLowerCase(Locale.ENGLISH).endsWith(".pdf") ? ".pdf" : "";
            int keepLength = MAX_ORIGINAL_NAME_LENGTH - suffix.length();
            sanitized = sanitized.substring(0, keepLength) + suffix;
        }
        return sanitized;
    }

    private String resolveExtension(String fileName) {
        int dotIndex = fileName.lastIndexOf('.');
        if (dotIndex < 0 || dotIndex == fileName.length() - 1) {
            return "";
        }
        return fileName.substring(dotIndex + 1).toLowerCase(Locale.ENGLISH);
    }
}
