package com.goafanti.common.controller;

import com.goafanti.common.bo.Result;
import com.goafanti.common.utils.FileUtils;
import com.goafanti.common.utils.LoggerUtils;
import com.goafanti.core.shiro.token.TokenManager;
import com.goafanti.order.enums.OrderImgEnums;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@RestController
@RequestMapping(value = "/api")
public class BaseApiController extends BaseController {

	@Value(value = "${upload.path}")
	private String	uploadPath			= null;
	@Value(value = "${upload.private.path}")
	private String	uploadPrivatePath	= null;

	/**
	 *
	 * @param request
	 * @return
	 */
	protected List<MultipartFile> getFiles(HttpServletRequest request) {
		if (ServletFileUpload.isMultipartContent(request)) {
			Iterator<String> itr = ((MultipartRequest) request).getFileNames();
			List<MultipartFile> files = new ArrayList<MultipartFile>();
			if (itr.hasNext()) {
				files.add(((MultipartRequest) request).getFile(itr.next()));
			}
			return files;
		}
		return new ArrayList<MultipartFile>();
	}

	/**
	 *
	 */
	protected String handleFile(Result res, String path, boolean isPrivate, HttpServletRequest req, String sign) {
		List<MultipartFile> files = getFiles(req);
		String fileName = "";
		if (!files.isEmpty()) {
			try {
				MultipartFile mf = files.get(0);
				fileName = FileUtils.splicingFileName(mf, isPrivate, sign, path, TokenManager.getUserId());
				mf.transferTo(isPrivate ? toPrivateFile(fileName) : toFile(fileName));
				LoggerUtils.debug(getClass(), fileName + " 文件上传成功");
			} catch (Exception e) {
				LoggerUtils.error(getClass(), "文件上传失败", e);
				res.getError().add(buildError("", "文件上传失败!"));
			}
		} else {
			res.getError().add(buildError("", "文件为空，上传失败!"));
		}
		return fileName;
	}


	/**
	 *  上传图片并压缩
	 */
	protected String uploadFile(Result res, String path,  HttpServletRequest req,String id, String sign) {
		List<MultipartFile> files = getFiles(req);
		String fileName = "";
		if (!files.isEmpty()) {
			try {
				MultipartFile mf = files.get(0);
				fileName = FileUtils.orderFileName(mf,id,path,sign);
				File file=toFile(fileName);
				mf.transferTo(file);
				fileName=compressFile(file,fileName);
				LoggerUtils.debug(getClass(), fileName + " 文件上传成功");
			} catch (Exception e) {
				LoggerUtils.error(getClass(), "文件上传失败", e);
				res.getError().add(buildError("", "文件上传失败!"));
			}
		} else {
			res.getError().add(buildError("", "文件为空，上传失败!"));
		}
		return fileName;
	}

	/**
	 * 图片压缩
	 */
	private String compressFile(File file, String fileName) throws IOException {
		if (file.length()>5242880&&
		(fileName.contains("jpg")||fileName.contains("jpeg")||fileName.contains("bmp") ||fileName.contains("png"))){
			String filetType="jpg";
			if (fileName.contains("jpeg")){
				filetType="jpeg";
			}else if (fileName.contains("bmp")){
				filetType="bmp";
			}else if (fileName.contains("png")){
				filetType="png";
			}
			String thumbnailFilePathName = fileName.substring(0, fileName.lastIndexOf(".")) + "_min"+fileName.substring(fileName.lastIndexOf("."));
			double scale = 0.4d ;
			Thumbnails.of(file).scale(1f).outputQuality(scale)
					.outputFormat(filetType)
					.toFile(uploadPath+thumbnailFilePathName);
			FileUtils.deleteFile(uploadPath+fileName);
			return thumbnailFilePathName;
		}
		return fileName;
	}

	protected Result deleteFile (Result res,String fileName){
		if (StringUtils.isBlank(fileName)) {
			res.getError().add(buildError("文件路径错误"));
			return res;
		}
		try {
			if (!com.goafanti.common.utils.excel.FileUtils.checkAllowDownload(fileName)) {
				throw new Exception("文件名称非法，不允许删除。 ");
			}
			String filePath = uploadPath + "/" + fileName;
			com.goafanti.common.utils.excel.FileUtils.deleteFile(filePath);
			if (fileName.contains(OrderImgEnums.CONTRACT.getCode())){

			}
			res.setData(1);
		} catch (Exception e) {
			LoggerUtils.error(PublicController.class, "删除文件失败", e);
		}
		return res;
	}


