package cn.superdesk.uniorder.controller._common;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import cn.superdesk.uniorder.common.rest.response.AnResponseStreamUtils;
import cn.superdesk.uniorder.common.rest.response.R;
import cn.superdesk.uniorder.common.rest.response.ResponseResultOuterUtils;
import cn.superdesk.uniorder.common.security.JwtUtil;
import cn.superdesk.uniorder.common.security.dto.LoginSysUser;
import cn.superdesk.uniorder.controller.base.BaseController;
import cn.superdesk.uniorder.dao.entity.common.UploadFiles;
import cn.superdesk.uniorder.dto._constant.ResourceConstant;
import cn.superdesk.uniorder.dto.param._common.UploadFilesListByUploadFileIdsCriteria;
import cn.superdesk.uniorder.dto.param._common.UploadFilesListByUploadFileUidsCriteria;
import cn.superdesk.uniorder.dto.param._common.UploadFilesParam;
import cn.superdesk.uniorder.dubbo.consumer._common.ProviderEnvConstantDubboCustomerService;
import cn.superdesk.uniorder.dubbo.consumer._common.UploadFilesDubboConsumerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @Description: 统一订单 公共接口-文件上传下载删除-不限文件类型
 * @Author: linjinyu
 * @CreateDate: 9/17/20 4:12 PM
 * @UpdateUser: linjinyu
 * @UpdateDate: 9/17/20 4:12 PM
 * @UpdateRemark: 修改内容
 * @Version: 1.0
 */
@Api(value = "公共接口-文件上传下载删除-不限文件类型", tags = {"公共接口-文件上传下载删除-不限文件类型"})
@Slf4j
@RestController
@RequestMapping("/common/upload/files")
public class CommonUploadFilesController extends BaseController {

	@Resource
	private UploadFilesDubboConsumerService         uploadFilesDubboConsumerService;
	@Resource
	private ProviderEnvConstantDubboCustomerService providerEnvConstantDubboCustomerService;

	/****************************************** 上传 start ******************************************/

	@ApiOperation(value = "多文件上传-返回持久化记录")
	@RequestMapping(value = "/uploadManyAndStoreRecord", method = RequestMethod.POST)
	public R<?> uploadManyAndStoreRecord(@RequestParam(value = "file") MultipartFile[] file) throws IOException {

		LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(getToken());

		ResourceConstant excelExportConstant = providerEnvConstantDubboCustomerService.getResourceConstant();

		String excelExportPathRoot             = excelExportConstant.getPathRoot();
		String excelExportRelativePathTemplate = excelExportConstant.getPathTemplate();
		String excelExportRelativePathStorage  = excelExportConstant.getPathStorage();

		String attachment = "attachment";

		String currentDate = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));

		String relativePath   = File.separator + attachment + File.separator + currentDate + File.separator;
		String targetFullPath = excelExportPathRoot + excelExportRelativePathStorage + relativePath;


		if (!FileUtil.exist(targetFullPath)) {
			FileUtil.mkdir(targetFullPath);
		}

		List<UploadFilesParam> pathList = new ArrayList<>();

