package com.wechat.controller;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import com.wechat.model.requestDto.*;
import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.docx4j.TraversalUtil;
import org.docx4j.XmlUtils;
import org.docx4j.convert.in.xhtml.FormattingOption;
import org.docx4j.convert.in.xhtml.ImportXHTMLProperties;
import org.docx4j.convert.in.xhtml.XHTMLImporter;
import org.docx4j.convert.in.xhtml.XHTMLImporterImpl;
import org.docx4j.dml.wordprocessingDrawing.Inline;
import org.docx4j.finders.RangeFinder;
import org.docx4j.jaxb.Context;
import org.docx4j.openpackaging.io3.Save;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.WordprocessingML.BinaryPartAbstractImage;
import org.docx4j.openpackaging.parts.WordprocessingML.MainDocumentPart;
import org.docx4j.openpackaging.parts.WordprocessingML.NumberingDefinitionsPart;
import org.docx4j.org.apache.poi.util.IOUtils;
import org.docx4j.wml.Body;
import org.docx4j.wml.CTBookmark;
import org.docx4j.wml.Document;
import org.docx4j.wml.Drawing;
import org.docx4j.wml.ObjectFactory;
import org.docx4j.wml.P;
import org.docx4j.wml.R;
import org.docx4j.wml.RFonts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.wechat.common.CommonHelper;
import com.wechat.common.utils.StringsUtils;
import com.wechat.global.base.dao.PagingResult;
import com.wechat.global.message.InfoMsg;
import com.wechat.model.dto.City;
import com.wechat.model.dto.JobAdvertisedListDto;
import com.wechat.model.dto.JobRepFormDtlDto;
import com.wechat.model.dto.JobRepFormPvDto;
import com.wechat.model.dto.JobViewDateViewDto;
import com.wechat.model.responseDto.DPResp;
import com.wechat.model.responseDto.JobAdvertisedNologinResp;
import com.wechat.model.responseDto.JobFairByHotelResp;
import com.wechat.model.responseDto.JobfairDepdsCitys;
import com.wechat.model.responseDto.LVResp;
import com.wechat.model.responseDto.ResultEntity;
import com.wechat.service.CommonService;
import com.wechat.service.MdeJobAdvertisedService;
import com.wechat.service.PositionService;


/**
 * 职位
 * @author tangwc
 *
 */
@Controller
@RequestMapping("position")
public class PositionController {
	
	@Autowired
	private PositionService positionService;
	
	@Autowired
	private MdeJobAdvertisedService jobAdvertisedService;
	
	@Resource
	private CommonHelper commonHelper;
	
	@Autowired
	private CommonService commonService;
	
	@Value("#{configProperties['upload.base.path']}")
	private String basePackagePath;
	@Value("#{configProperties['upload.path.file']}")
	private String uploadFilePath;
	
	// log 处理
	protected static final Log log = LogFactory.getLog(PositionController.class);
	