	/**
	 *
	 * @param res
	 * @param isPrivate
	 * @param req
	 * @return
	 */
	protected String handleFile(Result res, boolean isPrivate, HttpServletRequest req, String... fileName) {
		List<MultipartFile> files = getFiles(req);
		String realFilePath = "";
		if (!files.isEmpty()) {
			try {
				MultipartFile mf = files.get(0);
				realFilePath = FileUtils.buildFilePath(fileName) + FileUtils.getSuffix(mf.getOriginalFilename());
				File f = isPrivate ? toPrivateFile(realFilePath) : toFile(realFilePath);
				mf.transferTo(f);
				LoggerUtils.debug(getClass(), realFilePath + " 文件上传成功");
			} catch (Exception e) {
				LoggerUtils.error(getClass(), "文件上传失败", e);
				res.getError().add(buildError("", "文件上传失败!"));
			}
		} else {
			res.getError().add(buildError("", "文件上传失败!"));
		}
		return realFilePath;
	}

	/**
	 *
	 * @param res
	 * @param fileName
	 * @param filePath
	 */
	protected void downloadFile(HttpServletResponse res, String fileName, String filePath) {
		FileUtils.downloadFile(res, fileName,  uploadPath+ filePath);

	}

	protected void downloadUnPrivateFile(HttpServletResponse res, String fileName, String filePath) {
		FileUtils.downloadFile(res, fileName, uploadPrivatePath + filePath);
	}




	private File buildFile(String filePath) {
		File toFile = new File(filePath);
		toFile.mkdirs();
		return toFile;
	}

	/**
	 *
	 * @param fileName
	 * @return
	 */
	protected File toFile(String fileName) {
		return buildFile(uploadPath + fileName);
	}

	/**
	 *
	 * @param fileName
	 * @return
	 */
	protected File toPrivateFile(String fileName) {
		return buildFile(uploadPrivatePath + fileName);
	}

	/**
	 *
	 * @param fileName
	 * @return
	 */
	protected File toAdminPrivateFile(String fileName) {
		return buildFile(uploadPrivatePath + FileUtils.buildFilePath("/admin/", fileName));
	}

	protected Integer getPageNo(String pageNo) {
		if (StringUtils.isNumeric(pageNo)) {
			Integer pn = Integer.parseInt(pageNo);
			return pn < 1 ? 1 : pn;
		}
		return 1;
	}

	protected Integer getPageSize(String pageSize) {
		if (StringUtils.isNumeric(pageSize)) {
			Integer ps = Integer.parseInt(pageSize);
			return ps > 50 ? 50 : (ps < 10 ? 10 : ps);
		}
		return 10;
	}

	protected String handleFiles(Result res, String path, boolean isPrivate, HttpServletRequest req, String sign,
			String uid) {
		List<MultipartFile> files = getFiles(req);
		MultipartFile mf = files.get(0);

		String fileName = FileUtils.mosaicFileName(mf, isPrivate, sign, path,
				StringUtils.isBlank(uid) ? TokenManager.getUserId() : uid);
		if (!files.isEmpty()) {
			try {
				if (isPrivate) {
					mf.transferTo(toPrivateFile(fileName));
				} else {
					mf.transferTo(toFile(fileName));
				}
				LoggerUtils.debug(getClass(), fileName + " 文件上传成功");
			} catch (IllegalStateException | IOException e) {
				LoggerUtils.error(getClass(), "文件上传失败", e);
				res.getError().add(buildError("", "文件上传失败!"));
				return "";
			}
		} else {
			res.getError().add(buildError("", "文件上传失败!"));
			return "";
		}
		return fileName;
	}

	protected Integer handlePageNo(String pageNo) {
		try {
			Integer n = Integer.valueOf(pageNo);
			return n < 1 ? 1 : n;
		} catch (Exception e) {
			return 1;
		}
	}

	protected Integer handlePageSize(String pageSize) {
		try {
			Integer s = Integer.valueOf(pageSize);
			return s < 5 ? 5 : s > 100 ? 100 : s;
		} catch (Exception e) {
			return 10;
		}
	}

	protected Result res() {
		return new Result();
	}
}
