package kr.iotdoor.boot.web;

import kr.iotdoor.boot.model.file.StoredFile;
import kr.iotdoor.boot.service.FileStorageService;
import org.springframework.core.io.UrlResource;
import org.springframework.http.ContentDisposition;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.server.ResponseStatusException;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.LinkedHashMap;
import java.util.Map;

import static org.springframework.http.HttpStatus.NOT_FOUND;

@Controller
public class FileController {

    private final FileStorageService fileStorageService;

    public FileController(FileStorageService fileStorageService) {
        this.fileStorageService = fileStorageService;
    }

    @ResponseBody
    @PostMapping("/mfuc/file/upload.do")
    public ResponseEntity<Map<String, Object>> uploadFile(
        @RequestParam("file") MultipartFile file,
        @RequestParam(name = "directory", defaultValue = "common") String directory,
        @RequestParam(name = "description", required = false) String description
    ) {
        StoredFile storedFile = fileStorageService.storeSingleFile(file, directory, description);

        Map<String, Object> body = new LinkedHashMap<>();
        body.put("success", true);
        body.put("atchFileIdntfNo", storedFile.getAtchFileIdntfNo());
        body.put("fileSn", storedFile.getFileSn());
        body.put("orgnlFileNm", storedFile.getOrgnlFileNm());
        body.put("url", storedFile.getUrl());
        return ResponseEntity.ok(body);
    }

    @GetMapping("/comn/file/view/{atchFileIdntfNo}/{fileSn}")
    public ResponseEntity<UrlResource> viewFile(
        @PathVariable String atchFileIdntfNo,
        @PathVariable int fileSn
    ) throws IOException {
        StoredFile storedFile = fileStorageService.getStoredFile(atchFileIdntfNo, fileSn);
        if (storedFile == null) {
            throw new ResponseStatusException(NOT_FOUND);
        }

        Path filePath = fileStorageService.resolvePath(storedFile);
        if (!Files.exists(filePath)) {
            throw new ResponseStatusException(NOT_FOUND);
        }

        UrlResource resource = new UrlResource(filePath.toUri());
        String contentType = Files.probeContentType(filePath);
        MediaType mediaType = StringUtils.hasText(contentType)
            ? MediaType.parseMediaType(contentType)
            : MediaType.APPLICATION_OCTET_STREAM;

        return ResponseEntity.ok()
            .contentType(mediaType)
            .header(
                HttpHeaders.CONTENT_DISPOSITION,
                ContentDisposition.inline()
                    .filename(storedFile.getOrgnlFileNm(), StandardCharsets.UTF_8)
                    .build()
                    .toString()
            )
            .body(resource);
    }
}