	/**
	 * 职位页面初始化
	 * @param userCode
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(method = RequestMethod.GET)
    @ResponseBody
    public ResultEntity<Map<String,Object>> initMainPage(HttpServletRequest request) throws Exception {
		String userCode = commonService.getUserCode(request);
		String lang = commonService.getLanguage(request);
		Map<String,Object> map = positionService.init(userCode,lang);
		
		return new ResultEntity<Map<String,Object>>(InfoMsg.SUCCESS_REQUEST,map);
	}
	
	/**
	 * 获取推荐职位-分页查询
	 * @param userCode
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="getPagingRecommentJobs", method = RequestMethod.POST)
    @ResponseBody
    public ResultEntity<PagingResult<JobAdvertisedListDto>> getPagingRecommentJobs(HttpServletRequest request,@RequestBody PageReq page) throws Exception {
		ResultEntity<PagingResult<JobAdvertisedListDto>> rest = new ResultEntity<PagingResult<JobAdvertisedListDto>>();
		String userCode = commonService.getUserCode(request);

		rest.setResult(positionService.getPagingRecommentJobs(page, userCode));
		
		return rest;
	}
	
	/**
	 * 获取企业邀请数量
	 * @param userCode
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value="getHotelInvitationCount", method = RequestMethod.GET)
    @ResponseBody
    public ResultEntity<Integer> getHotelInvitationCount(HttpServletRequest request) throws Exception {
		String userCode = commonService.getUserCode(request);
		return new ResultEntity<Integer>(InfoMsg.SUCCESS_REQUEST,positionService.getRecievedHotelInvationInfoCounts(userCode));
	}
	
	/**
	 * 职位检索 按照关键词检索
	 * @param searchReq > keyWord index size
	 * @return
	 */
//	@Deprecated
//	@RequestMapping(value="searchPosition", method = RequestMethod.POST)
//    @ResponseBody
//    public ResultEntity<PagingResult<JobAdvertisedListDto>> searchPositionByKeyWord(@RequestBody PositionSearchReq searchReq, HttpServletRequest request){
//		String lang = commonService.getLanguage(request);
//		return new ResultEntity<PagingResult<JobAdvertisedListDto>>(InfoMsg.SUCCESS_REQUEST,positionService.searchPositionByKeyWord(searchReq,lang));
//	}

	/**
	 * @description 职位关键词搜索（用户版）
	 * @author rayson
	 * @param searchReq 职位检索 按照关键词检索
	 * @param request
	 * @date 2023-09-13 14:15
	 * @return ResultEntity<PagingResult<JobAdvertisedListDto>>
	 **/
	@RequestMapping(value="searchPosition", method = RequestMethod.POST)
	@ResponseBody
	public ResultEntity<PagingResult<JobAdvertisedListDto>> searchPositionByKeyWord(@RequestBody KeyWordReq searchReq, HttpServletRequest request){
		return new ResultEntity<PagingResult<JobAdvertisedListDto>>(InfoMsg.SUCCESS_REQUEST,positionService.searchPositionByKeyWord(searchReq,request));
	}

	/**
	 * 职位检索 按条件检索
	 * @param searchReq > position addProvince addCity addArea index size
	 * @return
	 */
	@RequestMapping(value="searchPositionByCondition", method = RequestMethod.POST)
	@ResponseBody
	public ResultEntity<PagingResult<JobAdvertisedListDto>> searchPositionByCondition(@RequestBody PositionSearchReq searchReq, HttpServletRequest request){
		String lang = commonService.getLanguage(request);
		return new ResultEntity<PagingResult<JobAdvertisedListDto>>(InfoMsg.SUCCESS_REQUEST,positionService.searchPositionByCondition(searchReq,lang));
	}
	
	/**
	 * 职位详情
	 * @param jobId 发布职位id
	 * @return
	 */
	@RequestMapping(value="getPositionDetail", method = RequestMethod.GET)
	@ResponseBody
	public ResultEntity<Map<String,Object>> getPositionDetail(@RequestParam Integer jobId,@RequestParam(required=false) String shareJob,HttpServletRequest request){
		String userCode = commonService.getUserCode(request);
		String lang = commonService.getLanguage(request);
		if(jobId==0 && !StringsUtils.isEmpty(shareJob))
		{
			jobId = commonHelper.getJobId(shareJob);
		}
		Map<String, Object> mapResult = positionService.getPositionDetail(jobId,userCode,lang,null);
		//职位id不正确
		if(mapResult == null)
		{
			log.error("有攻击嫌疑！！ip：【"+ commonHelper.getIRealIPAddr(request)+"】");
		} else {
			//记录pv uv
			positionService.recodeJobDtlPvUv(jobId,request);
		}
		return new ResultEntity<Map<String,Object>>(InfoMsg.SUCCESS_REQUEST,mapResult);
	}
	
