package com.petshop.backend.service;

import org.springframework.core.io.PathResource;
import org.springframework.core.io.Resource;
import org.springframework.http.MediaType;
import org.springframework.http.MediaTypeFactory;
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.util.Locale;
import java.util.UUID;

@Service
public class CatalogImageStorageService {

    private static final String PET_PREFIX = "/uploads/pets/";
    private static final String PRODUCT_PREFIX = "/uploads/products/";

    public String storePetImage(MultipartFile file) throws IOException {
        return storeImage(file, Paths.get("uploads", "pets").toAbsolutePath().normalize(), PET_PREFIX);
    }

    public String storeProductImage(MultipartFile file) throws IOException {
        return storeImage(file, Paths.get("uploads", "products").toAbsolutePath().normalize(), PRODUCT_PREFIX);
    }

    public Resource loadPetImage(String storedPath) {
        return new PathResource(resolveStoredPath(storedPath, Paths.get("uploads", "pets").toAbsolutePath().normalize(), PET_PREFIX));
    }

    public Resource loadProductImage(String storedPath) {
        return new PathResource(resolveStoredPath(storedPath, Paths.get("uploads", "products").toAbsolutePath().normalize(), PRODUCT_PREFIX));
    }

    public MediaType resolveMediaType(Resource resource) {
        return MediaTypeFactory.getMediaType(resource).orElse(MediaType.APPLICATION_OCTET_STREAM);
    }

    public void deletePetImage(String storedPath) throws IOException {
        deleteImage(storedPath, Paths.get("uploads", "pets").toAbsolutePath().normalize(), PET_PREFIX);
    }

    public void deleteProductImage(String storedPath) throws IOException {
        deleteImage(storedPath, Paths.get("uploads", "products").toAbsolutePath().normalize(), PRODUCT_PREFIX);
    }

    private String storeImage(MultipartFile file, Path directory, String prefix) throws IOException {
        Files.createDirectories(directory);
        String extension = resolveExtension(file.getOriginalFilename());
        String filename = UUID.randomUUID() + extension;
        Path filePath = directory.resolve(filename).normalize();
        Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);
        return prefix + filename;
    }

    private void deleteImage(String storedPath, Path directory, String prefix) throws IOException {
        if (storedPath == null || storedPath.isBlank()) {
            return;
        }
        Files.deleteIfExists(resolveStoredPath(storedPath, directory, prefix));
    }

    private Path resolveStoredPath(String storedPath, Path directory, String prefix) {
        if (storedPath == null || storedPath.isBlank() || !storedPath.startsWith(prefix)) {
            throw new IllegalArgumentException("Image file was not found");
        }
        String filename = storedPath.substring(prefix.length());
        if (filename.isBlank() || filename.contains("/") || filename.contains("\\") || filename.contains("..")) {
            throw new IllegalArgumentException("Image file was not found");
        }
        Path resolved = directory.resolve(filename).normalize();
        if (!resolved.startsWith(directory)) {
            throw new IllegalArgumentException("Image file was not found");
        }
        return resolved;
    }

    private String resolveExtension(String originalFilename) {
        if (originalFilename == null) {
            return ".jpg";
        }
        int extensionIndex = originalFilename.lastIndexOf('.');
        if (extensionIndex < 0 || extensionIndex == originalFilename.length() - 1) {
            return ".jpg";
        }
        String extension = originalFilename.substring(extensionIndex).toLowerCase(Locale.ROOT);
        return switch (extension) {
            case ".jpg", ".jpeg", ".png", ".gif" -> extension;
            default -> ".jpg";
        };
    }
}
