package com.jeequan.jeepay.components.oss.ctrl;

import cn.hutool.core.lang.UUID;
import com.jeequan.jeepay.components.oss.model.OssFileConfig;
import com.jeequan.jeepay.components.oss.service.IOssService;
import com.jeequan.jeepay.core.constants.ApiCodeEnum;
import com.jeequan.jeepay.core.ctrls.AbstractCtrl;
import com.jeequan.jeepay.core.exception.BizException;
import com.jeequan.jeepay.core.model.ApiRes;
import com.jeequan.jeepay.core.model.DBOSSConfig;
import com.jeequan.jeepay.core.service.ISysConfigService;
import com.jeequan.jeepay.core.utils.FileKit;
import com.jeequan.jeepay.core.utils.SpringBeansUtil;
import org.springframework.beans.factory.annotation.Autowired;
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;

/**
 * 统一文件上传接口（ossFile）
 *
 * @author terrfly
 * @date 2021/6/8 17:07
 */
@RestController
@RequestMapping("/api/ossFiles")
public class OssFileController extends AbstractCtrl {

    @Autowired private ISysConfigService sysConfigService;

    /** 文件上传、 将二进制文件上传到服务器， 在保存到对应是oss上。 （单文件） */
    @PostMapping("/singleFile")
    public ApiRes singleFileUpload(@RequestParam("file") MultipartFile file) {

        if( file == null ) {
            return ApiRes.fail(ApiCodeEnum.SYSTEM_ERROR, "选择文件不存在");
        }
        try {

            // 获取业务类型
            String bizType = getValStringRequired("bizType");

            // 文件存储路径
            String saveDirAndFileName = commonCheckAndGetFilePath(bizType, file.getOriginalFilename(), file.getSize());

            // 预览地址
            String url = getOssService().upload2PreviewUrl(OssFileConfig.getOssFileConfigByBizType(bizType).getOssSavePlaceEnum(), file, saveDirAndFileName);
            return ApiRes.ok(url);

        } catch (BizException biz) {
            throw biz;
        } catch (Exception e) {
            logger.error("upload error, fileName = {}", file.getOriginalFilename(), e);
            throw new BizException(ApiCodeEnum.SYSTEM_ERROR);
        }
    }


    /** 获取文件的上传form表单参数， 文件不上传到服务器， 返回form直接上传到对应的oss地址。  */
    @PostMapping("/form")
    public ApiRes formParams() {

        String bizType = getValStringRequired("bizType"); // 获取文件上传类型
        String sourceFileName = getValStringRequired("sourceFileName");  //用户上传的原始文件名称
        Long sourceFileSize = getValLongRequired("sourceFileSize");  //用户上传的原始文件大小 单位： 字节Byte

        // 文件存储路径
        String saveDirAndFileName = commonCheckAndGetFilePath(bizType, sourceFileName, sourceFileSize);

        OssFileConfig ossFileConfig = OssFileConfig.getOssFileConfigByBizType(bizType);

        IOssService.UploadFormParams result = getOssService().genFormParams(bizType, ossFileConfig, saveDirAndFileName);
        return ApiRes.ok(result);
    }

    /** 统一校验, 获取文件的存储地址 */
    private String commonCheckAndGetFilePath(String bizType, String fileOriginalFilename, Long fileSize){

        OssFileConfig ossFileConfig = OssFileConfig.getOssFileConfigByBizType(bizType);

        //1. 判断bizType 是否可用
        if(ossFileConfig == null){
            throw new BizException("类型有误");
        }

        // 2. 判断文件是否支持
        String fileSuffix = FileKit.getFileSuffix(fileOriginalFilename, false);
        if( !ossFileConfig.isAllowFileSuffix(fileSuffix) ){
            throw new BizException("上传文件格式不支持！");
        }

        // 3. 判断文件大小是否超限
        if( !ossFileConfig.isMaxSizeLimit(fileSize) ){
            throw new BizException("上传大小请限制在["+ossFileConfig.getMaxSize() / 1024 / 1024 +"M]以内！");
        }

        // 新文件地址 (xxx/xxx.jpg 格式)
        return bizType + "/" + UUID.fastUUID() + "." + fileSuffix;
    }


    /** 后端java直接调用上传 */
    public String singleFileUpload(MultipartFile file, String bizType) {

        // 文件存储路径
        String saveDirAndFileName = commonCheckAndGetFilePath(bizType, file.getOriginalFilename(), file.getSize());

        // 预览地址
        return getOssService().upload2PreviewUrl(OssFileConfig.getOssFileConfigByBizType(bizType).getOssSavePlaceEnum(), file, saveDirAndFileName);

    }


    private IOssService getOssService(){

        DBOSSConfig dbossConfig = sysConfigService.getOssConfig();
        return SpringBeansUtil.getBean(dbossConfig.getOssUseType() + "OssService", IOssService.class);

    }


}
