package com.lingyue.parse.util;

import com.lingyue.parse.enums.FileType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;

/**
 * 文件类型检测工具类
 * 
 * @author lingyue
 * @since 2026-01-14
 */
@Slf4j
public class FileTypeDetector {
    
    /**
     * 检测文件类型
     * 
     * @param file 上传的文件
     * @return 文件类型
     */
    public static FileType detectFileType(MultipartFile file) {
        // 1. 先通过扩展名判断
        String originalFilename = file.getOriginalFilename();
        if (originalFilename != null && originalFilename.contains(".")) {
            String extension = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
            FileType typeByExt = FileType.fromExtension(extension);
            if (typeByExt != FileType.UNKNOWN) {
                log.debug("通过扩展名检测到文件类型: {}", typeByExt);
                return typeByExt;
            }
        }
        
        // 2. 通过MIME类型判断
        String contentType = file.getContentType();
        if (contentType != null) {
            FileType typeByMime = FileType.fromMimeType(contentType);
            if (typeByMime != FileType.UNKNOWN) {
                log.debug("通过MIME类型检测到文件类型: {}", typeByMime);
                return typeByMime;
            }
        }
        
        // 3. 通过文件头（Magic Number）判断
        try {
            FileType typeByMagic = detectByMagicNumber(file.getInputStream());
            if (typeByMagic != FileType.UNKNOWN) {
                log.debug("通过文件头检测到文件类型: {}", typeByMagic);
                return typeByMagic;
            }
        } catch (IOException e) {
            log.error("读取文件头失败", e);
        }
        
        log.warn("无法检测文件类型，返回UNKNOWN");
        return FileType.UNKNOWN;
    }
    
    /**
     * 通过文件头（Magic Number）检测文件类型
     */
    private static FileType detectByMagicNumber(InputStream inputStream) throws IOException {
        byte[] header = new byte[8];
        int bytesRead = inputStream.read(header);
        
        if (bytesRead < 4) {
            return FileType.UNKNOWN;
        }
        
        // PDF: %PDF (25 50 44 46)
        if (header[0] == 0x25 && header[1] == 0x50 && header[2] == 0x44 && header[3] == 0x46) {
            return FileType.PDF;
        }
        
        // PNG: 89 50 4E 47
        if (header[0] == (byte) 0x89 && header[1] == 0x50 && header[2] == 0x4E && header[3] == 0x47) {
            return FileType.IMAGE_PNG;
        }
        
        // JPEG: FF D8 FF
        if (header[0] == (byte) 0xFF && header[1] == (byte) 0xD8 && header[2] == (byte) 0xFF) {
            return FileType.IMAGE_JPG;
        }
        
        // GIF: 47 49 46 38
        if (header[0] == 0x47 && header[1] == 0x49 && header[2] == 0x46 && header[3] == 0x38) {
            return FileType.IMAGE_GIF;
        }
        
        // ZIP-based formats (DOCX, XLSX): 50 4B 03 04
        if (header[0] == 0x50 && header[1] == 0x4B && header[2] == 0x03 && header[3] == 0x04) {
            // 需要进一步判断是DOCX还是XLSX，这里暂时返回WORD
            return FileType.WORD;
        }
        
        // DOC: D0 CF 11 E0
        if (header[0] == (byte) 0xD0 && header[1] == (byte) 0xCF && 
            header[2] == 0x11 && header[3] == (byte) 0xE0) {
            return FileType.WORD_OLD;
        }
        
        return FileType.UNKNOWN;
    }
    
    /**
     * 验证文件扩展名是否允许
     */
    public static boolean isAllowedExtension(String filename, String allowedExtensions) {
        if (filename == null || !filename.contains(".")) {
            return false;
        }
        
        String extension = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
        String[] allowed = allowedExtensions.split(",");
        
        for (String ext : allowed) {
            if (ext.trim().equalsIgnoreCase(extension)) {
                return true;
            }
        }
        
        return false;
    }
}