	/**
	 * 职位PV获取
	 * @param jobId 发布职位id
	 * @return
	 */
	@RequestMapping(value="getPositionPv", method = RequestMethod.GET)
	@ResponseBody
	public ResultEntity<Integer> getPositionPv(@RequestParam Integer jobId,@RequestParam(required=false) String shareJob,HttpServletRequest request){
		if(jobId==0 && !StringsUtils.isEmpty(shareJob))
		{
			jobId = commonHelper.getJobId(shareJob);
		}
		int jobPv = positionService.getPvByJobId(jobId);
		return new ResultEntity<Integer>(InfoMsg.SUCCESS_REQUEST,jobPv);
	}
	
	/**
	 * 职位详情 未登录状态
	 * @param jobId 发布职位id
	 * @return
	 */
	@RequestMapping(value="getDetailNoLogin", method = RequestMethod.GET)
	@ResponseBody
	public ResultEntity<Map<String,Object>> getDetailNoLogin(@RequestParam String shareJob,HttpServletRequest request){
		Integer jobId = commonHelper.getJobId(shareJob);
		String lang = commonService.getLanguage(request);
		Map<String, Object> mapResult = positionService.getPositionDetail(jobId,null,lang,shareJob);
		//职位id不正确
		if(mapResult == null)
		{
			log.error("有攻击嫌疑！！ip：【"+ commonHelper.getIRealIPAddr(request)+"】");
		} else {
			//记录pv uv
			positionService.recodeJobDtlPvUv(jobId,request);
		}

		return new ResultEntity<Map<String,Object>>(InfoMsg.SUCCESS_REQUEST,mapResult);
	}
	
	/**
	 * 职位收藏与取消
	 * @param userCode  jobId 发布职位id
	 * @return
	 */
	@RequestMapping(value="jobCollection", method = RequestMethod.POST)
	@ResponseBody
	public ResultEntity<Integer> jobCollection(@RequestBody JobCollectionReq collection){
		
		return new ResultEntity<Integer>(InfoMsg.SUCCESS_REQUEST,positionService.updateUserJobCollection(collection));
	}
	
	
	/**
	 * 投递简历
	 * @param jobId 发布职位id  curriculumVitae
	 * @return
	 */
	@RequestMapping(value="postCurriculumVitae", method = RequestMethod.POST)
	@ResponseBody
	public ResultEntity<Integer> postCurriculumVitae(@Valid @RequestBody JobCollectionReq collection,HttpServletRequest req){
		int i = positionService.postCurriculumVitae(collection,req);
		if(i == 1) {
			return new ResultEntity<Integer>(InfoMsg.SUCCESS_REQUEST,i);
		}
		return new ResultEntity<Integer>(InfoMsg.ERROR_SAVE_FIELD,i);
		
	}
	
	/**
	 * 创建简历
	 * @param jobId 发布职位id  curriculumVitae
	 * @throws Exception 
	 */
	@RequestMapping(value="makeCV", method = RequestMethod.POST)
	@ResponseBody
	public void makeCV(@RequestParam String html) throws Exception{
	        String baseURL = "C:\\Users\\Administrator\\Desktop";

	        String content = "<html>" +
	                "<head>你好</head>" +
	               "<body>" +
	                 "<table>" +
	                  "<tr>" +
	                   "<td>信息1</td>" +              
	                   "<td>信息2</td>" +              
	                   "<td>t3</td>" +              
	                  "<tr>" +
	                 "</table>" +
	                 "</body>" +
	                 "</html>";

	        
	        String unescaped = html;
	        if (html.contains("&lt;") ) {
	            unescaped = StringEscapeUtils.unescapeHtml(html);
	        }
	        // 设置字体映射
	        RFonts rfonts = Context.getWmlObjectFactory().createRFonts();
	        rfonts.setAscii("Century Gothic");
	        XHTMLImporterImpl.addFontMapping("Century Gothic", rfonts);

	        // 创建一个空的docx对象
	        ImportXHTMLProperties.setProperty("docx4j-ImportXHTML.Element.Heading.MapToStyle", true);
	        WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.createPackage();

	        XHTMLImporter importer = new XHTMLImporterImpl(wordMLPackage);
	        importer.setRunFormatting(FormattingOption.CLASS_PLUS_OTHER);


	        NumberingDefinitionsPart ndp = new NumberingDefinitionsPart();
	        wordMLPackage.getMainDocumentPart().addTargetPart(ndp);
	        ndp.unmarshalDefaultNumbering();

	        // 转换XHTML，并将其添加到我们制作的空docx中
	        XHTMLImporterImpl XHTMLImporter = new XHTMLImporterImpl(wordMLPackage);

	        XHTMLImporter.setHyperlinkStyle("Hyperlink");
	        wordMLPackage.getMainDocumentPart().getContent().addAll(
	                XHTMLImporter.convert(unescaped, basePackagePath+uploadFilePath));
	        wordMLPackage.save(new java.io.File(basePackagePath+uploadFilePath+"test.docx"));
		
	}
	
