package nlib.sch.web;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
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.regex.Matcher;
import java.util.regex.Pattern;

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

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ModelAttribute;
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 nlib.cmm.Constant;
import nlib.sch.service.CmmVO;
import nlib.sch.util.DataMap;
import egovframework.rte.fdl.cmmn.exception.EgovBizException;
import nlib.cmm.NlibCommonController;
import nlib.cmm.service.CodeService;
import nlib.cmm.service.NlibProperty;
import nlib.cmm.service.PagingVO;
import nlib.col.service.CartService;
import nlib.col.service.CollectionService;
import nlib.col.service.CollectionVO;
import nlib.col.service.InterestService;
import nlib.col.service.RisService;
import nlib.sch.service.NlibSearchService;
import nlib.sch.service.NlibSearchVO;
import nlib.sch.util.NlibCmmUtil;
import nlib.user.service.NlibLoginVO;
import nlib.util.StringUtil;

@Controller
public class NlibSearchController extends NlibCommonController {

    private static final Logger log = LoggerFactory.getLogger(NlibSearchController.class);
    static final String DEFUALT_PAGE_SIZE = NlibProperty.getProperty("list.paging.page.size");
    
    @Resource(name = "cartService")
    private CartService cartService;

    @Resource(name = "codeService") 
	private CodeService codeService;
	
	@Resource(name="risService")
	private RisService risService;

	@Resource(name = "interestService")
	private InterestService interestService;
	
	@Resource(name = "nlibProperty")
    protected NlibProperty nlibProperty;
	
	@Resource(name = "collectionService")
	private CollectionService collectionService;
	
	@Resource(name = "nlibSearchService")
	private NlibSearchService nlibSearchService;
	
	
	/**
	 * 소장자료 화면을 호출한다.
	 * 
	 * @param req
	 * @return
	 */
	@RequestMapping(value = "/search/searchList.do")
	public String searchList(
			HttpServletRequest req
			, Authentication authentication
			, ModelMap model
			, @ModelAttribute("searchVO") NlibSearchVO searchVO
  			, HttpServletRequest request
			, HttpServletResponse res) throws Exception {
		HttpSession session = request.getSession();
		String councilCd = (String)session.getAttribute("councilCd");
		
		//검색엔진파라미터로 문화원코드
		searchVO.setMngOrgCd(councilCd);
		
		List<CollectionVO> operList = new ArrayList();
		// 페이징 사이즈 코드 목록 조회 (DB방식으로 변경 2021.08.06 KNKIM)
		List<Map<String,String>> pageSizeCodes = codeService.listCodes("PAGE_SIZE_OPTION");
		
		if(searchVO.getPageIndex() < 1) searchVO.setPageIndex(1);
		if(searchVO.getPageSize() < 1) searchVO.setPageSize(DEFUALT_PAGE_SIZE);
		
		  	//검색엔진 
	  	try{ 	
	  		searchVO.setQuery(StringUtil.getString(searchVO.getQuery(), ""));
			searchVO.setReQuery(StringUtil.getString(searchVO.getReQuery(), ""));
			
			//결과내재검색만 입력했을경우
			if(searchVO.getQuery().length() == 0 && searchVO.getReQuery().length() > 0)
			{
				searchVO.setQuery(searchVO.getReQuery());
				searchVO.setReQuery("");
				searchVO.setReQueryChk("query");
			}
			
			searchVO = nlibSearchService.getSearch(searchVO);
			
			//페이지 셋팅
			PagingVO pageVO = new PagingVO();
		  	pageVO.setPagingVO(Integer.parseInt(searchVO.getTotalCount()), searchVO.getPageIndex(), searchVO.getPageSize());
		  	
			String mbInfoId = getMbInfoId(request);
			
			if(StringUtil.isEmpty(mbInfoId)) {
				// 검색엔진에서 받아온 masterId로 상세정보 조회
				operList = collectionService.setDetailInfoForList(searchVO.getResultList(), null);
			} else {
				// 검색엔진에서 받아온 masterId로 상세정보 조회
				operList = collectionService.setDetailInfoForList(searchVO.getResultList(), getMbInfoId(request));
			}
			
			//결과 데이터 담기
			searchVO.setResultList(operList);
			
			// 경로
			NlibCmmUtil.setNfsPathModelMap(request,model);
	
			model.addAttribute("pageVO", pageVO);
			model.addAttribute("searchVO", searchVO);
		}catch(Exception e){
			e.printStackTrace();
		}
	  	//주제분야 목록 조회
  		List<Map<String,String>> clsf = codeService.listCtClsfs();
	  	//자료유형
	  	List<Map<String, String>> firstClassList = codeService.listCodes(Constant.CODE_ID_MASTER_TYPE_DIV_CD);
	  	List<Map<String, String>> secondClassList = codeService.listCodes(Constant.CODE_ID_DTLS_TYPE_DIV_CD);
	  	
	  	//검색엔진 주제분야 카운트
	  	List<HashMap<String, String>> subject= searchVO.getSubjectCountList();
	  	List<HashMap<String, String>> type= searchVO.getTypeCountList();
	  	
	  	int count = 0;
	  	// 검색엔진 건수 자료 조합 
	  	for(int i=0; i<clsf.size(); i++) {
	  		count = 0;
	  		for(int j=0; j<subject.size(); j++)
	  		{
	  			if(String.valueOf(clsf.get(i).get("clsfId")).equals(String.valueOf(subject.get(j).get("category_nm"))))
	  			{
	  				count += Integer.parseInt(subject.get(j).get("category_cnt"));
	  			}
	  			if(String.valueOf(clsf.get(i).get("clsfId")).equals(String.valueOf(subject.get(j).get("category_nm_up"))))
	  			{
	  				count += Integer.parseInt(subject.get(j).get("category_cnt"));
	  			}
	  		}
	  		clsf.get(i).put("cnt", Integer.toString(count));	  		
	  	}
	  	
	  	for(int i=0; i<firstClassList.size(); i++) {
	  		count = 0;
	  		for(int j=0; j<type.size(); j++)
	  		{
	  			if(String.valueOf(firstClassList.get(i).get("sCodeId")).equals(String.valueOf(type.get(j).get("class_nm_up"))))
	  			{
	  				count += Integer.parseInt(type.get(j).get("class_cnt"));
	  			}
	  		}
	  		firstClassList.get(i).put("cnt", Integer.toString(count));	  		
	  	}
	  	
	  	for(int i=0; i<secondClassList.size(); i++) {
	  		count = 0;
	  		for(int j=0; j<type.size(); j++)
	  		{
	  			if(String.valueOf(secondClassList.get(i).get("sCodeId")).equals(String.valueOf(type.get(j).get("class_nm"))))
	  			{
	  				count += Integer.parseInt(type.get(j).get("class_cnt"));
	  			}
	  		}
	  		secondClassList.get(i).put("cnt", Integer.toString(count));	  		
	  	}
		// 반환 정보 
	  	model.addAttribute("pageSizeCodes", pageSizeCodes);
	  	//주제분야
	  	model.addAttribute("firstCategoryList", clsf);
	  	model.addAttribute("secondCategoryList", clsf);
	  	//자료유형
  		model.addAttribute("firstClassList", firstClassList);
  	    model.addAttribute("secondClassList", secondClassList);
  	    
		searchVO.setQuery(searchVO.getQuery().replaceAll("\\\"", "&quot;"));
		return "nlib/collection/searchList";
	}
		
