package org.brapi.test.BrAPITestServer.controller.upload;

import java.util.Map;

import org.brapi.test.BrAPITestServer.model.dto.upload.ImageUploadResponse;
import org.brapi.test.BrAPITestServer.service.upload.MinioImageStorageService;
import org.brapi.test.BrAPITestServer.service.upload.MinioImageStorageService.StoredImage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import io.minio.errors.ErrorResponseException;

@RestController
@RequestMapping("/upload")
public class ImageUploadController {
	private static final Logger LOGGER = LoggerFactory.getLogger(ImageUploadController.class);

	private final MinioImageStorageService imageStorageService;

	public ImageUploadController(MinioImageStorageService imageStorageService) {
		this.imageStorageService = imageStorageService;
	}

	@CrossOrigin
	@PostMapping(value = "/image", consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
			produces = MediaType.APPLICATION_JSON_VALUE)
	public ResponseEntity<?> uploadImage(@RequestParam("file") MultipartFile file) {
		try {
			ImageUploadResponse response = imageStorageService.uploadImage(file);
			return ResponseEntity.ok(response);
		} catch (IllegalArgumentException e) {
			return ResponseEntity.badRequest().body(Map.of("detail", e.getMessage()));
		} catch (Exception e) {
			LOGGER.error("Image upload failed", e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
					.body(Map.of("detail", "image upload failed"));
		}
	}

	@CrossOrigin
	@GetMapping(value = "/image/{objectName:.+}")
	public ResponseEntity<?> getImage(@PathVariable("objectName") String objectName) {
		try {
			StoredImage image = imageStorageService.loadImage(objectName);
			InputStreamResource resource = new InputStreamResource(image.getInputStream());
			return ResponseEntity.ok()
					.header(HttpHeaders.CONTENT_DISPOSITION, "inline; filename=\"" + objectName + "\"")
					.contentLength(image.getSize())
					.contentType(resolveContentType(image.getContentType()))
					.body(resource);
		} catch (IllegalArgumentException e) {
			return ResponseEntity.badRequest().body(Map.of("detail", e.getMessage()));
		} catch (ErrorResponseException e) {
			if ("NoSuchKey".equals(e.errorResponse().code()) || "NoSuchBucket".equals(e.errorResponse().code())) {
				return ResponseEntity.status(HttpStatus.NOT_FOUND).body(Map.of("detail", "image not found"));
			}
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
					.body(Map.of("detail", "image download failed"));
		} catch (Exception e) {
			LOGGER.error("Image download failed for {}", objectName, e);
			return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
					.body(Map.of("detail", "image download failed"));
		}
	}

	private MediaType resolveContentType(String contentType) {
		if (contentType == null || contentType.isBlank()) {
			return MediaType.APPLICATION_OCTET_STREAM;
		}
		return MediaType.parseMediaType(contentType);
	}
}
