package com.qmth.qrzk.web.controller;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONObject;

import org.apache.commons.io.IOUtils;
import org.apache.log4j.Logger;
import org.docx4j.Docx4J;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import com.qmth.qrzk.repository.pager.model.PagerConstruct;
import com.qmth.qrzk.repository.pager.service.ZujuanService;
import com.qmth.qrzk.repository.task.WordHistory;
import com.qmth.qrzk.repository.user.model.Attachment;
import com.qmth.qrzk.repository.user.model.User;
import com.qmth.qrzk.repository.user.service.IUserService;
import com.qmth.qrzk.repository.user.service.impl.AttachmentService;
import com.qmth.qrzk.repository.user.service.impl.PaperTaskServiceImpl;
import com.qmth.qrzk.repository.utils.Consts;
import com.qmth.qrzk.repository.utils.General;
import com.qmth.qrzk.repository.utils.docx.HtmlCreator;
import com.zhuozhengsoft.pageoffice.FileSaver;

@Controller
@RequestMapping("/attachment")
public class AttachmentController extends BaseAjaxController{
	
	private static final Logger log = Logger.getLogger(AttachmentController.class);
	
	@Autowired
	private AttachmentService attachmentService;
	
	@Autowired
	private PaperTaskServiceImpl paperTaskSerivce;
	
	@Autowired 
	private ZujuanService zujuanService;
	
	@Autowired
	@Qualifier("userServiceImpl")
	private IUserService userService;
	
