package it.powerbyte.springbootstarter.controller;

import it.powerbyte.springbootstarter.entity.FileStorage;
import it.powerbyte.springbootstarter.models.FileInfo;
import it.powerbyte.springbootstarter.repository.FileStorageRepository;
import it.powerbyte.springbootstarter.service.FilesStorageService;
import lombok.AllArgsConstructor;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;

import java.net.URLConnection;
import java.util.List;
import java.util.stream.Collectors;

@Controller
@AllArgsConstructor
@RestController
public class FilesController {

    private final FilesStorageService storageService;

    @PostMapping("/upload/{ownerId}")
    public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file, @PathVariable("ownerId") Long ownerId) {
        String message;
        try {
            storageService.save(ownerId, file);

            message = "Uploaded the file successfully: " + file.getOriginalFilename();
            return ResponseEntity.status(HttpStatus.OK).body(message);
        } catch (Exception e) {
            message = "Could not upload the file: " + file.getOriginalFilename() + "!";
            return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(message);
        }
    }

    @GetMapping("/files")
    public ResponseEntity<List<FileInfo>> getListFiles() {
        List<FileInfo> fileInfos = storageService.loadAll().map(path -> {
            String filename = path.getFileName().toString();
            String url = MvcUriComponentsBuilder
                    .fromMethodName(FilesController.class, "getFile", path.getFileName().toString()).build().toString();
            String mimeType = URLConnection.guessContentTypeFromName(path.getFileName().toString());

            return new FileInfo(filename, url, mimeType);
        }).collect(Collectors.toList());

        return ResponseEntity.status(HttpStatus.OK).body(fileInfos);
    }

    @GetMapping("/files/{ownerId}")
    public ResponseEntity<List<FileStorage>> getListFiles(@PathVariable("ownerId") Long ownerId) {

        List<FileStorage> files = storageService.findByOwnerId(ownerId);
        return ResponseEntity.status(HttpStatus.OK).body(files);
    }

    @GetMapping("/files/{filename:.+}")
    @ResponseBody
    public ResponseEntity<Resource> getFile(@PathVariable String filename) {
        Resource file = storageService.load(filename);
        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"").body(file);
    }
}
