package com.sckw.file.controller;

import com.sckw.core.annotation.RepeatSubmit;
import com.sckw.core.model.file.FileInfo;
import com.sckw.core.web.constant.HttpStatus;
import com.sckw.core.web.response.HttpResult;
import com.sckw.core.web.response.result.Status;
import com.sckw.file.api.dto.FileInfoDTO;
import com.sckw.file.dubbo.FileDubboApiServiceImpl;
import com.sckw.file.model.param.FileImageParam;
import com.sckw.file.service.FileService;
import io.seata.spring.annotation.GlobalTransactional;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.text.ParseException;
import java.util.Map;

/**
 * @author lfdc
 * @version 1.0
 * @className FileApiController
 * @description alibaba-oss测试用例
 * @company sckw
 * @date 2023-06-02 16:06:43
 */
@Slf4j
@RestController
@RequestMapping("/file")
@AllArgsConstructor
public class KwfFileController {

    @Autowired
    private FileService fileService;

    @Autowired
    private FileDubboApiServiceImpl fileApiService;

    /**
     * 上传文件至OSS
     *
     * @param file
     * @return
     */
    @RequestMapping(value = "/fileUpload", method = RequestMethod.POST)
    public HttpResult fileUpload(@RequestParam("file") MultipartFile file) {
        try {
            //获取上传文件
            return fileService.uploadFile(file);
        } catch (Exception e) {
            log.error("文件上传失败:{}", e.getMessage(), e);
            return HttpResult.error(HttpStatus.GLOBAL_EXCEPTION_CODE, e.getMessage());
        }

    }

    /**
     * 批量上传文件至OSS
     *
     * @param file
     * @return
     */
    @RequestMapping(value = "/fileUploadList", method = RequestMethod.POST)
    public HttpResult uploadFileList(@RequestParam("file") MultipartFile[] file) {
        //获取上传文件
        return fileService.uploadFileList(file);

    }

    /**
     * OSS下载文件/获取文件地址
     *
     * @return
     */
    @RequestMapping(value = "/fileDownload", method = RequestMethod.GET)
    public HttpResult fileDownload(@NotBlank @RequestParam("fileName") String fileName) {
        try {
            fileService.fileDownload(fileName);
            return HttpResult.ok();
        } catch (Exception e) {
            log.error("文件下载失败:{}", e.getMessage(), e);
            return HttpResult.error(HttpStatus.GLOBAL_EXCEPTION_CODE, e.getMessage());
        }
    }

    /**
     * oss删除文件
     *
     * @param fileName https://kaiwu-saas.oss-cn-chengdu.aliyuncs.com/kll/uploads/20230621/07ccbec381a011d121a215719199ac49.html
     * @return
     */
    @RequestMapping(value = "/remove", method = RequestMethod.GET)
    public HttpResult remove(String fileName) {
        //获取上传文件
        fileService.remove(fileName);
        return HttpResult.ok(HttpStatus.SUCCESS_CODE, HttpStatus.SUCCESS_MESSAGE);
    }

    /***
     * 批量下载(zip)
     * @param fileAllName
     * @param response
     * @throws IOException
     * fileAllName为前端传过来的多个文件路径字符串，用逗号隔开('filePath/file.xsl','filePath/file1.xsl','filePath/file2.xsl')
     */
    @RequestMapping("downAllOssFile")
    @ResponseBody
    public HttpResult downAllOssFile(@RequestParam("fileAllName") String fileAllName, HttpServletRequest request, HttpServletResponse response) {
        return fileService.downAllOssFile(fileAllName, request, response);
    }

    /**
     * 前端调用接口获取oss信息-使用中
     *
     * @param file
     * @return
     */
    @RequestMapping(value = "/uploadFileInfo", method = RequestMethod.POST)
    public HttpResult uploadFileInfo(@RequestParam("file") MultipartFile file) {
        try {
            return fileService.uploadFileInfo(file);
        } catch (Exception e) {
            log.info("上传文件失败:{}",e.getMessage(),e);
            return HttpResult.error("上传文件失败:" + e.getMessage());
        }
    }


