package io.gmss.fiscad.service;

import io.gmss.fiscad.exceptions.FileStorageException;
import io.gmss.fiscad.exceptions.MyFileNotFoundException;
import io.gmss.fiscad.proprietes.FileStorageProperties;
import io.gmss.fiscad.utils.FileNameGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;

@Service
public class FileStorageService {

    private final Path fileStorageLocation;

    @Autowired
    public FileStorageService(FileStorageProperties fileStorageProperties) {
        this.fileStorageLocation = Paths.get(fileStorageProperties.getUploadDir())
                .toAbsolutePath().normalize();
        System.out.println(fileStorageLocation.getFileSystem());
        try {
            Files.createDirectories(this.fileStorageLocation);
        } catch (Exception ex) {
            throw new FileStorageException("Impossible de créer le répertoire où le fichier sera sauvegarder. Ecriture sur disque impossible. Vérifiez vos droits systèmes.", ex);
        }
    }

    public String storeFile(MultipartFile file) {
        // Normalize file name
        String fileName = StringUtils.cleanPath(file.getOriginalFilename());

        String[] extension = fileName.split("\\.");

        fileName = FileNameGenerator.generateString() + "." + extension[extension.length - 1];

        try {
            // Check if the file's name contains invalid characters
            if (fileName.contains("..")) {
                throw new FileStorageException("Désolé! Le nom du fichier contient des caractères non autorisé " + fileName);
            }

            // Copy file to the target location (Replacing existing file with the same name)
            Path targetLocation = this.fileStorageLocation.resolve(fileName);
            Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);

            return fileName;
        } catch (IOException ex) {
            throw new FileStorageException("Impossible d'enregistrer le fichier " + fileName + ". Réessayer plus tard!", ex);
        }
    }

    public boolean deleteFile(String fileName) throws IOException {

        try {
            Path filePath = this.fileStorageLocation.resolve(fileName).normalize();
            Resource resource = new UrlResource(filePath.toUri());
            if (resource.exists()) {
                File file = resource.getFile();
                if (file.delete()) {
                    System.out.println(file.getName() + " is deleted!");
                } else {
                    System.out.println("Delete operation is failed.");
                }
            } else {
                throw new MyFileNotFoundException("Impossible de trouver le ficher " + fileName);
            }
        } catch (MalformedURLException ex) {
            throw new MyFileNotFoundException("Impossible de trouver le ficher " + fileName, ex);
        }
        return true;
    }

    public Resource loadFileAsResource(String fileName) {
        try {
            Path filePath = this.fileStorageLocation.resolve(fileName).normalize();
            Resource resource = new UrlResource(filePath.toUri());
            if (resource.exists()) {
                return resource;
            } else {

                throw new MyFileNotFoundException("Impossible de trouver le ficher " + fileName);
            }
        } catch (MalformedURLException ex) {
            throw new MyFileNotFoundException("Impossible de trouver le ficher " + fileName, ex);
        }
    }

}