	/**
	 * 자료상세조회 및 원문보기시에 로그 
	 * @param req
	 * @param authentication
	 * @param paramMap
	 * @param model
	 * @param searchVO
	 * @param request
	 * @param res
	 */
	@RequestMapping(value = "/search/InsertDataInquiryLog.ajax")
	@ResponseBody
	public void InsertDataInquiryLog(HttpServletRequest req
			, Authentication authentication
			, @RequestParam Map<String, String> paramMap
			, ModelMap model
			, @ModelAttribute("searchVO") NlibSearchVO searchVO
  			, HttpServletRequest request
			, HttpServletResponse res
			) throws Exception {
		HttpSession session = request.getSession();
		
		String masterId = request.getParameter("masterId");
		String mbInfoId = getMbInfoId(request);
		String councilCd = (String)session.getAttribute("councilCd");
		
		CollectionVO colVO = new CollectionVO();
		
		colVO.setMasterId(masterId);
		colVO.setMbInfoId(StringUtil.getString(mbInfoId,""));
		colVO.setMngOrgCd(councilCd);
		
		collectionService.insertDataInquiryLog(colVO);
	}
			
	/**
	 * 소장자료 상세조회
	 * 
	 * @param req
	 * @return
	 */
	@RequestMapping(value = "/search/searchItemDetail.do")
	public String searchItemDetail(
			HttpServletRequest req
			, Authentication authentication
			, @RequestParam Map<String, String> paramMap
			, ModelMap model
			, @ModelAttribute("searchVO") NlibSearchVO searchVO
  			, HttpServletRequest request
			, HttpServletResponse res
			) throws Exception {
		HttpSession session = request.getSession();
		String masterId = request.getParameter("masterId");
		List<String> mngOrgList = new ArrayList<>(); 
		List<String> keywordList = new ArrayList<>(); 
		
		CollectionVO vo = new CollectionVO();
		vo.setMasterId(masterId);
		
		vo = collectionService.getItemInfo(vo);

		if(vo == null)
		{
			model.addAttribute("msg", "해당 자료를 조회할 수 없습니다.\\n관리자에게 문의하여 주시기 바랍니다.");
			model.addAttribute("url","/search/searchList.do");
			return "nlib/cmm/alert";
		}
		
		String councilCd = (String)session.getAttribute("councilCd"); 
		vo.setMngOrgCd(councilCd);
		//함께 볼만한 자료
		List<CollectionVO> seeTogetherListVO = collectionService.selectSeeTogetherList(vo);
		//유사한 자료
		List<CollectionVO> similarListVO = collectionService.selectSimilarList(vo);
		
		//관리부서명 중복 제외하고 리스트생성
		for(int i=0; similarListVO.size() > i; i++)
		{
			if(!mngOrgList.contains(similarListVO.get(i).getDeptNm()))
			{
				mngOrgList.add(similarListVO.get(i).getDeptNm());
			}
		}
		
		model.addAttribute("seeTogetherListVO", seeTogetherListVO);
		model.addAttribute("similarListVO", similarListVO);
		model.addAttribute("mngOrgList",mngOrgList);
		//반납예정일 편집
		if(!(vo == null) && !StringUtil.getString(vo.getRtnExpctDd(),"").equals(""))
		{
			String strDate = vo.getRtnExpctDd();
			SimpleDateFormat dtFormat = new SimpleDateFormat("yyyyMMdd");
			SimpleDateFormat newDtFormat = new SimpleDateFormat("yyyy-MM-dd");
			Date formatDate = dtFormat.parse(strDate);
			String strNewDtFormat = newDtFormat.format(formatDate); 
			vo.setRtnExpctDd(strNewDtFormat);
		}
		//키워드 편집
		if(!(vo == null) && !StringUtil.getString(vo.getKeyword(),"").equals(""))
		{
			String keyword_arr[] = vo.getKeyword().replace(',',';').split(";");
			
			for(int i = 0; keyword_arr.length > i; i++)
			{
				keywordList.add(keyword_arr[i]);
			}
		}
		//목차 편집
		if(!(vo == null) && !StringUtil.getString(vo.getBookIndex(),"").equals(""))
		{
			String bookIndex = vo.getBookIndex();
			bookIndex = bookIndex.replace("---","-");
			
			if(bookIndex.indexOf("***") != -1)
			bookIndex = bookIndex.substring(0, bookIndex.indexOf("***"));
			
			vo.setBookIndex(bookIndex);
		}
		model.addAttribute("keywordList",keywordList);
		model.addAttribute("result", vo);
		model.addAttribute("searchVO", searchVO);
		return "nlib/collection/searchItemDetail";
	}
	
