package com.ffii.core.common.file.web;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
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.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.server.ResponseStatusException;

import com.ffii.core.common.SecurityUtils;
import com.ffii.core.common.file.FileRefType;
import com.ffii.core.common.file.service.FileService;

/** @author Fung */
@RestController
@RequestMapping("/protected/file/ul")
public class FileUploadController {

  private final int MAX_FILE_SIZE;
  private FileService service;

  public FileUploadController(
      @Value("${app.upload.max-size:20971520}") int maxFileSize,
      FileService service) {
    this.MAX_FILE_SIZE = maxFileSize;
    this.service = service;
  }

  @PostMapping("/{refType}/{refId}")
  @ResponseStatus(HttpStatus.CREATED)
  public Map<String, Object> upload(
      @PathVariable String refType,
      @PathVariable int refId,
      @RequestParam(required = false) String refCode,
      @RequestParam(required = false) String remarks,
      @RequestParam(required = false) Boolean needReturn,
      @RequestParam List<MultipartFile> multipartFiles) {
    checkAuth(refType);
    List<String> reason = new ArrayList<>();
    List<Map<String, Object>> fileList = new ArrayList<>();
    multipartFiles
        .forEach(multipartFile -> {
          if (multipartFile.getSize() == 0L) {
            reason.add(multipartFile.getOriginalFilename() + " size zero.");
          } else if (multipartFile.getSize() > MAX_FILE_SIZE) {
            reason.add(multipartFile.getOriginalFilename() + " size too large.");
          } else {
            try {
              Map<String, Object> ref = this.service.upload(refId, refType, refCode, multipartFile,
                  remarks);
              fileList.add(ref);
            } catch (Exception e) {
              e.printStackTrace();
              reason.add(multipartFile.getOriginalFilename() + " cannot upload.");
            }
          }
        });

    if (needReturn != null && needReturn) {
      return Map.of("errors", reason, "files", fileList);
    }
    return Map.of("errors", reason);

  }

  private void checkAuth(String refType) {
    if (FileRefType.MANUFACTURER.equals(refType) && SecurityUtils.isNotGranted("EDIT_MANUFACTURER")) {
      throw new ResponseStatusException(HttpStatus.FORBIDDEN);
    }
  }

}
