package com.bonus.gs.sub.evaluate.outsourceEnterprise.controller;


import com.bonus.gs.sub.evaluate.manager.controller.BaseController;
import com.bonus.gs.sub.evaluate.manager.utils.AesCbcUtils;
import com.bonus.gs.sub.evaluate.manager.utils.AjaxRes;
import com.bonus.gs.sub.evaluate.manager.utils.GlobalConst;
import com.bonus.gs.sub.evaluate.manager.utils.POIOutputHelperNumBer;
import com.bonus.gs.sub.evaluate.outsourceEnterprise.beans.ImportUserDataVo;
import com.bonus.gs.sub.evaluate.outsourceEnterprise.beans.ViolationBean;
import com.bonus.gs.sub.evaluate.outsourceEnterprise.dao.ViolationDao;
import com.bonus.gs.sub.evaluate.outsourceEnterprise.service.ViolationService;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * @author Lenovo
 */
@Controller
@RequestMapping("/backstage/violations/")
public class ViolationController extends BaseController<ViolationBean> {

	@Autowired
	private ViolationService service;
	@Autowired
	private ViolationDao dao;


	@GetMapping("outsourceEnterpriseByPage")
	@ResponseBody
	public AjaxRes outsourceEnterpriseByPage(ViolationBean o){
		AjaxRes ar = getAjaxRes();
		List<ViolationBean> list = service.getOutsourceEnterpriseByPage(o);
		ar.setListSucceed(list);
		return ar;
	}


	/**
	 * 添加外包企业
	 * @param o
	 * @return
	 */
	@RequestMapping(value = "addOutsourceEnterprise", method = RequestMethod.POST)
	@ResponseBody
	public AjaxRes addOutsourceEnterprise(@RequestBody ViolationBean o) {
		ViolationBean pmBean = AesCbcUtils.decryptAllStringFields(o);
		AjaxRes ar = getAjaxRes();
		try {
			ar = service.addOutsourceEnterprise(pmBean);
		} catch (Exception e) {
			e.printStackTrace();
			ar.setFailMsg("添加外包企业失败!");
		}
		return ar;
	}

	@RequestMapping(value = "formValidation", method = RequestMethod.POST)
	@ResponseBody
	public AjaxRes formValidation(@RequestBody ViolationBean o) {

		AjaxRes ar = getAjaxRes();
		try {
			int count = dao.formValidation(o.getEnterpriseName(), o.getId());
			if (count > 0) {
				ar.setSucceed('"' + o.getEnterpriseName() + '"' + "已存在,请重新输入!");
				ar.setRes(2);
			} else {
				ar.setSucceed("名称可用!");
			}
		} catch (Exception e) {
			logger.error(e.toString(), e);
			ar.setFailMsg("名称查重错误,请软件管理员!");
		}
		return ar;
	}