	@RequestMapping(value="makeCV2", method = RequestMethod.POST)
	@ResponseBody
	public static void main(@RequestParam String img) throws Exception {

        org.docx4j.wml.ObjectFactory foo = Context.getWmlObjectFactory();

        String template = "C:/Users/LENOVO/Desktop/20190623tpl.docx";

        boolean save = true;
        String outputfilepath = "C:/Users/LENOVO/Desktop/test.docx";
        
        String imagePath = "C:/Users/LENOVO/Desktop/1537933417000_11861375768989696_mini.jpg";
        
        // 书签名
        String bookmarkName = "headimg";
        // 载入模板文件
        WordprocessingMLPackage wordMLPackage = WordprocessingMLPackage.load(new java.io.File(template));
        // 提取正文
        MainDocumentPart documentPart = wordMLPackage.getMainDocumentPart();
        Document wmlDoc = (Document) documentPart.getJaxbElement();
        Body body = wmlDoc.getBody();
        // 提取正文中所有段落
        List<Object> paragraphs = body.getContent();
        // 提取书签并创建书签的游标
        RangeFinder rt = new RangeFinder("CTBookmark", "CTMarkupRange");
        new TraversalUtil(paragraphs, rt);

        //需要替换的map
        HashMap<String, String> mappings = new HashMap<String, String>();
        mappings.put("img", img);
        mappings.put("name", "25");
        /*        mappings.put("username", "qlq");*/
        
        
     // 遍历书签
        for (CTBookmark bm : rt.getStarts()) {
            // 这儿可以对单个书签进行操作，也可以用一个map对所有的书签进行处理
            if (bm.getName().equals(bookmarkName)) {
        // 读入图片并转化为字节数组，因为docx4j只能字节数组的方式插入图片
        InputStream is = new FileInputStream(imagePath);
        byte[] bytes = IOUtils.toByteArray(is);
        // 穿件一个行内图片
        BinaryPartAbstractImage imagePart = BinaryPartAbstractImage.createImagePart(wordMLPackage, bytes);

        // createImageInline函数的前四个参数我都没有找到具体啥意思，，，，
        // 最有一个是限制图片的宽度，缩放的依据
        Inline inline = imagePart.createImageInline(null, null, 0, 1, false, 800);
        // 获取该书签的父级段落headimg
        P p = (P) (bm.getParent());

        ObjectFactory factory = new ObjectFactory();
        // R对象是匿名的复杂类型，然而我并不知道具体啥意思，估计这个要好好去看看ooxml才知道
        R run = factory.createR();
        // drawing理解为画布？
        Drawing drawing = factory.createDrawing();
        drawing.getAnchorOrInline().add(inline);
        run.getContent().add(drawing);
        p.getContent().add(run);

            }}

        long start = System.currentTimeMillis();

        documentPart.variableReplace(mappings);

        long end = System.currentTimeMillis();
        long total = end - start;
        System.out.println("Time: " + total);

        // Save it
        if (save) {
        	Save saver = new Save(wordMLPackage);
        	saver.save(new FileOutputStream(outputfilepath));
/*            SaveToZipFile saver = new SaveToZipFile(wordMLPackage);
            saver.save(outputfilepath);*/
        } else {
            System.out.println(XmlUtils.marshaltoString(documentPart.getJaxbElement(), true, true));
        }
    }
	
	
	/**
	 * 获取招聘会信息
	 * @return
	 * @throws UnsupportedEncodingException 
	 */
	@RequestMapping(value="getJobFair", method = RequestMethod.POST)
	@ResponseBody
	public ResultEntity<JobFairByHotelResp> getJobFair(@RequestBody JobFairReq fairReq,HttpServletRequest request) throws UnsupportedEncodingException{
		ResultEntity<JobFairByHotelResp> result = new ResultEntity<JobFairByHotelResp>();
		JobFairByHotelResp hotels = positionService.getJobFairByHotel(fairReq.getFairId());
		//招聘会获取为空
		if(null == hotels)
		{
			result.setMsg(InfoMsg.ERROR_JOBFAIR_OFF);
		}
		result.setResult(hotels);

		return result;
	}
	