    /**
     * app-前端调用接口上传oss
     *
     * @param file
     * @return
     */
    @RequestMapping(value = "/appUploadFileInfo", method = RequestMethod.POST,produces = "application/json")
    public HttpResult appUploadFileInfo(@RequestParam("file") MultipartFile file) {
        try {
            return fileService.appUploadFileInfo(file);
        } catch (Exception e) {
            log.info("上传文件失败:{}",e.getMessage(),e);
            return HttpResult.error(Status.FAILURE.getCode(),"上传文件失败:" + e.getMessage());
        }
    }

    /**
     * 前端调用接口获取oss信息-加密
     *
     * @param file
     * @return
     */
    @RequestMapping(value = "/uploadFileEncrypt", method = RequestMethod.POST,produces = "application/json")
    public HttpResult uploadFileEncrypt(@NotNull @RequestParam("file") MultipartFile file) {
        try {
            return fileService.uploadFileEncrypt(file);
        } catch (Exception e) {
            log.info("上传文件失败:{}",e.getMessage(),e);
            return HttpResult.error("上传文件失败:" + e.getMessage());
        }
    }

    /**
     * app-前端调用接口获取oss信息-加密
     *
     * @param file
     * @return
     */
    @RequestMapping(value = "/appUploadFileEncrypt", method = RequestMethod.POST,produces = "application/json")
    public HttpResult appUploadFileEncrypt(@RequestParam("file") MultipartFile file) {
        try {
            return fileService.appUploadFileEncrypt(file);
        } catch (Exception e) {
            log.info("上传文件失败:{}",e.getMessage(),e);
            return HttpResult.error(Status.FAILURE.getCode(),"上传文件失败:" + e.getMessage());
        }
    }

    @RepeatSubmit(interval = 1000,message ="前方拥堵，请稍后尝试")
    @RequestMapping(name = "通过key获取地址",value = "/getImage",method = RequestMethod.POST)
    public HttpResult getImage(@RequestBody @Valid FileImageParam fileImageParam){
        try {
            return fileService.getImage(fileImageParam);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * dubbo接收文件信息保存至数据库
     *
     * @param fileInfo
     * @return
     */
    @RequestMapping(value = "/fileInfoInsertByOSS", method = RequestMethod.POST)
    @GlobalTransactional(rollbackFor = Exception.class)
    public HttpResult fileInfoInsertByOSS(@RequestBody FileInfo fileInfo) {
        try {
            return fileApiService.fileInfoInsert(fileInfo);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * dubbo接收上传文件至OSS
     *
     * @param inputStream
     * @param FileInfoDTO
     * @return
     */
    @RequestMapping(value = "/fileDubboUpload", method = RequestMethod.POST)
    public HttpResult fileDubboUpload(InputStream inputStream, FileInfoDTO FileInfoDTO) {
        return fileService.fileDubboUpload(inputStream, FileInfoDTO);
    }

    /**
     * feign接收上传文件至OSS
     *
     * @param file
     * @return
     */
    @RequestMapping(value = "/fileFeignUpload", method = RequestMethod.POST)
    public HttpResult fileFeignUpload(@RequestParam("file") MultipartFile file) {
        return fileService.uploadFile(file);
    }

    /**
     * file-feign-demo
     *
     * @param userName
     * @return
     */
    @GetMapping(value = "/fileFeignDemo")
    public HttpResult fileFeignDemo(@RequestParam("userName") String userName) {
        return HttpResult.ok(userName);
    }


    /**
     * file-feign-demo1
     *
     * @param map
     * @return
     */
    @RequestMapping(value = "fileFeignDemo1", method = RequestMethod.POST)
    public HttpResult fileFeignDemo1(@RequestBody Map<String, String> map) {
        return HttpResult.ok(map);
    }


    @RequestMapping(value = "/selectAll", method = RequestMethod.GET)
    public HttpResult selectAll() {
        return fileService.selectAll();
    }

}
