package ru.soune.nocopy.service.file;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.soune.nocopy.entity.file.FileEntity;
import ru.soune.nocopy.service.file.cloud.CloudStorageService;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;

@Service
@Slf4j
@RequiredArgsConstructor
public class ImageResizeService {

    private final CloudStorageService cloudStorageService;

    private static final int THUMBNAIL_SIZE = 100;

    private static final int MEDIUM_SIZE = 600;

    @Value("${file.storage.base-path}")
    private String storagePath;

    @Transactional
    public void generateSizes(FileEntity file, byte[] data) throws IOException {
        try (ByteArrayInputStream bis = new ByteArrayInputStream(data)) {
            BufferedImage original = ImageIO.read(bis);

            if (original == null) {
                log.warn("Cannot read image: {}", file.getId());
                return;
            }

            String baseName = file.getId().replace(".", "_");

            if (original.getWidth() > THUMBNAIL_SIZE) {
                String thumbPath = resizeAndSave(original, baseName + "_thumb", THUMBNAIL_SIZE);
                file.setThumbnailPath(thumbPath);
                cloudStorageService.saveFilesToStorage(file.getMimeType(), file.getFileExtension(),
                        thumbPath);
            }

            if (original.getWidth() > MEDIUM_SIZE) {
                String mediumPath = resizeAndSave(original, baseName + "_medium", MEDIUM_SIZE);
                file.setMediumPath(mediumPath);
                cloudStorageService.saveFilesToStorage(file.getMimeType(), file.getFileExtension(),
                        mediumPath);
            }
        }
    }

    private String resizeAndSave(BufferedImage original, String fileName, int targetWidth) throws IOException {
        int targetHeight = (int) ((double) original.getHeight() / original.getWidth() * targetWidth);

        BufferedImage resized = new BufferedImage(targetWidth, targetHeight, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = resized.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.drawImage(original, 0, 0, targetWidth, targetHeight, null);
        g.dispose();

        Path dirPath = Paths.get(storagePath, "resized");
        Files.createDirectories(dirPath);

        Path filePath = dirPath.resolve(fileName + ".jpg");
        ImageIO.write(resized, "jpg", filePath.toFile());

        return filePath.toString();
    }
}
