package com.lesingle.edu.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HexFormat;

/**
 * 文件存储服务
 */
@Slf4j
@Service
public class FileStorageService {

    @Value("${file.upload-dir:uploads}")
    private String uploadDir;

    @Value("${file.base-url:/files}")
    private String baseUrl;

    /**
     * 保存文件
     */
    public String saveFile(MultipartFile file, String type) throws IOException {
        // 生成文件路径：uploads/type/YYYY-MM-DD/filename
        String dateStr = LocalDate.now().format(DateTimeFormatter.ISO_LOCAL_DATE);
        String relativePath = String.format("%s/%s", type, dateStr);
        Path targetDir = Paths.get(uploadDir, relativePath);

        // 确保目录存在
        if (!Files.exists(targetDir)) {
            Files.createDirectories(targetDir);
        }

        // 生成安全的文件名
        String originalFilename = file.getOriginalFilename();
        String extension = "";
        if (originalFilename != null && originalFilename.contains(".")) {
            extension = originalFilename.substring(originalFilename.lastIndexOf("."));
        }

        String filename = generateUniqueFilename() + extension;
        Path targetPath = targetDir.resolve(filename);

        // 保存文件
        Files.copy(file.getInputStream(), targetPath, StandardCopyOption.REPLACE_EXISTING);

        log.info("文件保存成功：{}", targetPath);

        // 返回访问URL
        return String.format("%s/%s/%s/%s", baseUrl, type, dateStr, filename);
    }

    /**
     * 删除文件
     */
    public boolean deleteFile(String fileUrl) {
        try {
            // 从URL中提取相对路径
            if (!fileUrl.startsWith(baseUrl)) {
                return false;
            }

            String relativePath = fileUrl.substring(baseUrl.length() + 1);
            Path filePath = Paths.get(uploadDir, relativePath);

            if (Files.exists(filePath)) {
                Files.delete(filePath);
                log.info("文件删除成功：{}", filePath);
                return true;
            }

            return false;
        } catch (IOException e) {
            log.error("删除文件失败：{}", fileUrl, e);
            return false;
        }
    }

    /**
     * 验证文件类型
     */
    public boolean validateFileType(MultipartFile file, String type) {
        String contentType = file.getContentType();
        String filename = file.getOriginalFilename();

        // 根据类型验证
        return switch (type) {
            case "cover" -> isImage(contentType, filename);
            case "ebook" -> isPdfOrPpt(contentType, filename);
            case "audio" -> isAudio(contentType, filename);
            case "video" -> isVideo(contentType, filename);
            case "ppt" -> isPpt(contentType, filename);
            case "document" -> isDocument(contentType, filename);
            default -> true;
        };
    }

    /**
     * 验证文件大小
     */
    public boolean validateFileSize(MultipartFile file, String type) {
        long maxSize = switch (type) {
            case "cover", "poster", "image" -> 10 * 1024 * 1024L; // 10MB
            case "ebook", "audio", "video", "ppt", "document" -> 300 * 1024 * 1024L; // 300MB
            default -> 300 * 1024 * 1024L; // 默认300MB
        };

        return file.getSize() <= maxSize;
    }

    private boolean isImage(String contentType, String filename) {
        if (contentType == null) return false;
        return contentType.startsWith("image/") ||
               (filename != null && filename.matches(".*\\.(jpg|jpeg|png|gif|webp)$"));
    }

    private boolean isPdfOrPpt(String contentType, String filename) {
        if (contentType == null) return false;
        return contentType.equals("application/pdf") ||
               contentType.contains("presentation") ||
               (filename != null && filename.matches(".*\\.(pdf|ppt|pptx)$"));
    }

    private boolean isAudio(String contentType, String filename) {
        if (contentType == null) return false;
        return contentType.startsWith("audio/") ||
               (filename != null && filename.matches(".*\\.(mp3|wav|m4a|ogg)$"));
    }

    private boolean isVideo(String contentType, String filename) {
        if (contentType == null) return false;
        return contentType.startsWith("video/") ||
               (filename != null && filename.matches(".*\\.(mp4|webm|mov|avi)$"));
    }

    private boolean isPpt(String contentType, String filename) {
        if (contentType == null) return false;
        return contentType.contains("presentation") ||
               contentType.equals("application/pdf") ||
               (filename != null && filename.matches(".*\\.(ppt|pptx|pdf)$"));
    }

    private boolean isDocument(String contentType, String filename) {
        if (contentType == null) return false;
        return contentType.contains("word") ||
               contentType.contains("document") ||
               (filename != null && filename.matches(".*\\.(doc|docx|pdf)$"));
    }

    /**
     * 生成唯一文件名
     */
    private String generateUniqueFilename() {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            String input = System.currentTimeMillis() + "-" + Math.random();
            byte[] hash = md.digest(input.getBytes());
            return HexFormat.of().formatHex(hash);
        } catch (NoSuchAlgorithmException e) {
            return String.valueOf(System.currentTimeMillis());
        }
    }
}
