package com.example.PhotoGallery.Controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import com.example.PhotoGallery.Components.ImageIngestionCoordinator;
import com.example.PhotoGallery.Services.PhotoService;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
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.util.UUID;

@Controller
public class UploadPhotoController {

    @Autowired
    ImageIngestionCoordinator ingestionCoordinator;
    @Autowired
    PhotoService photoService;

    private static final int MAX_IMAGES_PER_UPLOAD = 20;

    @Value("${photogallery.paths.originals}")
    private String originalsPath;

    @GetMapping("/uploadPhoto")
    public String uploadPhotoPage() {
        return "uploadPhoto";
    }

    @PostMapping("/uploadPhoto")
    public String handleMultipleFileUpload(
            @RequestParam("files") MultipartFile[] files,
            Model model) {

        if (files == null || files.length == 0) {
            model.addAttribute("message", "No files selected.");
            return "uploadPhoto :: responseMessage";
        }

        if (files.length > MAX_IMAGES_PER_UPLOAD) {
            model.addAttribute(
                    "message",
                    "Maximum " + MAX_IMAGES_PER_UPLOAD + " images allowed per upload.");
            return "uploadPhoto :: responseMessage";
        }

        int successCount = 0;
        StringBuilder errors = new StringBuilder();

        for (MultipartFile file : files) {
            if (file.isEmpty()) {
                continue;
            }

            // MIME validation
            String contentType = file.getContentType();
            if (contentType == null || !contentType.startsWith("image/")) {
                errors.append("Skipped non-image file: ")
                        .append(file.getOriginalFilename());
                continue;
            }

            // Metadata validation (actual image decode)
            try (InputStream is = file.getInputStream()) {
                BufferedImage image = ImageIO.read(is);
                if (image == null) {
                    errors.append("Invalid image file: ")
                            .append(file.getOriginalFilename());
                    continue;
                }
            } catch (IOException e) {
                errors.append("Failed to read image: ")
                        .append(file.getOriginalFilename());
                continue;
            }

            try {
                // Prevent filename collisions
                String cleanName = StringUtils.cleanPath(file.getOriginalFilename());
                String uniqueName = UUID.randomUUID() + "_" + cleanName;

                Path targetPath = Paths.get(originalsPath).resolve(uniqueName);
                Files.createDirectories(targetPath.getParent());

                file.transferTo(targetPath.toFile());
                successCount++;

            } catch (IOException e) {
                errors.append("Upload failed for ")
                        .append(file.getOriginalFilename());
            }
        }

        //Update photo library by creating thumbnails and inserting into DB
        scanLibrary();

        model.addAttribute(
                "message",
                successCount + " image(s) uploaded successfully." + errors);

        return "uploadPhoto :: responseMessage";
    }

    private void scanLibrary() {
        ingestionCoordinator.startIfNotRunning(
                photoService::writeImagesFromDirToDB);
    }

}