	/**
     * YOURLS의 API를 통해서 단축URL 가져오기 
     * @param cmmVO
     * @param model
     * @param commandMap
     * @param req
     * @param res
     * @return
     * @throws EgovBizException
     */
    @RequestMapping(value="/search/shorturl-data.do")
    @ResponseBody
   	public String shorturl (
   			@ModelAttribute("cmmVO") CmmVO cmmVO
   			, ModelMap model
   			, HttpServletRequest req
			, HttpServletResponse res
   			) throws EgovBizException  {
    	String returnUrl = "";
    	DataMap paramMap = DataMap.getParamMap(req);
    	try {
    		String originUrl = URLEncoder.encode(paramMap.getString("url"), "UTF-8");
			URL url = new URL( NlibProperty.getProperty("shorturl.api") + "&action=shorturl&format=xml&title=nculture&url=" + originUrl);
			HttpURLConnection con = (HttpURLConnection) url.openConnection(); 
			con.setRequestMethod("GET");
			//con.setRequestProperty("Authorization", header);
            int responseCode = con.getResponseCode();
            BufferedReader br;
            if(responseCode==200) { // 정상 호출
                br = new BufferedReader(new InputStreamReader(con.getInputStream()));
            } else {  // 에러 발생
                br = new BufferedReader(new InputStreamReader(con.getErrorStream()));
            }
            
            String inputLine;
            StringBuffer response = new StringBuffer();
            while ((inputLine = br.readLine()) != null) {
                response.append(inputLine);
            }
            br.close();
						
			String str = response.toString();
			Pattern pattern = Pattern.compile("<shorturl>(.+?)</shorturl>");
			Matcher matcher = pattern.matcher(str);
			while (matcher.find()) {
				returnUrl = matcher.group(1);  		    
			    if(matcher.group(1) ==  null){
			    	break;
			    }
			}
		} catch (Exception e) {
			System.err.println(e.toString());
		}
    	return returnUrl;
   	}
	/**
	 * 상세검색 팝업.
	 *  
	 * (2021.10.19 YJS 추가)
	 * 
	 * @param request
	 * @param model
	 * @return
	 * @throws Exception 
	 */
	@RequestMapping(value="/search/getDetailedSearchFormPopup.do")
	public String getDetailedSearchFormPopup(HttpServletRequest request, ModelMap model) throws Exception {
		
		//주제분야 목록 조회
		List<Map<String,String>> clsf = codeService.listCtClsfs();
  		model.addAttribute("firstCategoryList", clsf);
  		model.addAttribute("secondCategoryList", clsf);

  		//자료유형
  		model.addAttribute("firstClassList", codeService.listCodes(Constant.CODE_ID_MASTER_TYPE_DIV_CD));
  	    model.addAttribute("secondClassList", codeService.listCodes(Constant.CODE_ID_DTLS_TYPE_DIV_CD));
  	    
    	
        return "nlib/search/getDetailedSearchFormPopup";
	}
	
}