//		org.apache.tomcat.util.http.fileupload.impl.SizeLimitExceededException: the request was rejected because its size (70395315) exceeds the configured maximum (52428800)

		if (file.length > 0) {

			for (MultipartFile multipartFile : file) {

				String fileOriginalName = multipartFile.getOriginalFilename();
				String mimeType         = multipartFile.getContentType();
				String uid              = UUID.randomUUID().toString();
				String fileName         = uid + "@" + fileOriginalName;
				String suffix           = Objects.requireNonNull(multipartFile.getOriginalFilename()).substring(multipartFile.getOriginalFilename().lastIndexOf(".") + 1);

				File file1 = FileUtil.writeBytes(multipartFile.getBytes(), targetFullPath + fileName);

				if (file1.length() > 0) {

					UploadFilesParam tmp = UploadFilesParam.builder()
							.uid(uid)
							.appId("")
							.groupName("flsc_qch")
							.provider("local")
							.fileOriginalName(fileOriginalName)
							.fileName(fileName)
							.fileUrl(targetFullPath + fileName)
							.fileLocation(relativePath + fileName)
							.suffix(suffix)
							.mimeType(mimeType)
							.createTime(DateUtil.date())
							.createUserId(loginSysUser.getSysUserId())
							.createUserName(loginSysUser.getFullName())
							.build();

					uploadFilesDubboConsumerService.addUploadFiles(tmp);

					pathList.add(tmp);
				}
			}
		} else {
			return ResponseResultOuterUtils.createErrorResult("500", "未检查到文件流");
		}

		return ResponseResultOuterUtils.createSuccesResult(pathList);
	}

	/****************************************** 查看 start ******************************************/

	@Deprecated
	@ApiOperation(value = "查看文件列表-根据-uploadFileIds")
	@PostMapping("listByUploadFileIds")
	public R<?> listByUploadFileIds(@RequestBody UploadFilesListByUploadFileIdsCriteria criteria) {

		LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(getToken());

		List<UploadFiles> uploadFiles = uploadFilesDubboConsumerService.findUploadFilesByIds(criteria.getUploadFileIds());

		if (CollUtil.isEmpty(uploadFiles)) {
			return ResponseResultOuterUtils.createErrorResult("500", "资源不存在");
		}

		return ResponseResultOuterUtils.createSuccesResult(uploadFiles);
	}


	@ApiOperation(value = "查看文件列表-根据-uploadFileUids")
	@PostMapping("listByUploadFileUids")
	public R<?> listByUploadFileUids(@RequestBody UploadFilesListByUploadFileUidsCriteria criteria) {

		LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(getToken());

		List<UploadFiles> uploadFiles = uploadFilesDubboConsumerService.findUploadFilesByUids(criteria.getUploadFileUids());

		if (CollUtil.isEmpty(uploadFiles)) {
			return ResponseResultOuterUtils.createErrorResult("500", "资源不存在");
		}

		return ResponseResultOuterUtils.createSuccesResult(uploadFiles);
	}

	/****************************************** 下载 start ******************************************/

	@Deprecated
	@ApiOperation(value = "下载文件-根据-uploadFileId")
	@GetMapping("downloadByUploadFileId/{uploadFileId}")
	@ResponseBody
	public void downloadByUploadFileId(HttpServletResponse response, @PathVariable Long uploadFileId) {

		LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(getToken());

		UploadFiles uploadFiles = uploadFilesDubboConsumerService.findUploadFilesById(uploadFileId);

		if (ObjectUtil.isEmpty(uploadFiles)) {
			AnResponseStreamUtils.outputJson(JSONUtil.toJsonStr(ResponseResultOuterUtils.createErrorResult("500", "资源不存在")), response);
			return;
		}

		download(response, uploadFiles);

	}

	/**
	 * /common/upload/files/downloadByUploadFileUid/{uploadFileUid}
	 *
	 * @param response
	 * @param uploadFileUid
	 * @return
	 */
	@ApiOperation(value = "下载文件-根据-uploadFileUid")
	@GetMapping("downloadByUploadFileUid/{uploadFileUid}")
	@ResponseBody
	public void downloadByUploadFileUid(HttpServletResponse response, @PathVariable String uploadFileUid) {

		LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(getToken());

		UploadFiles uploadFiles = uploadFilesDubboConsumerService.findUploadFilesByUid(uploadFileUid);

		if (ObjectUtil.isEmpty(uploadFiles)) {
			AnResponseStreamUtils.outputJson(JSONUtil.toJsonStr(ResponseResultOuterUtils.createErrorResult("500", "资源不存在")), response);
			return;
		}

		download(response, uploadFiles);

	}

	private void download(HttpServletResponse response, UploadFiles uploadFiles) {

		ResourceConstant excelExportConstant = providerEnvConstantDubboCustomerService.getResourceConstant();

		String excelExportPathRoot             = excelExportConstant.getPathRoot();
		String excelExportRelativePathTemplate = excelExportConstant.getPathTemplate();
		String excelExportRelativePathStorage  = excelExportConstant.getPathStorage();

		String attachment = "attachment";

		// relativePath = fileLocation
		String relativePath   = uploadFiles.getFileLocation();
		String targetFullPath = excelExportPathRoot + excelExportRelativePathStorage + relativePath;

		try {

			// getWriter() has already been called for this response // 通过reset的处理办法不优 再考量

			// 准备将Excel的输出流通过response输出到页面下载 会有问题
//			response.reset();
//			response.flushBuffer();

			// throw IOException
			ServletOutputStream outputStream = response.getOutputStream();

			response.setContentType("application/force-download");
			// 设置编码,避免文件名中文乱码
			response.setHeader("Content-Disposition", "attachment;filename=" + uploadFiles.getFileOriginalName());
			outputStream.write(FileUtil.readBytes(targetFullPath));

			IoUtil.close(outputStream);

			outputStream.flush();

		} catch (IOException ioe) {
			ioe.printStackTrace();
		}

	}


	/****************************************** 删除 start ******************************************/

	@Deprecated
	@ApiOperation(value = "删除文件-根据-uploadFileId")
	@GetMapping("deleteByUploadFileId/{uploadFileId}")
	public R<?> deleteByUploadFileId(@PathVariable Long uploadFileId) {

		LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(getToken());

		UploadFiles uploadFiles = uploadFilesDubboConsumerService.findUploadFilesById(uploadFileId);

		if (ObjectUtil.isEmpty(uploadFiles)) {
			return ResponseResultOuterUtils.createErrorResult("500", "资源不存在");
		}

		delete(uploadFiles);

		return null;
	}

	/**
	 * /common/upload/files/deleteByUploadFileUid/{uploadFileUid} 非本来不能删除
	 *
	 * @param response
	 * @param uploadFileUid
	 * @return
	 */
	@ApiOperation(value = "删除文件-根据-uploadFileUid")
	@GetMapping("deleteByUploadFileUid/{uploadFileUid}")
	public R<?> deleteByUploadFileUid(@PathVariable String uploadFileUid) {

		LoginSysUser loginSysUser = JwtUtil.getLoginSysUser(getToken());

		UploadFiles uploadFiles = uploadFilesDubboConsumerService.findUploadFilesByUid(uploadFileUid);

		if (ObjectUtil.isEmpty(uploadFiles)) {
			return ResponseResultOuterUtils.createErrorResult("500", "资源不存在");
		}

		if (!uploadFiles.getCreateUserId().equals(loginSysUser.getSysUserId())) {
			return ResponseResultOuterUtils.createErrorResult("500", "要删除此资源请经本人同意");
		}

		return delete(uploadFiles);
	}

	private R<?> delete(UploadFiles uploadFiles) {

		ResourceConstant excelExportConstant = providerEnvConstantDubboCustomerService.getResourceConstant();

		String excelExportPathRoot             = excelExportConstant.getPathRoot();
		String excelExportRelativePathTemplate = excelExportConstant.getPathTemplate();
		String excelExportRelativePathStorage  = excelExportConstant.getPathStorage();

		String attachment = "attachment";

		// relativePath = fileLocation
		String relativePath   = uploadFiles.getFileLocation();
		String targetFullPath = excelExportPathRoot + excelExportRelativePathStorage + relativePath;

		FileUtil.del(targetFullPath);

		uploadFilesDubboConsumerService.deleteUploadFiles(uploadFiles.getId());

		return ResponseResultOuterUtils.createSuccesResult();
	}


}
