package com.qmth.qrzk.web.controller;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.zip.ZipException;

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

import net.sf.json.JSONObject;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.io.FileUtils;
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.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.qmth.qrzk.repository.constants.WebConstants;
import com.qmth.qrzk.repository.service.query.CodeBookLogParams;
import com.qmth.qrzk.repository.service.query.SuffixParams;
import com.qmth.qrzk.repository.user.model.CodeBook;
import com.qmth.qrzk.repository.user.model.CodeBookLog;
import com.qmth.qrzk.repository.user.model.Suffix;
import com.qmth.qrzk.repository.user.model.User;
import com.qmth.qrzk.repository.user.service.ICodeBookLogService;
import com.qmth.qrzk.repository.user.service.ICodeBookService;
import com.qmth.qrzk.repository.user.service.ISuffixService;
import com.qmth.qrzk.repository.util.zip.ZipUtil;
import com.qmth.qrzk.repository.utils.CompressZIP;
import com.qmth.qrzk.repository.utils.FileTool;
import com.qmth.qrzk.repository.utils.MySQLDump;
import com.qmth.qrzk.repository.utils.ServerConfig;
import com.qmth.qrzk.repository.utils.StringUtils;
import com.qmth.qrzk.repository.utils.excel.PasswordExcelUtil;

@Controller
@RequestMapping("/examSetting")
public class ExamSettingController extends BaseAjaxController {

	private static final String BASE_JSP_PATH = "examPaper/";

	@Autowired
	private ISuffixService suffixService;

	@Autowired
	@Qualifier("codeBookServiceImpl")
	private ICodeBookService codeBookService;

	@Autowired
	@Qualifier("codeBookLogServiceImpl")
	private ICodeBookLogService codeBookLogService;
	
	@Autowired
	private BasicDataSource dataSource;

	@RequestMapping(value = "/querySuffix")
	@ResponseBody
	public Map<String, Object> queryUsers(SuffixParams params) {
		Map<String, Object> result = new HashMap<String, Object>();
		List<Suffix> suffixs = suffixService.querySuffix(params);
		int total = suffixService.querySuffixCount(params);
		result.put("rows", suffixs);
		result.put("total", total);
		return result;
	}

	@RequestMapping("/setting")
	public ModelAndView setting() {
		ModelAndView view = new ModelAndView(BASE_JSP_PATH + "setting");
		return view;
	}

	@RequestMapping("/backups")
	public ModelAndView backups() {
		ModelAndView view = new ModelAndView(BASE_JSP_PATH + "backups");
		return view;
	}

	@RequestMapping("/delSuffix")
	public void delSuffix(HttpServletRequest request,
			HttpServletResponse response, @RequestBody Suffix suffix) {
		int flag = suffixService.delSuffix(suffix.getId());
		JSONObject object = new JSONObject();
		if (flag == 0) {
			object.put("result", "fail");
			this.outJsonString(response, object.toString());
		} else {
			object.put("result", "success");
			this.outJsonString(response, object.toString());
		}
	}

	@RequestMapping("/saveSuffix")
	public void saveSuffix(HttpServletRequest request,
			HttpServletResponse response, @RequestBody Suffix suffix) {
		List<Suffix> list = suffixService.findByName(suffix.getSuffix());
		int flag = list.size();
		JSONObject object = new JSONObject();
		if (flag == 0) {
			suffixService.addSuffix(suffix.getSuffix());
			object.put("result", "success");
			this.outJsonString(response, object.toString());
		} else {
			object.put("result", "fail");
			this.outJsonString(response, object.toString());
		}
	}

	@RequestMapping("/pswSetting")
	public ModelAndView pswSetting() {
		ModelAndView view = new ModelAndView(BASE_JSP_PATH + "pswSetting");
		return view;
	}

	@RequestMapping(value = "/queryLog")
	@ResponseBody
	public Map<String, Object> queryLog(CodeBookLogParams params) {
		Map<String, Object> result = new HashMap<String, Object>();
		List<CodeBookLog> list = codeBookLogService.queryAllLog(params);
		//int count = codeBookService.getCount();
//		for (int i = 0; i < list.size(); i++) {
//			if (i == 0) {
//				list.get(i).setSurplus(count);
//			} else {
//				list.get(i).setSurplus(0);
//			}
//		}
		int total = codeBookLogService.queryAllLogCount(params);
		result.put("rows", list);
		System.out.println("----->>>>>" + list);
		result.put("total", total);
		System.out.println("----->>>>>" + total);
		return result;
	}

