package com.rjlresaka.util;

import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Locale;
import java.util.UUID;

import javax.servlet.ServletContext;
import javax.servlet.http.Part;

import com.rjlresaka.model.StoredAttachment;

public final class FileStorageUtil {

    private FileStorageUtil() {
    }

    public static StoredAttachment store(Part part, ServletContext context) throws IOException {
        if (part == null || part.getSize() <= 0) {
            return null;
        }

        String originalName = cleanFilename(part.getSubmittedFileName());
        if (originalName.isEmpty()) {
            return null;
        }

        String storedName = UUID.randomUUID().toString().replace("-", "") + "_" + originalName;
        Path uploadDirectory = resolveUploadDirectory(context);
        Files.createDirectories(uploadDirectory);
        Path target = uploadDirectory.resolve(storedName);

        try (InputStream inputStream = part.getInputStream()) {
            Files.copy(inputStream, target, StandardCopyOption.REPLACE_EXISTING);
        }

        StoredAttachment attachment = new StoredAttachment();
        attachment.setOriginalName(originalName);
        attachment.setStoragePath(storedName);
        attachment.setContentType(part.getContentType());
        attachment.setSize(part.getSize());
        return attachment;
    }

    public static Path resolveStoredFile(String storedName, ServletContext context) throws IOException {
        if (storedName == null || storedName.contains("..") || storedName.contains("/") || storedName.contains("\\")) {
            throw new IOException("Nom de fichier invalide.");
        }
        return resolveUploadDirectory(context).resolve(storedName);
    }

    private static Path resolveUploadDirectory(ServletContext context) {
        String configuredDir = context.getInitParameter("upload.dir");
        if (configuredDir == null || configuredDir.trim().isEmpty()) {
            configuredDir = "uploads";
        }
        configuredDir = configuredDir.replace("\\", "/").replace("..", "").trim();

        String realRoot = context.getRealPath("/");
        if (realRoot != null && !realRoot.trim().isEmpty()) {
            return Paths.get(realRoot, "WEB-INF", configuredDir);
        }
        return Paths.get(System.getProperty("java.io.tmpdir"), "rjlresaka", configuredDir);
    }

    private static String cleanFilename(String filename) {
        if (filename == null) {
            return "";
        }
        String cleaned = filename.replace("\\", "/");
        int slashIndex = cleaned.lastIndexOf('/');
        if (slashIndex >= 0) {
            cleaned = cleaned.substring(slashIndex + 1);
        }
        cleaned = cleaned.trim().replaceAll("[^a-zA-Z0-9._-]", "_");
        if (cleaned.length() > 120) {
            String extension = "";
            int dotIndex = cleaned.lastIndexOf('.');
            if (dotIndex > 0) {
                extension = cleaned.substring(dotIndex).toLowerCase(Locale.ROOT);
                cleaned = cleaned.substring(0, dotIndex);
            }
            cleaned = cleaned.substring(0, 100) + extension;
        }
        return cleaned;
    }
}