	/**
	 * 获取招聘会
			酒店在招职位列表信息
	 * @param usercode 用户id
	 * @return
	 */
	@RequestMapping(value="getFairJobList", method = RequestMethod.GET)
	@ResponseBody
	public ResultEntity<List<JobAdvertisedNologinResp>> getFairJobListByHotel(@RequestParam String shareCode,HttpServletRequest request){
		ResultEntity<List<JobAdvertisedNologinResp>> result = new ResultEntity<List<JobAdvertisedNologinResp>>();
		String code[] = commonHelper.getUserCodeAes(shareCode);
		String userCode= code[0];
		
		List<JobAdvertisedNologinResp> jobList = jobAdvertisedService.getPublishingJobsNologin(userCode);
		//职位列表为空
		if(jobList == null)
		{
			result.setMsg(InfoMsg.ERROR_JOBFAIR_OFF);
		}
		result.setResult(jobList);

		return result;
	}
	
	/**
	 * 获取招聘会参与酒店的
	 *  职位列表信息和城市信息
	 * @return
	 */
	@RequestMapping(value="getJobFairDepdCitys", method = RequestMethod.GET)
	@ResponseBody
	public ResultEntity<JobfairDepdsCitys> getJobFairDepdCitys(@RequestParam Integer fairId,HttpServletRequest request){
		ResultEntity<JobfairDepdsCitys> result = new ResultEntity<JobfairDepdsCitys>();
		List<City> citys = positionService.getJobFairCitys(fairId);
		List<DPResp> depds = positionService.getJobFairDepartments(fairId);
		//招聘会获取为空
		if(citys == null || depds == null || depds.isEmpty() || citys.isEmpty())
		{
			result.setMsg(InfoMsg.ERROR_JOBFAIR_OFF);
		}
		
		JobfairDepdsCitys fairInfo = new JobfairDepdsCitys();
		fairInfo.setCitys(citys);
		fairInfo.setDepds(depds);
		result.setResult(fairInfo);

		return result;
	}
	
	
	/**
	 * 根据时间查询 某企业简历投递数据
	 * @param usercode 用户id
	 * @return
	 */
	@RequestMapping(value="getJobViewByDate", method = RequestMethod.POST)
	@ResponseBody
	public ResultEntity<List<JobRepFormPvDto>> getJobViewByDate(@RequestBody JobReportFormReq req, HttpServletRequest request, HttpServletResponse response) {
		ResultEntity<List<JobRepFormPvDto>> result = new ResultEntity<List<JobRepFormPvDto>>();
		String userCode = commonService.getUserCode(request);
		
		//按时间统计
		List<JobRepFormPvDto> resultList = new ArrayList<JobRepFormPvDto>();
		//统计类型
		String statisticType = req.getStatisticType();
		if(StringsUtils.isEmpty(statisticType) && req.getDayStart() ==null) {
			req.setStatisticType("0");
			statisticType = "0";
		}
		
		//根据集记方式处理起止时间
		JobViewDateViewDto dvDto = positionService.getStrEndDataByType(statisticType,req.getDayStart(),req.getDayEnd());
		
		//按时间集记
		resultList = positionService.findRepFormPvByDate(userCode,dvDto,req.getJobId());

		result.setResult(resultList);
		
		return result;
	}
	