	/**
	 * 外包企业表单复现
	 * @param model
	 * @return
	 */
	@RequestMapping("toViewOutsourceEnterprise")
	public String toViewOutsourceEnterprise(Model model, ViolationBean o) {
		try {
			o = service.toViewOutsourceEnterprise(o);
			model.addAttribute("user", o);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "/outsourceEnterprise/outsourceEnterpriseFrom";
	}

	/**
	 * 修改外包企业
	 * @param o
	 * @return
	 */
	@RequestMapping(value = "updateOutsourceEnterprise", method = RequestMethod.POST)
	@ResponseBody
	public AjaxRes updateOutsourceEnterprise(@RequestBody ViolationBean o) {
		ViolationBean pmBean = AesCbcUtils.decryptAllStringFields(o);
		AjaxRes ar = getAjaxRes();
		try {
			ar = service.updateOutsourceEnterprise(pmBean);
		} catch (Exception e) {
			e.printStackTrace();
			ar.setFailMsg("修改外包企业失败!");
		}
		return ar;
	}

	/**
	 * 删除外包企业
	 * @param id
	 * @return
	 */
	@RequestMapping("outsourceEnterpriseDelete")
	@ResponseBody
	public AjaxRes outsourceEnterpriseDelete(String id) {
		AjaxRes ar = getAjaxRes();
		try {
			String[] idArr = id.split(",");
			int result = service.outsourceEnterpriseDelete(idArr);
			if(result > 0) {
				ar.setRes(GlobalConst.SUCCEED);
				ar.setResMsg("删除成功");
			}else {
				ar.setFailMsg(GlobalConst.DATA_FAIL);
				ar.setResMsg("删除失败,请联系系统管理员");
			}

		}catch(Exception e) {
			logger.error(e.toString(), e);
			ar.setFailMsg(GlobalConst.DATA_FAIL);
		}
		return ar;
	}

	@RequestMapping("getOutsourceEnterpriseById")
	@ResponseBody
	public AjaxRes getOutsourceEnterpriseById(String id) {
		AjaxRes ar = getAjaxRes();
		try {
			ViolationBean o = new ViolationBean();
			o.setId(id);
			ViolationBean result = service.toViewOutsourceEnterprise(o);
			ar.setSucceed(result);

		}catch(Exception e) {
			logger.error(e.toString(), e);
			ar.setFailMsg(GlobalConst.DATA_FAIL);
		}
		return ar;
	}

	@RequestMapping("exportOutsourceEnterprise")
	public void exportOutsourceEnterprise(HttpServletRequest request, HttpServletResponse response, ViolationBean bean) {
		String filename = "外包公司详情表";
		List<ViolationBean> gradelist = service.exportOutsourceEnterprise(bean);
		// 导出所有人员基本信息
		try {
			excelOut(response, gradelist, filename, "外包公司详情表");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	@RequestMapping(value = "toLeadInto", method = RequestMethod.POST)
	@ResponseBody
	public AjaxRes toLeadInto(@RequestParam("file") MultipartFile file) {
		AjaxRes ar = getAjaxRes();
		AjaxRes ars = getAjaxRes();
		Integer result = 0;
		int errorNum = 0;
		Map<String,ImportUserDataVo> map=new HashMap<String,ImportUserDataVo>();
		try {
			String fileName = file.getOriginalFilename();
			System.out.println("OriginalFilename：" + fileName);
			if (!StringUtils.endsWithAny(fileName, ".xls", ".xlsx")) {
				throw new RuntimeException("不支持excel以外的文件导入！");
			}
			//根据指定的文件输入流导入Excel从而产生Workbook对象
			Workbook wb = null;
			Sheet hssfSheet = null;
			InputStream inputStream = file.getInputStream();
			if (fileName.endsWith(".xls")) {
				// 处理xls格式的Excel
				POIFSFileSystem poifsFileSystem = new POIFSFileSystem(inputStream);
				wb = new HSSFWorkbook(poifsFileSystem);
			} else if (fileName.endsWith(".xlsx")) {
				// 处理xlsx格式的Excel
				wb = new XSSFWorkbook(inputStream);
			}
			// 读取第一个sheet
			hssfSheet = wb.getSheetAt(0);
			// 判断Sheet是否为空
			if (hssfSheet != null) {
				// 遍历行row，continue只是终止本次循环，接着还执行后面的循环
				int rowNum = hssfSheet.getLastRowNum();
				// 从第三行开始
				for (int rownum = 2; rownum <= rowNum; rownum++) {
					// 获取到每一行
					errorNum = rownum;
					Row sheetRow = hssfSheet.getRow(rownum);

					// 获得第i行对象
					Row row = hssfSheet.getRow(rownum);
					if (sheetRow != null && !isRowEmpty(sheetRow)) {
						// 先去判断
						ars = compareSaveData(sheetRow, rownum + 1,map);
						if (ars.getRes() == 2) {
							ar.setFailMsg(ars.getResMsg());
							result = 2;
							return ar;
						}
					}
				}
				if (result != 2) {
					for (int rownums = 2; rownums <= rowNum; rownums++) {
						Row sheetRows = hssfSheet.getRow(rownums);
						if (sheetRows != null && !isRowEmpty(sheetRows)) {
							ar = addSaveData(sheetRows,rownums+1);
							if (ar.getRes() == 0) {
								return ar;
							}
						}
					}
					if (ar.getRes() == 1) {
						ar.setSucceedMsg("外包公司导入成功!");
						return ar;
					}
				}else {
					ar.setFailMsg("第" + (errorNum-1) + "行数据有误字段不能为空，导入失败");
				}
			}
			if (wb != null) {
				wb.close();
			}
		} catch (Exception e) {
			logger.error(e.toString(), e);
			ar.setFailMsg("模板错误，请重新选择模板！");
		}
		return ar;
	}

	private AjaxRes compareSaveData(Row sheetRow, int rownum,Map<String,ImportUserDataVo> map) throws Exception {
		AjaxRes ar = getAjaxRes();
		try {
			String enterpriseName = getValue(sheetRow.getCell(0)).trim();
			String socialCreditCode = translateToPlainStr(getValue(sheetRow.getCell(1)).trim()).replace(".0", "");
			String setTime = getValue(sheetRow.getCell(2)).trim();
			String corporateName = getValue(sheetRow.getCell(3)).trim();
			String idCard = getValue(sheetRow.getCell(4)).trim();
			String phone = translateToPlainStr(getValue(sheetRow.getCell(5)).trim());
			if (StringUtils.isBlank(enterpriseName) || StringUtils.isBlank(socialCreditCode) || StringUtils.isBlank(setTime) || StringUtils.isBlank(corporateName) || StringUtils.isBlank(idCard) || StringUtils.isBlank(phone)) {
				ar.setFailMsg("第" + (rownum-1) + "行数据有误字段不能为空，导入失败");
				ar.setRes(2);
				return ar;
			}
			ImportUserDataVo importUserDataVo=new ImportUserDataVo();
			importUserDataVo.setName(enterpriseName);
			Integer num=service.getImportDataCheck(importUserDataVo);
			if (num!=null && num>0) {
				ar.setFailMsg("第" + (rownum-1) + "行企业名称已存在");
				ar.setRes(2);
				return ar;
			}
			importUserDataVo=new ImportUserDataVo();
			importUserDataVo.setUserPhone(phone);
			 num=service.getImportDataCheck(importUserDataVo);
			if (num!=null && num>0) {
				ar.setFailMsg("第" + (rownum-1) + "手机号已存在");
				ar.setRes(2);
				return ar;
			}
			importUserDataVo=new ImportUserDataVo();
			importUserDataVo.setIdCard(idCard);
			num=service.getImportDataCheck(importUserDataVo);
			if (num!=null && num>0) {
				ar.setFailMsg("第" + (rownum-1) + "身份证号码已存在");
				ar.setRes(2);
				return ar;
			}
			importUserDataVo=new ImportUserDataVo();
			importUserDataVo.setCode(socialCreditCode);
			num=service.getImportDataCheck(importUserDataVo);
			if (num!=null && num>0) {
				ar.setFailMsg("第" + (rownum-1) + "统一社会信用代码已存在");
				ar.setRes(2);
				return ar;
			}

			importUserDataVo.setRow(rownum-1);
			ImportUserDataVo his=map.get(socialCreditCode);
			if(his!=null){
				ar.setFailMsg("第" + (rownum-1) + "行与"+his.getRow()+"行统一社会信用代码重复!");
				ar.setRes(2);
				return ar;
			}else{
				map.put(socialCreditCode,importUserDataVo);
			}

			his=map.get(idCard);
			if(his!=null){
				ar.setFailMsg("第" + (rownum-1) + "行与"+his.getRow()+"行身份证号码重复!");
				ar.setRes(2);
				return ar;
			}else{
				map.put(idCard,importUserDataVo);
			}

			his=map.get(phone);
			if(his!=null){
				ar.setFailMsg("第" + (rownum-1) + "行与"+his.getRow()+"行手机号重复!");
				ar.setRes(2);
			}else{
				map.put(idCard,importUserDataVo);
			}

		} catch (Exception e) {
			logger.error(e.toString(), e);
			ar.setFailMsg("第" + rownum + "行数据有误，导入失败");
		}
		return ar;
	}

	private AjaxRes addSaveData(Row sheetRow,int row) throws Exception {
		AjaxRes ar = getAjaxRes();
		try {
			ViolationBean bean = new ViolationBean();
			String enterpriseName = getValue(sheetRow.getCell(0)).trim();
			String socialCreditCode = translateToPlainStr(getValue(sheetRow.getCell(1)).trim()).replace(".0", "");
			String setTime = getValue(sheetRow.getCell(2)).trim();
			String corporateName = getValue(sheetRow.getCell(3)).trim();
			String idCard = getValue(sheetRow.getCell(4)).trim();
			String phone = translateToPlainStr(getValue(sheetRow.getCell(5)).trim());
			bean.setEnterpriseName(enterpriseName);
			bean.setSocialCreditCode(socialCreditCode);
			bean.setSetTime(setTime);
			bean.setCorporateName(corporateName);
			bean.setIdCard(idCard);
			bean.setPhone(phone);
			ar=service.updateShopBaseInfo(bean,row);
		} catch (Exception e) {
			logger.error(e.toString(), e);
			ar.setFailMsg(GlobalConst.IMP_FAIL);
		} finally {
		}
		return ar;
	}

	/*****************************************************************人员违章详情记录******************************************************/


	@RequestMapping("exportSubpageList")
	public void exportSubpageList(HttpServletRequest request, HttpServletResponse response, ViolationBean bean) {
		String filename = "人员违章记录表";
		List<ViolationBean> gradelist = service.exportSubpageList(bean);
		// 导出所有人员基本信息
		try {
			excelOut(response, gradelist, filename, "人员违章记录表");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


	/*****************************************************************公共方法******************************************************/

	// 判断该行是否为空
	public static boolean isRowEmpty(Row row) {
		int count = 0;
		for (int c = row.getFirstCellNum(); c < row.getLastCellNum(); c++) {
			Cell cell = row.getCell(c);
			if (cell != null && cell.getCellType() != Cell.CELL_TYPE_BLANK) {
				count++;
			}
		}
		if (count >= 1) { // 表示是有效数据行
			return false;
		}
		return true;
	}

	private static String getValue(Cell hssfCell) {
		if (hssfCell == null) {
			return "";
		}

		CellType cellType = CellType.forInt(hssfCell.getCellType());

		switch (cellType) {
			case BOOLEAN:
				return String.valueOf(hssfCell.getBooleanCellValue());
			case NUMERIC:
				// 处理日期和时间
				if (DateUtil.isCellDateFormatted(hssfCell)) {
					return new SimpleDateFormat("yyyy-MM-dd").format(hssfCell.getDateCellValue());
				} else {
					return String.valueOf(hssfCell.getNumericCellValue());
				}
			case STRING:
				return String.valueOf(hssfCell.getStringCellValue());
			case BLANK:
				return "";
			case ERROR:
				return "ERROR";
			default:
				// 处理未来可能添加的新单元格类型
				throw new IllegalArgumentException("Unsupported cell type: " + cellType);
		}
	}

	public String translateToPlainStr(String number) {
		String regEx="^([\\+|-]?\\d+(.{0}|.\\d+))[Ee]{1}([\\+|-]?\\d+)$";
		// 编译正则表达式
		Pattern pattern = Pattern.compile(regEx);
		// 忽略大小写的写法
		// Pattern pat = Pattern.compile(regEx, Pattern.CASE_INSENSITIVE);
		Matcher matcher = pattern.matcher(number);
		// 字符串是否与正则表达式相匹配
		boolean rs = matcher.matches();
		// 判断是否为字符串的科学计数法
		if(rs){
			// 科学计数法转数字
			BigDecimal originValue = new BigDecimal(number);
			// 数字转字符串
			return originValue.toPlainString();
		}
		return number;
	}

	private void excelOut(HttpServletResponse response, List<ViolationBean> registlist, String filename, String sheetname)
			throws Exception {
		if (registlist != null) {
			List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
			int size = registlist.size();
			for (int i = 0; i < size; i++) {
				ViolationBean bean = registlist.get(i);
				Map<String, Object> maps = outVehicleOilBeanMap(i, bean, sheetname);
				results.add(maps);
			}
			List<String> headers = outVehicleOilHeaders(sheetname);
			HSSFWorkbook workbook = POIOutputHelperNumBer.excel(results, headers, filename);
			OutputStream out = null;
			response.setContentType("application/vnd.ms-excel;charset=UTF-8");
			response.addHeader("Content-Disposition",
					"attachment;filename=" + URLEncoder.encode(filename, "UTF-8") + ".xls");
			response.setHeader("Pragma", "No-cache");
			out = response.getOutputStream();
			workbook.write(out);
			out.flush();
			out.close();
		}
	}

	private Map<String, Object> outVehicleOilBeanMap(int i, ViolationBean bean, String sheetname) {
		Map<String, Object> maps = new LinkedHashMap<String, Object>();
		maps.put("id", i + 1);
		switch (sheetname) {
			case "违章详情表":
				maps.put("violator", bean.getViolator());
				maps.put("violationNumber", bean.getViolationNumber());
				maps.put("typeViolation", bean.getTypeViolation());
				maps.put("violationLevel", bean.getViolationLevel());
				maps.put("personInCharge", bean.getPersonInCharge());
				maps.put("penaltyScore", bean.getPenaltyScore());
				maps.put("affiliatedEnterprise", bean.getAffiliatedEnterprise());
				maps.put("jointLiability", bean.getJointLiability());
				maps.put("jointPenaltyScore", bean.getJointPenaltyScore());
				maps.put("illegalContent", bean.getIllegalContent());
				maps.put("inspector", bean.getInspector());
				maps.put("inspectorUnit", bean.getInspectorUnit());
				maps.put("inspectionTime", bean.getInspectionTime());
				break;
			case "黑名单详情表":
				maps.put("userName", bean.getUserName());
				maps.put("idCard", bean.getIdCard());
				maps.put("sex", bean.getSex());
				maps.put("phone", bean.getPhone());
				maps.put("unit", bean.getUnit());
				maps.put("reason", bean.getReason());
				maps.put("enterTime", bean.getEnterTime());
				maps.put("operatorId", bean.getOperatorId());
				maps.put("createTime", bean.getCreateTime());
				break;
			case"外包公司详情表":
				maps.put("enterpriseName", bean.getEnterpriseName());
				maps.put("socialCreditCode", bean.getSocialCreditCode());
				maps.put("setTime", bean.getSetTime());
				maps.put("corporateName", bean.getCorporateName());
				maps.put("idCard", bean.getIdCard());
				maps.put("phone", bean.getPhone());
				maps.put("proNum", bean.getProNum());
				break;
			case"人员违章记录表":
				maps.put("name", bean.getName());
				maps.put("sex", bean.getSex());
				maps.put("idCard", bean.getIdCard());
				maps.put("phone", bean.getPhone());
				maps.put("deptName", bean.getDeptName());
				maps.put("inThoseDays", bean.getInThoseDays());
				maps.put("deductionOfPoints", bean.getDeductionOfPoints());
				maps.put("violationCount", bean.getViolationCount());
				break;
			default:
				break;
		}

		return maps;
	}

	private List<String> outVehicleOilHeaders(String sheetname) {
		ArrayList<String> list = new ArrayList<String>();
		list.add("序号");

		switch (sheetname) {
			case "违章详情表":
				list.add("违章单位");
				list.add("违章编号");
				list.add("违章类型");
				list.add("违章级别");
				list.add("直接负责人");
				list.add("处罚记分");
				list.add("所属企业");
				list.add("连带责任人");
				list.add("连带责任人处罚记分");
				list.add("违章内容");
				list.add("检查人员");
				list.add("检查人员单位");
				list.add("检查时间");
				break;
			case "黑名单详情表":
				list.add("姓名");
				list.add("身份证号码");
				list.add("性别");
				list.add("联系电话");
				list.add("所属部门/项目");
				list.add("加入黑名单原因");
				list.add("进入日期");
				list.add("操作人");
				list.add("操作时间");
				break;
			case"外包公司详情表":
				list.add("企业名称");
				list.add("统一社会信用代码");
				list.add("成立日期");
				list.add("法人姓名");
				list.add("法人身份证号码");
				list.add("法人手机号码");
				list.add("项目数量");
				break;
			case"人员违章记录表":
				list.add("姓名");
				list.add("性别");
				list.add("身份证号码");
				list.add("联系电话");
				list.add("所属部门");
				list.add("记分年");
				list.add("剩余记分");
				list.add("违章次数");
				break;
			default:
				break;
		}
		return list;
	}





}

