package com.crm.rely.backend.service.impl.base;

import com.crm.rely.backend.configuration.LocaleMessage;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.exception.ServiceException;
import com.crm.rely.backend.util.FileProcessUtil;
import com.google.common.base.Strings;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.InputStream;

public class BaseUpload {
    private final static String FILE_COMMON = "/file/common/";
    @Autowired
    private LocaleMessage localeMessage;
    @Value("${web.upload-path:./upload}")
    private String UPLOAD;

    private static boolean isSafeImage(InputStream inputStream) {
        try {

            // 检查文件头（魔数）
            byte[] headerBytes = new byte[8];
            inputStream.read(headerBytes, 0, 8);
            if (!isValidImageHeader(headerBytes)) {
                System.out.println("图片文件头不合法，可能存在风险");
                return false;
            }

            // 验证图片内容
            BufferedImage image = ImageIO.read(inputStream);
            if (image == null) {
                System.out.println("无法解析为有效图片");
                return false;
            }

            // 检查图片尺寸限制
            int width = image.getWidth();
            int height = image.getHeight();
            if (width > 5000 || height > 5000) {
                System.out.println("图片尺寸过大: " + width + "x" + height);
                return false;
            }

            return true;
        } catch (Exception e) {
            System.out.println("图片验证失败: " + e.getMessage());
            return false;
        }
    }

    // 验证文件头（魔数）是否是合法图片格式
    private static boolean isValidImageHeader(byte[] headerBytes) {
        if (headerBytes.length < 8) {
            return false;
        }

        // JPEG 文件头 (FF D8 FF)
        if (headerBytes[0] == (byte) 0xFF && headerBytes[1] == (byte) 0xD8 && headerBytes[2] == (byte) 0xFF) {
            return true;
        }

        // PNG 文件头 (89 50 4E 47 0D 0A 1A 0A)
        if (headerBytes[0] == (byte) 0x89 && headerBytes[1] == (byte) 0x50 && headerBytes[2] == (byte) 0x4E &&
                headerBytes[3] == (byte) 0x47 && headerBytes[4] == (byte) 0x0D && headerBytes[5] == (byte) 0x0A &&
                headerBytes[6] == (byte) 0x1A && headerBytes[7] == (byte) 0x0A) {
            return true;
        }

        // GIF 文件头 (47 49 46 38)
        if (headerBytes[0] == (byte) 0x47 && headerBytes[1] == (byte) 0x49 && headerBytes[2] == (byte) 0x46 &&
                headerBytes[3] == (byte) 0x38) {
            return true;
        }

        // BMP 文件头 (42 4D)
        if (headerBytes[0] == (byte) 0x42 && headerBytes[1] == (byte) 0x4D) {
            return true;
        }

        // WebP 文件头 (52 49 46 46 .... 57 45 42 50)
        if (headerBytes[0] == (byte) 0x52 && headerBytes[1] == (byte) 0x49 && headerBytes[2] == (byte) 0x46 &&
                headerBytes[3] == (byte) 0x46 && headerBytes[8] == (byte) 0x57 && headerBytes[9] == (byte) 0x45 &&
                headerBytes[10] == (byte) 0x42 && headerBytes[11] == (byte) 0x50) {
            return true;
        }

        return false;
    }

    protected void validated(MultipartFile file, int size, String regex) throws ServiceException {
        //验证文件大小
        if (file.getSize() > size * 1000 * 1024) {
            throw new ServiceException(localeMessage.getMessage(Constants.UPLOAD_FILE_SIZE_MAX) + size + "MB");
        }
        //文件格式
        String fileName = file.getOriginalFilename().toLowerCase();
        if (!fileName
                .substring(fileName.lastIndexOf(".") + 1, fileName.length())
                .matches(regex)) {
            throw ServiceException.exception(localeMessage.getMessage(Constants.UPLOAD_FILE_REGEX,
                    Constants.UPLOAD_FILE_REGEX) + " " + regex);

        }
    }

    protected String saveFile(String middlePath, String filename, InputStream inputStream) {
        return saveFile(middlePath, filename, false, inputStream);
    }

    protected String saveFile(String middlePath, String filename, boolean isSaveFileName, InputStream inputStream) {
        String savePath = getMiddlePath(middlePath);

        String path = FileProcessUtil.upload(filename, isSaveFileName, inputStream, savePath);
        return (Strings.isNullOrEmpty(middlePath) ? (FILE_COMMON) : middlePath) + path;
    }

    protected String saveFile(String middlePath, MultipartFile file) {
        return saveFile(middlePath, false, file);
    }

    protected String saveFile(String middlePath, boolean isSaveFileName, MultipartFile file) {

        String savePath = getMiddlePath(middlePath);

        String path = FileProcessUtil.upload(file, isSaveFileName, savePath);
        return (Strings.isNullOrEmpty(middlePath) ? (FILE_COMMON) : middlePath) + path;
    }

    private String getMiddlePath(String middlePath) {
        if (!Strings.isNullOrEmpty(middlePath) && !middlePath.startsWith("/")) {
            middlePath = "/" + middlePath;
        }
        String savePath = UPLOAD + (Strings.isNullOrEmpty(middlePath) ? (FILE_COMMON) : middlePath);
        return savePath;
    }
}