	/**
	 * 根据时间查询 某企业简历投递数据
	 * 总分析图表
	 * @param usercode 用户id
	 * @return
	 */
	@RequestMapping(value="getGeneralJobViewByDate", method = RequestMethod.POST)
	@ResponseBody
	public ResultEntity<Map<String, Integer>> getGeneralJobViewByDate(@RequestBody JobReportFormReq req, HttpServletRequest request, HttpServletResponse response) {
		ResultEntity<Map<String, Integer>> result = new ResultEntity<Map<String, Integer>>();
		String userCode = commonService.getUserCode(request);
		//统计类型
		String statisticType = req.getStatisticType();
		if(StringsUtils.isEmpty(statisticType) && req.getDayStart() ==null) {
			req.setStatisticType("0");
			statisticType = "0";
		}
		
		//根据集记方式处理起止时间
		JobViewDateViewDto dvDto = positionService.getStrEndDataByType(statisticType,req.getDayStart(),req.getDayEnd());
		
		//按时间集记
		Map<String, Integer> resultMap = positionService.findGeneralViewByDate(userCode,dvDto,req.getJobId());

		result.setResult(resultMap);
		
		return result;
	}
	
	/**
	 * 根据时间查询 候选者的学历分步
	 * 总分析图表
	 * @param usercode 用户id
	 * @return
	 */
	@RequestMapping(value="countEducationByDate", method = RequestMethod.POST)
	@ResponseBody
	public ResultEntity<List<LVResp>> countEducationByDate(@RequestBody JobReportFormReq req, HttpServletRequest request, HttpServletResponse response) {
		ResultEntity<List<LVResp>> result = new ResultEntity<List<LVResp>>();
		String userCode = commonService.getUserCode(request);
		//统计类型
		String statisticType = req.getStatisticType();
		if(StringsUtils.isEmpty(statisticType) && req.getDayStart() ==null) {
			req.setStatisticType("0");
			statisticType = "0";
		}
		
		//根据集记方式处理起止时间
		JobViewDateViewDto dvDto = positionService.getStrEndDataByType(statisticType,req.getDayStart(),req.getDayEnd());
		
		//按时间集记
		List<LVResp> resultMap = positionService.countEducationByDate(userCode,dvDto,req.getJobId());

		result.setResult(resultMap);
		
		return result;
	}
	
	/**
	 * 根据时间查询 某企业简历投递数据
	 * 数据列表
	 * @param usercode 用户id
	 * @return
	 */
	@RequestMapping(value="getReportsFormByDate", method = RequestMethod.POST)
	@ResponseBody
	public ResultEntity<List<JobRepFormDtlDto>> getReportsFormByDate(@RequestBody JobReportFormReq req, HttpServletRequest request, HttpServletResponse response) {
		ResultEntity<List<JobRepFormDtlDto>> result = new ResultEntity<List<JobRepFormDtlDto>>();
		String userCode = commonService.getUserCode(request);
		//统计类型
		String statisticType = req.getStatisticType();
		if(StringsUtils.isEmpty(statisticType) && req.getDayStart() ==null) {
			req.setStatisticType("0");
			statisticType = "0";
		}
		
		//根据集记方式处理起止时间
		JobViewDateViewDto dvDto = positionService.getStrEndDataByType(statisticType,req.getDayStart(),req.getDayEnd());
		
		//按时间集记
		List<JobRepFormDtlDto> resultList = positionService.getReportsFormByDate(userCode,dvDto);

		result.setResult(resultList);
		
		return result;
	}
	
}
