package com.goafanti.common.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;

import com.goafanti.achievement.bo.InputAchievement;
import com.goafanti.common.bo.Error;
import com.goafanti.common.error.BusinessException;


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

	private static final Pattern	SLASH_PATTERN		= Pattern.compile("^/|/$");
	private static final String		SLASH				= "/";
	private static final String		UNDERLINE			= "_";

	/**
	 * response 输出JSON
	 *
	 * @param hresponse
	 * @param resultMap
	 * @throws IOException
	 */
	public static void out(HttpServletResponse response, String jsonStr) {
		PrintWriter out = null;
		try {
			response.setHeader("Content-Type", "application/json");
			response.setCharacterEncoding("UTF-8");
			out = response.getWriter();
			out.println(jsonStr);
		} catch (Exception e) {
			LoggerUtils.fmtError(FileUtils.class, e, "输出数据失败");
		} finally {
			if (null != out) {
				out.flush();
				out.close();
			}
		}
	}

	/**
	 * Excel报表导出
	 *
	 * @param response
	 * @param fileName
	 * @param workbook
	 */
	public static void downloadExcel(HttpServletResponse response, String fileName, HSSFWorkbook workbook) {
		String fn = null;
		try {
			fn = URLEncoder.encode(fileName, "UTF-8");
		} catch (UnsupportedEncodingException e1) {
			fn = fileName;
		}
		response.setContentType("application/x-download;charset=UTF-8");
		response.setHeader("Content-Disposition", "attachment; filename=\"" + fn + "\";");
		OutputStream out = null;
		try {
			out = response.getOutputStream();
			workbook.write(out);
		} catch (IOException e) {
			LoggerUtils.fmtError(FileUtils.class, e, "输出Excel失败");
		} finally {
			if (null != out) {
				try {
					out.flush();
					out.close();
				} catch (IOException e) {
					out = null;
				}
			}
		}
	}

	/**
	 * 根据上传文件 拼接fileName
	 *
	 * @param mf
	 * @param isPrivate
	 * @param sign
	 * @param path
	 * @return
	 */
	public static String mosaicFileName(MultipartFile mf, boolean isPrivate, String sign, String path, String uid) {
		String suffix = mf.getOriginalFilename().substring(mf.getOriginalFilename().lastIndexOf("."));
		boolean uniq = false;
		if (sign.indexOf("demand_picture") != -1|| sign.indexOf("achievement_picture") != -1 || sign.indexOf("user_picture")!=-1
				|| sign.indexOf("jt_project_picture")!=-1 || sign.indexOf("jt_business_picture")!=-1 || sign.indexOf("honor_picture")!=-1
				|| sign.indexOf("banners")!=-1|| sign.indexOf("head_portrait")!=-1 || sign.indexOf("video")!=-1 ||sign.indexOf("eventPlanning")!=-1 ) {
			uniq = true;
		}
		String fileName = "";
		if (isPrivate || StringUtils.isNotBlank(sign)) {
			if (uniq) {
				fileName = path + uid + "/" + System.nanoTime() + "_" + sign + suffix;
			} else {
				fileName = path + uid + "/" +  sign + suffix;
			}
		} else {
			fileName = path + uid + "/" + System.nanoTime() + suffix;
		}
		return fileName;
	}

	public static String mosaicFileName( String fn, boolean isPrivate, String path, String uid) {
		String fileName = "";
		if (isPrivate) {
			fileName = path + uid + "/" + fn;
		} else {
			fileName = path + uid + "/" + "logo"  + fn ;
		}
		return fileName;
	}

	/**
	 * 获取下载文件名称
	 *
	 * @param path
	 * @return
	 */
	public static String getDownloadFileName(String path) {
		if (StringUtils.isBlank(path) || path.lastIndexOf(".") < 0) {
			return null;
		}
		String prefix = "附件";
		String suffix = path.substring(path.lastIndexOf("."));
		return prefix + suffix;
	}

	public static String getSuffix(String path) {
		if (StringUtils.isBlank(path) || path.lastIndexOf(".") < 0) {
			return "";
		}
		return path.substring(path.lastIndexOf("."));
	}

	/**
	 * 拼接文件路径
	 *
	 * @param root
	 * @param params
	 * @return
	 */
	public static String buildFilePath(String... params) {
		StringBuilder sb = new StringBuilder();
		if (params != null) {
			for (String s : params) {
				sb.append(SLASH);
				sb.append(SLASH_PATTERN.matcher(s).replaceAll(""));
			}
		}
		return sb.toString();
	}

	/**
	 * 拼接文件名字
	 *
	 * @param root
	 * @param params
	 * @return
	 */
	public static String buildFileName(String... params) {
		return StringUtils.join(params, UNDERLINE);
	}

	// year
	private static String subStr(String s) {
		return "企业" + s.substring(s.lastIndexOf(UNDERLINE) + 1, s.lastIndexOf("."));
	}

	public static boolean deleteFile(String realFilePath) {
		return new File(realFilePath).delete();
	}

	/**
	 *
	 * @param response
	 * @param fileName
	 * @param realFilePath
	 */
	public static void downloadFile(HttpServletResponse response, String fileName, String realFilePath) {
		InputStream in = null;
		OutputStream out = null;
		byte[] buffer = new byte[8 * 1024];
		try {
			File file = new File(realFilePath);
			in = new FileInputStream(file);
			out = response.getOutputStream();
			// 设置文件MIME类型
			response.setContentType("application/octet-stream");
			fileName = java.net.URLEncoder.encode(fileName, "UTF-8");
			response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
			response.setHeader("Content-Length", String.valueOf(file.length()));
			for (;;) {
				int bytes = in.read(buffer);
				if (bytes == -1) {
					break;
				}
				out.write(buffer, 0, bytes);
			}
		} catch (IOException e) {
			LoggerUtils.fmtError(FileUtils.class, e, "IO错误：%s", e.getMessage());
		} finally {
			try {
				if (in != null) {
					in.close();
				}
			} catch (IOException e) {
				in = null;
				LoggerUtils.fmtError(FileUtils.class, e, "IO错误：%s", e.getMessage());
			}
			try {
				if (out != null) {
					out.close();
				}
			} catch (IOException e) {
				out = null;
				LoggerUtils.fmtError(FileUtils.class, e, "IO错误：%s", e.getMessage());
			}
		}
	}

	public static Workbook getWorkBook(MultipartFile file) {
        //创建Workbook工作薄对象，表示整个excel
        Workbook workbook = null;
        try {
        //获取excel文件的io流
        InputStream is = file.getInputStream();
        //如果是xls，使用HSSFWorkbook；如果是xlsx，使用XSSFWorkbook
        if(file.getOriginalFilename().matches("^.+\\.(?i)(xls)$"))workbook = new HSSFWorkbook(is);
        if(file.getOriginalFilename().matches("^.+\\.(?i)(xlsx)$"))workbook = new XSSFWorkbook(is);
        } catch (IOException e) {
        }
        return workbook;
        }

	public static Sheet pushReadFile(MultipartFile file) {
		 //获得Workbook工作薄对象
	       Workbook workbook = getWorkBook(file);
	       Sheet sheet=null;
	       if(workbook != null){
	       	//获得当前sheet工作表
	   		 sheet = workbook.getSheetAt(0);
	   		if(sheet == null){
	   			throw new BusinessException(new Error("未找到正确的参数。"));
	   		}
	       }
	       return sheet;
	}

	public static  int rowDispose(Sheet sheet, int firstRowNum) {
		int lastRowNum=sheet.getLastRowNum();
		//处理空白行
   		for (int i = firstRowNum; i <= sheet.getLastRowNum();i++) {
   			Row r = sheet.getRow(i);
   			if(r == null){
   				// 如果是空行（即没有任何数据、格式），直接把它以下的数据往上移动
   				sheet.shiftRows(i+1, sheet.getLastRowNum(),-1);
   				continue;
   			}
   			boolean flag = false;
   			for(Cell c:r){
   				if(c.getCellTypeEnum() != CellType.BLANK){
   					flag = true;
   					break;
   				}
   			}
   			if(flag){
   				i++;
   				continue;
   			} else{
   				//如果是空白行（即可能没有数据，但是有一定格式）
   				if(i == sheet.getLastRowNum())//如果到了最后一行，直接将那一行remove掉
   					sheet.removeRow(r);
   				else//如果还没到最后一行，则数据往上移一行
   				    sheet.shiftRows(i+1, sheet.getLastRowNum(),-1);
   			}
   		}

   		if (lastRowNum<2) {
   			throw new BusinessException(new Error("未找到正确的参数。"));
			}
		return sheet.getLastRowNum();
	}

	public static  int rowDisposeNotBlank(Sheet sheet, int firstRowNum) {
		int lastRowNum=sheet.getLastRowNum();
		//行数从0开始 默认使用2行做头部，则设置1
		int i=1;
		for(int rowNum = firstRowNum+2;rowNum <= lastRowNum;rowNum++){
			Row row = sheet.getRow(rowNum);
			if(row == null){
				continue;
			}
			 Cell cell = row.getCell(0);
			 String str =FileUtils.getCellValue(cell);
			 if (StringUtils.isNotBlank(str)) {
				i++;
			}
		}
   		if (i<2) {
   			throw new BusinessException(new Error("未找到正确的参数。"));
			}
		return i;
	}

	public static String getCellValue(Cell cell){
     	String cellValue = "";
     	if(cell == null){
     		return cellValue;
     	}
     	        //把数字当成String来读，避免出现1读成1.0的情况
     	        if(cell.getCellTypeEnum() == CellType.NUMERIC){
     	        cell.setCellType(CellType.STRING);
     	        }
     	        //判断数据的类型
     	        switch (cell.getCellTypeEnum()){
     	        case NUMERIC: //数字
     	        cellValue = String.valueOf(cell.getNumericCellValue());
     	        break;
     	        case STRING: //字符串
     	        cellValue = String.valueOf(cell.getStringCellValue());
     	        break;
     	        case BOOLEAN: //Boolean
     	        cellValue = String.valueOf(cell.getBooleanCellValue());
     	        break;
     	        case FORMULA: //公式
     	        cellValue = String.valueOf(cell.getCellFormula());
     	        break;
     	        case BLANK: //空值
     	        cellValue = "";
     	        break;
     	        case ERROR: //故障
     	        cellValue = "非法字符";
     	        break;
     	        default:
     	        cellValue = "未知类型";
     	        break;
     	        }
     	        return cellValue;
	}

}