	@RequestMapping("/validateCodeBook")
	public void validateCodeBook(HttpServletResponse response) {
		JSONObject object = new JSONObject();
		int result = codeBookService.getCount();
		if (result > 0) {
			object.put("canBackup", true);
		} else {
			object.put("canBackup", false);
		}
		this.outJsonString(response, object.toString());
	}

	@RequestMapping(value = "/addCodeBook")
	public void addCodeBook(HttpSession session, HttpServletRequest request,
			HttpServletResponse response, @RequestBody CodeBookLog codeBookLog) {
		// 添加之前先删除前面所有的CodeBook
		codeBookService.deleteCodeBook(null);

		JSONObject object = new JSONObject();
		codeBookLog.setCreateTime(new Date());
		User user = (User) session.getAttribute(WebConstants.WEB_SESSION_USER);
		codeBookLog.setCreateBy(user.getName());
		int result = codeBookLogService.addLog(codeBookLog);
		if (result > 0) {
			List<CodeBook> list = new ArrayList<CodeBook>();
			for (int i = 0; i < codeBookLog.getCodeNum(); i++) {
				CodeBook codeBook = new CodeBook();
				codeBook.setRandomCode(StringUtils.getStringByDate(new Date())
						+ StringUtils.getRandomSimpleString(6));
				codeBook.setPassword(StringUtils.getRandomComplexString(14));
				list.add(codeBook);
			}
			codeBookService.insertCodeBook(list);
			object.put("result", "success");
		} else {
			object.put("result", "fail");
		}
		this.outJsonString(response, object.toString());
	}