	/**
	 * 在线打开word 不可修改内容
	 * @param request
	 * @param response
	 * @param attachmentId
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/viewword/{attachmentId}")
	@ResponseBody
    public Map<String, Object> viewword(HttpServletRequest request, HttpServletResponse response, @PathVariable int attachmentId){
		
		Map<String, Object> map = new HashMap<String, Object>();
		String code = "0";
		Attachment att = attachmentService.getAttachmentById(attachmentId);
    	if(att == null){
    		request.setAttribute("content", "非法链接！");
    		request.setAttribute("title", "非法链接！");
    		code = "1";
//    		return "/word/error";
    	}
    	File paperFile = new File(att.getStorePath());
    	if(!paperFile.exists()){
    		request.setAttribute("content", "您要下载的文件不存在，请与管理员联系！");
    		request.setAttribute("文件不存在", "非法链接！");
    		code = "2";
//    		return "/word/error";
    	}
    	String suffix = att.getOriginalName().substring(att.getOriginalName().lastIndexOf('.'));
		
		//生成临时文件供pageOffice使用
		String filePath = att.getStorePath();
		File file = new File(filePath);  
//		String tempPath = att.getStorePath().replace('\\', '/') + suffix;
		String tempPath = att.getStorePath() + suffix;
		File tempFile = new File(tempPath);
		FileInputStream in = null;
		FileOutputStream out = null;
		try {  
            in = new FileInputStream(file);

//            out = new FileOutputStream(tempFile);
//            IOUtils.copyLarge(in, out);
//			out.flush();
			WordprocessingMLPackage wordMLPackage = Docx4J.load(file);
			Docx4J.save(wordMLPackage, tempFile, Docx4J.FLAG_SAVE_ZIP_FILE);
        } catch (Exception e){
            e.printStackTrace();
        } finally {
        	General.close(in);
        	General.close(out);
        }
		
		map.put("title", att.getOriginalName());
		map.put("tempPath", tempPath);
		map.put("code", code);
		
		return map;
		
//		PageOfficeCtrl poCtrl=new PageOfficeCtrl(request);
//		poCtrl.setMenubar(false);//隐藏菜单栏
//		poCtrl.setOfficeToolbars(false);//隐藏Office工具条
//		poCtrl.setCustomToolbar(false);//隐藏自定义工具栏
//		
//		//设置服务器页面
//		poCtrl.setServerPage(request.getContextPath() + "/poserver.zz");
//		//添加自定义按钮
////		poCtrl.addCustomToolButton("保存","Save",1);
////		String userId = request.getParameter("userId");
//		//设置保存页面
////		poCtrl.setSaveFilePage(request.getContextPath() + "/attachment/savefile/" + attachmentId + "/" + userId);
//		//打开Word文档
//		poCtrl.webOpen(tempPath, OpenModeType.docReadOnly,"张佚名");
//		poCtrl.setTagId("PageOfficeCtrl1");//此行必需
//		
//		request.setAttribute("title", att.getOriginalName());
		
//		return "/word/Word";
    }
	
	@RequestMapping(value = "/openword/{attachmentId}")
	@ResponseBody
    public Map<String, Object> openword(HttpServletRequest request, HttpServletResponse response, @PathVariable int attachmentId){
		
		Map<String, Object> map = new HashMap<String, Object>();
		String paperId = request.getParameter("paperId");
		String attType = request.getParameter("attType");
		
		String code = "0";
		
		if(paperId == null || "".equals(paperId)){
			request.setAttribute("content", "您要下载的文件不存在，请与管理员联系！");
    		request.setAttribute("文件不存在", "非法链接！");
    		code = "1";
//    		return "/word/error";
		}else{
			PagerConstruct pager = zujuanService.findById(Integer.parseInt(paperId));
			if(attType.equals(Consts.WordType.HJ) || attType.equals(Consts.WordType.PAPER)){
				attachmentId = pager.getLastPaperWord();
			}else if(attType.equals(Consts.WordType.DA) || attType.equals(Consts.WordType.ANSWER)){
				attachmentId = pager.getLastAnswerWord();
			}else if(attType.equals(Consts.WordType.WPJ) || attType.equals(Consts.WordType.WANGPING)){
				attachmentId = pager.getLastWangpingWord();
			}else if(attType.equals(Consts.WordType.ZY) || attType.equals(Consts.WordType.ZHUANYIN)){
				//attachmentId = pager.getLastZhuanyinWord();
			}else if(attType.equals(Consts.WordType.ZK)){
				attachmentId = pager.getLastTikaWord();
			}
		}
		
		Attachment att = attachmentService.getAttachmentById(attachmentId);
    	if(att == null){
    		request.setAttribute("content", "非法链接！");
    		request.setAttribute("title", "非法链接！");
    		code = "2";
//    		return "/word/error";
    	}
    	File paperFile = new File(att.getStorePath());
    	if(!paperFile.exists()){
    		request.setAttribute("content", "您要下载的文件不存在，请与管理员联系！");
    		request.setAttribute("文件不存在", "非法链接！");
    		code = "3";
//    		return "/word/error";
    	}
    	String suffix = att.getOriginalName().substring(att.getOriginalName().lastIndexOf('.'));
		
		//生成临时文件供pageOffice使用
		String filePath = att.getStorePath();
		File file = new File(filePath);  
//		String tempPath = att.getStorePath().replace('\\', '/') + suffix;
		String tempPath = att.getStorePath() + suffix;
		File tempFile = new File(tempPath);
		FileInputStream in = null;
		OutputStream out = null;
		try {  
            in = new FileInputStream(file);

//            out = new FileOutputStream(tempFile);
            //Streams.copy(in, out, true);
//			IOUtils.copyLarge(in,out);
//			out.flush();
			WordprocessingMLPackage wordMLPackage = Docx4J.load(file);
			Docx4J.save(wordMLPackage, tempFile, Docx4J.FLAG_SAVE_ZIP_FILE);
        } catch (Exception e){
            e.printStackTrace();  
        } finally {
        	General.close(in);
        	General.close(out);
        }
//		request.setAttribute("title", att.getOriginalName());
//		String userId = request.getParameter("userId");
//		String taskUserId = request.getParameter("taskUserId");
		
		map.put("title", att.getOriginalName());
		map.put("attachmentId", attachmentId);
		map.put("tempPath", tempPath);
		map.put("code", code);
		
		return map;
		
//		PageOfficeCtrl poCtrl=new PageOfficeCtrl(request);
//		poCtrl.setMenubar(false);//隐藏菜单栏
////		poCtrl.setCustomToolbar(false);//隐藏自定义工具栏
//		//设置服务器页面
//		poCtrl.setServerPage(request.getContextPath() + "/poserver.zz");
//		
//		if(userId.equals(taskUserId) && !attType.equals(Consts.WordType.TIKA)){
//			//添加自定义按钮
//			poCtrl.addCustomToolButton("保存","Save",1);
//			//设置保存页面
//			poCtrl.setSaveFilePage(request.getContextPath() + "/attachment/savefile/" + attachmentId + "/" + userId 
//					+ "?paperId=" + paperId + "&attType=" + attType);
//			poCtrl.webOpen(tempPath, OpenModeType.docAdmin,"张佚名");
//		}else{
//			poCtrl.setOfficeToolbars(false);//隐藏Office工具条
//			poCtrl.webOpen(tempPath, OpenModeType.docReadOnly,"张佚名");
//		}
//		//打开Word文档
//		poCtrl.setTagId("PageOfficeCtrl1");//此行必需
		
//		PageOfficeLink.openWindow(request,"/word/Word.jsp","width=1300px;height=730px;");
//		return "/word/editWord";
    } 
	
	@RequestMapping("/savefile/{attachmentId}/{userId}")  
    public void savefile(HttpServletRequest request, HttpServletResponse response, @PathVariable int attachmentId, @PathVariable int userId){
		
		String paperId = request.getParameter("paperId");
		String attType = request.getParameter("attType");
		PagerConstruct pager = zujuanService.findById(Integer.parseInt(paperId));
		if(attType.equals(Consts.WordType.HJ) || attType.equals(Consts.WordType.PAPER)){
			attachmentId = pager.getLastPaperWord();
		}else if(attType.equals(Consts.WordType.DA) || attType.equals(Consts.WordType.ANSWER)){
			attachmentId = pager.getLastAnswerWord();
		}else if(attType.equals(Consts.WordType.WPJ) || attType.equals(Consts.WordType.WANGPING)){
			attachmentId = pager.getLastWangpingWord();
		}else if(attType.equals(Consts.WordType.ZY) || attType.equals(Consts.WordType.ZHUANYIN)){
			attachmentId = pager.getLastZhuanyinWord();
		}else if(attType.equals(Consts.WordType.ZK)){
			attachmentId = pager.getLastTikaWord();
		}
		
		Attachment att = attachmentService.getAttachmentById(attachmentId);
    	if(att == null){
    		response.setCharacterEncoding("UTF-8");
    		response.setContentType("text/html;charset=UTF-8");
    		return;
    	}
    	File paperFile = new File(att.getStorePath());
    	if(!paperFile.exists()){
    		response.setCharacterEncoding("UTF-8");
    		response.setContentType("text/html;charset=UTF-8");
    		return;
    	}
    	String suffix = att.getOriginalName().substring(att.getOriginalName().lastIndexOf('.'));
		
    	String filePath = att.getStorePath();
    	//在线保存文件
		FileSaver fs = new FileSaver(request,response);
		fs.saveToFile(filePath + suffix);
		fs.close();
		
		//判断是否为原始文件
		List<WordHistory> wordHistory = paperTaskSerivce.getPaperWordHistories(Integer.parseInt(paperId), attType);
		File file = new File(filePath + suffix);  
		//判断是否为原始文件
		if(wordHistory != null && wordHistory.size() > 1){
			//不是原始文件 保存之后替换文件
			File tempFile = new File(filePath);
			FileInputStream in = null;
			FileOutputStream out = null;
			try {  
				in = new FileInputStream(file);
				
				out = new FileOutputStream(tempFile);
				IOUtils.copyLarge(in,out);
				out.flush();
			} catch (IOException e){
				e.printStackTrace();  
			} finally {
				General.close(in);
				General.close(out);
			}
			
			attachmentService.updateAtt(att, tempFile, userId);
		}else{
			//是原始文件 重新生成最新word
			FileInputStream is = null;
			Attachment attachment = null;
			try{
				is = new FileInputStream(file);
				attachment = attachmentService.storeFile(is, att.getOriginalName(), userId);
			}catch (IOException e){
				e.printStackTrace();
			} finally {
				General.close(is);
			}
//			PagerConstruct pager = zujuanService.findById(Integer.parseInt(paperId));
			
			if(attType.equals(Consts.WordType.HJ) || attType.equals(Consts.WordType.PAPER)){
				pager.setLastPaperWord(attachment.getId());
			}else if(attType.equals(Consts.WordType.DA) || attType.equals(Consts.WordType.ANSWER)){
				pager.setLastAnswerWord(attachment.getId());
			}else if(attType.equals(Consts.WordType.WPJ) || attType.equals(Consts.WordType.WANGPING)){
				pager.setLastWangpingWord(attachment.getId());
			}else if(attType.equals(Consts.WordType.ZY) || attType.equals(Consts.WordType.ZHUANYIN)){
				pager.setLastZhuanyinWord(attachment.getId());
			}else if(attType.equals(Consts.WordType.ZK)){
				pager.setLastTikaWord(attachment.getId());
			}
			attachmentService.changeAttStatus(attachment.getId(), Consts.AttachmentStatus.USING);
			zujuanService.updatePagerConstruct(pager);
			paperTaskSerivce.addWordHistory(Integer.parseInt(paperId), attachment.getId(), userService.findById(userId), attType);
		}
		
    } 
	
    @RequestMapping(value = "/download/{attachmentId}")
    public void download(HttpServletResponse response,HttpServletRequest request,@PathVariable int attachmentId,String fileName) throws IOException {
    	Attachment att = attachmentService.getAttachmentById(attachmentId);
    	if(att == null){
    		response.setCharacterEncoding("UTF-8");
    		response.setContentType("text/html;charset=UTF-8");
    		response.getWriter().print("非法链接！");
    		return;
    	}
    	File paperFile = new File(att.getStorePath());
    	if(!paperFile.exists()){
    		response.setCharacterEncoding("UTF-8");
    		response.setContentType("text/html;charset=UTF-8");
    		response.getWriter().print("您要下载的文件不存在，请与管理员联系！");
    		return;
    	}
		String agent = request.getHeader("USER-AGENT");
		if(fileName == null || fileName.trim().length() == 0){
			fileName = att.getOriginalName();
		}else{
			fileName = fileName.trim();
			if(!fileName.contains(".") && att.getOriginalName().contains(".")){
				fileName = fileName + att.getOriginalName().substring(att.getOriginalName().lastIndexOf('.'));
			}
		}
		String downLoadName = null;
		if (null != agent && -1 != agent.indexOf("MSIE")){//IE
		  downLoadName = URLEncoder.encode(fileName, "UTF-8");
		} else if (null != agent && -1 != agent.indexOf("Mozilla")){//Firefox
		  downLoadName = new String(fileName.getBytes("UTF-8"),"iso-8859-1");
		} else {//其他浏览器
		  downLoadName = URLEncoder.encode(fileName, "UTF-8");
		}
		response.reset();//可以加也可以不加
		response.setContentType("application/x-download");
        response.setHeader("Content-Disposition", "attachment;filename=" + downLoadName);
    	response.setHeader("Content-Length", att.getFileLength() + "");
    	OutputStream outp = null;
    	FileInputStream in = null;
    	try{
    		outp = response.getOutputStream();
    		in = new FileInputStream(paperFile);
    		IOUtils.copyLarge(in, outp);
    		outp.flush();
    	}catch (Exception e){
    		log.warn("下载文件【id=" + attachmentId + "】出现异常：" + e.getMessage(),e);
    	}finally{
    		General.close(in);
    		General.close(outp);
    	}
    }
	
    @RequestMapping(value = "/preview/{attachmentId}")
    public void preview(HttpServletResponse response,HttpServletRequest request,@PathVariable int attachmentId,String fileName) throws IOException {
    	Attachment att = attachmentService.getAttachmentById(attachmentId);
    	if(att == null){
    		response.setCharacterEncoding("UTF-8");
    		response.setContentType("text/html;charset=UTF-8");
    		response.getWriter().print("非法链接！");
    		return;
    	}
    	File paperFile = new File(att.getStorePath());
    	if(!paperFile.exists()){
    		response.setCharacterEncoding("UTF-8");
    		response.setContentType("text/html;charset=UTF-8");
    		response.getWriter().print("您要下载的文件不存在，请与管理员联系！");
    		return;
    	}
    	if(att.getOriginalName().toLowerCase().endsWith(".docx")){
    		InputStream is = null;
    		try {
        		is = new FileInputStream(paperFile);
        		response.setCharacterEncoding("UTF-8");
        		response.setContentType("text/html;charset=UTF-8");
        		response.getWriter().append(HtmlCreator.covertToHtml(IOUtils.toByteArray(is),att.getOriginalName()));
        		return;
			} catch (Exception e) {
				log.warn("预览文件【id=" + attachmentId + "】出现异常：" + e.getMessage(),e);
			} finally{
				General.close(is);
			}
    	}
		String agent = request.getHeader("USER-AGENT");
		if(fileName == null || fileName.trim().length() == 0){
			fileName = att.getOriginalName();
		}else{
			fileName = fileName.trim();
			if(!fileName.contains(".") && att.getOriginalName().contains(".")){
				fileName = fileName + att.getOriginalName().substring(att.getOriginalName().lastIndexOf('.'));
			}
		}
		String downLoadName = null;
		if (null != agent && -1 != agent.indexOf("MSIE")){//IE
		  downLoadName = URLEncoder.encode(fileName, "UTF-8");
		} else if (null != agent && -1 != agent.indexOf("Mozilla")){//Firefox
		  downLoadName = new String(fileName.getBytes("UTF-8"),"iso-8859-1");
		} else {//其他浏览器
		  downLoadName = URLEncoder.encode(fileName, "UTF-8");
		}
		response.reset();//可以加也可以不加
		response.setContentType("application/x-download");
        response.setHeader("Content-Disposition", "attachment;filename=" + downLoadName);
    	response.setHeader("Content-Length", att.getFileLength() + "");
    	OutputStream outp = null;
    	FileInputStream in = null;
    	try{
    		outp = response.getOutputStream();
    		in = new FileInputStream(paperFile);
    		IOUtils.copyLarge(in, outp);
    		outp.flush();
    	}catch (Exception e){
    		log.warn("下载文件【id=" + attachmentId + "】出现异常：" + e.getMessage(),e);
    	}finally{
    		General.close(in);
    		General.close(outp);
    	}
    }
    
    @RequestMapping(value = "/upload")
    public void upload(HttpServletRequest request,HttpServletResponse response,Integer userId){
    	User user = null;
    	if(userId != null){
    		user = Consts.UserMap.get(userId);
    	}else{
    		user = this.getCurUser(request.getSession());
    	}
    	MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		CommonsMultipartFile file = (CommonsMultipartFile) multipartRequest.getFile("file");
		if(file == null){
			file = (CommonsMultipartFile) multipartRequest.getFile("Filedata");
		}
		InputStream is = null;
		try{
			is = file.getInputStream();
			String fileName = file.getOriginalFilename();
			log.info(user.getName() + "(" + user.getId() + ")" + "上传了：" + fileName);
			Attachment att = attachmentService.storeFile(is, fileName, user.getId());
			att.setStorePath(null);
			Map<String,Object> resultMap = successResult("上传文件：" + fileName + "成功");
			resultMap.put("att", att);
			JSONObject resultJson=new JSONObject();
			resultJson.putAll(resultMap);
			outJsonString(response, resultJson.toString());;
		}catch(Exception e){
			log.error("上传文件失败，原因：" + e.getMessage(), e);
			JSONObject resultJson=new JSONObject();
			resultJson.putAll(failedResult("上传文件失败"));
			outJsonString(response, resultJson.toString());;
		}finally{
			General.close(is);
		}
    }
    
    /**
	 * 上传试卷复审
	 * @param request
	 * @param response
	 */
	@RequestMapping(value = "/uploadReviewAtt/{batchId}", method = {RequestMethod.POST, RequestMethod.GET})
	public void uploadReviewAtt(HttpSession session,HttpServletRequest request,HttpServletResponse response, @PathVariable Integer batchId){
		JSONObject object = new JSONObject();
		
		//上传文件
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		CommonsMultipartFile file = (CommonsMultipartFile) multipartRequest.getFile("file");
		InputStream stream = null;
		OutputStream os = null;
		File zipFile = null;
		try{
			stream = file.getInputStream();
			String fileName = file.getOriginalFilename();
			fileName = new String(fileName.getBytes(), "utf-8");
			
			zipFile = General.newTempFile("zip");
			os = new FileOutputStream(zipFile);
			IOUtils.copyLarge(stream, os);
			os.flush();
			
		}catch(Exception e){
			log.error("附件上传失败，原因：" + e.getMessage(),e);
			object.putAll(failedResult("附件上传失败"));
			outJsonString(response, object.toString());
		}finally{
			General.close(stream);
			General.close(os);
		}
		
		String outPath = zipFile.getAbsolutePath();
		
		try {
			//解压附件
			object = attachmentService.unZipFile(batchId, outPath, getCurUser(session));
			outJsonString(response, object.toString());
		} catch (IOException e) {
			log.error("附件上传失败，原因：" + e.getMessage(),e);
			object = new JSONObject();
			object.putAll(failedResult("附件上传失败"));
			outJsonString(response, object.toString());;
		}
		
	}
	
	
//	/**
//	 * 备份数据库和word文件
//	 * @param request
//	 * @param response
//	 * @return
//	 * @throws IOException
//	 */
//	@RequestMapping(value = "/backup")
//	@ResponseBody
//    public Map<String, Object> backup(){
//		Map<String, Object> resultMap = successResult("备份数据库");
//		String filename = attachmentService.generateFilename();
//		String returnstr = attachmentService.backupDB(filename);
//		attachmentService.backupFile(filename);
//		resultMap.put("opflag", returnstr);
//		return resultMap;
//    }
//
//	/**
//	 * 恢复数据库和word文件
//	 * @param request
//	 * @param response
//	 * @return
//	 * @throws IOException
//	 */
//	@RequestMapping(value = "/restore/{originalName}",method = {RequestMethod.POST})
//	@ResponseBody
//    public Map<String, Object> restore(@PathVariable String originalName){
//		Map<String, Object> resultMap = successResult("恢复数据库");
//		String returnstr = attachmentService.restoreDB(originalName);
//		attachmentService.restoreFile(originalName);
//		resultMap.put("opflag", returnstr);
//		return resultMap;
//    }
//
//	/**
//	 * 备份数据库文件列表
//	 * @param request
//	 * @param response
//	 * @return
//	 * @throws IOException
//	 */
//	@RequestMapping(value = "/backuplist")
//	@ResponseBody
//    public Map<String, Object> backupList(@RequestBody AttachmentQueryParams attachmentQueryParams){
//		Map<String, Object> resultMap = successResult("备份数据库列表");
//		List<Attachment> returnList = attachmentService.getBackupDBAttachment(attachmentQueryParams);
//		int total = attachmentService.getBackupDBAttachmentCount(attachmentQueryParams);
//		resultMap.put("rows", returnList);
//		resultMap.put("total", total);
//		return resultMap;
//    }
    
}