	@RequestMapping("/downPasswordExcel")
	public void downPasswordExcel(HttpServletRequest request,
			HttpServletResponse response) {
		PasswordExcelUtil excelUtil = new PasswordExcelUtil();
		Map<String, CodeBook> map = new HashMap<String, CodeBook>();
		List<CodeBook> list = codeBookService.getAllCodeBook();
		for (CodeBook p : list) {
			map.put(String.valueOf(p.getId()), p);
		}
		try {
			excelUtil.render(map, request, response);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@RequestMapping("/backupSys")
	public void backupSys(HttpServletRequest request,HttpServletResponse response) {
		String paperPath = ServerConfig.getInstance().getWorkInfo().getProperty("URL");
		
		String user = dataSource.getUsername();
		String pwd = dataSource.getPassword();
		String[] dbUrl = dataSource.getUrl().split("\\?")[0].split("/"); // jdbc:mysql://localhost:3306/qrzk_jk
		String dbName = dbUrl[dbUrl.length-1];
		String host = dbUrl[dbUrl.length-2].split(":")[0];
		String port = dbUrl[dbUrl.length-2].split(":")[1];
		
		String mysqlDumpStr = "mysqldump -h" + host + " -P" + port +  " -u" + user + " -p" + pwd + " "
								+ dbName;

		SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmm");
		String zipName = formatter.format(new Date()) + ".zip";

		String backupPath = paperPath + "/backup/";
		String sqlPath = paperPath + "/paper/backup.sql";
		String randomPath = backupPath + "random.txt";

		try {
			// 根据配置的mysql信息生成相应的备份数据库文件backup.sql至指定的目录
			File f = new File(backupPath);
			if (!f.exists()) {
				f.mkdir();
			}
			MySQLDump.sqlDump(mysqlDumpStr, sqlPath);

			// 将paper目录下的所有文件进行加密打包
			List<CodeBook> codeBooks = codeBookService.getAllCodeBook();
			Random random = new Random(codeBooks.size());
			int index = random.nextInt(codeBooks.size());
			CodeBook codeBook = codeBooks.get(index);

			ZipUtil z = new ZipUtil();

			try {
				z.compress(paperPath + "paper", backupPath + "backup.zip",
						codeBook.getPassword(), true);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			File file = new File(randomPath);
			if (!file.exists()) {
				try {
					file.createNewFile();
					FileUtils.writeStringToFile(file,"随机码:" + codeBook.getRandomCode());
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			CompressZIP.fileToZip(backupPath, paperPath + "download/", zipName); // 打包成zip包
			codeBookService.deleteCodeBook(codeBook);
		} catch (Exception e) {

		} finally {
			FileTool.delAllFile(backupPath); // 删除zip文件夹所有文件
			FileTool.deletefile(sqlPath);
//			FileTool.downLoad(response, paperPath + "download/", zipName); // 下载试卷
//			FileTool.delAllFile(paperPath + "download/");
		}
		
		JSONObject object = new JSONObject();
		object.put("zipFileName", zipName);
		this.outJsonString(response, object.toString());
	}
	
	@RequestMapping("/downloadBackupFile/{zipFileName}")
	public void downloadBackupFile(HttpServletResponse response, @PathVariable String zipFileName){
		String paperPath = ServerConfig.getInstance().getWorkInfo().getProperty("URL");
		FileTool.downLoad(response, paperPath + "download/", zipFileName+".zip"); // 下载试卷
		FileTool.delAllFile(paperPath + "download/");
	}

	@RequestMapping("/restoreSys")
	public void restoreSys(HttpServletRequest request,HttpServletResponse response) {
		JSONObject object = new JSONObject();
		String realPath = ServerConfig.getInstance().getWorkInfo().getProperty("URL");
		MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
		CommonsMultipartFile file = (CommonsMultipartFile) multipartRequest.getFile("file");
		String fileName = file.getOriginalFilename();
		String path = realPath + "zip/";

		FileTool.deletefile(path + "random.txt");
		FileTool.deletefile(path + "backup.zip");
		// 将上传文件存放到zip文件夹下
		FileTool.writeFile(file, path, fileName);
		// 解压zip文件夹下的解压包
		CompressZIP.unZipFiles(path + fileName, path);
		// 删除掉上传的zip包
		FileTool.deletefile(path + fileName);
		// 获取random.txt的随机码
		File randomFile = new File(path + "random.txt");
		String randomCode = null;
		try {
			String content = FileUtils.readFileToString(randomFile, "UTF-8");
			randomCode = content.split(":")[1];
		} catch (IOException e) {
			e.printStackTrace();
		}
		object.put("randomCode", randomCode);
		this.outJsonString(response, object.toString());
	}

	@RequestMapping("/continueRestoreSys")
	public void continueRestoreSys(HttpServletRequest request,HttpServletResponse response,@RequestBody CodeBook codeBook) {
		JSONObject object = new JSONObject();
		String realPath = ServerConfig.getInstance().getWorkInfo().getProperty("URL");
		String path = realPath + "zip/";
		String password = codeBook.getPassword();
		boolean zipResult = true;
		try {
			ZipUtil z = new ZipUtil();
			try {
				z.uncompress(path + "backup.zip", path, password, true);
			} catch (ZipException e) {
				object.put("success", false);
				object.put("message", "解压失败,请确认解压密码是否正确。");
				zipResult = false;
				e.printStackTrace();
			}
			
			if(zipResult){
				// 根据sql文件还原数据库
				String user = dataSource.getUsername();
				String pwd = dataSource.getPassword();
				String[] dbUrl = dataSource.getUrl().split("\\?")[0].split("/"); // jdbc:mysql://localhost:3306/qrzk_jk
				String dbName = dbUrl[dbUrl.length-1];
				String host = dbUrl[dbUrl.length-2].split(":")[0];
				String port = dbUrl[dbUrl.length-2].split(":")[1];
				
				String mysqlLoadStr = "mysql -h" + host + " -P" + port +  " -u" + user + " -p" + pwd + " --default-character-set=utf8 "
										+ dbName;
				MySQLDump.sqlLoad(mysqlLoadStr, path + "backup.sql");
				FileTool.deletefile(path + "backup.sql");
				File ff = new File(realPath + "zip/");
				File[] files = ff.listFiles();
				for (File f : files) {
					if (f.isDirectory()) {
						FileTool.copyFolder(f.getAbsolutePath(), realPath
								+ "paper/" + f.getName() + "/");
						FileTool.delFolder(f.getAbsolutePath());
					}
				}
				object.put("success", true);
			}
		} catch (Exception e) {
			object.put("success", false);
		} finally {
			if(zipResult){
				FileTool.delFolder(path);
			}
			this.outJsonString(response, object.toString());
		}
	}
}
