package kr.co.jinwoosi.clfd.main.web;

import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

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

import kr.co.jinwoosi.clfd.conts.banner.service.BannerService;
import kr.co.jinwoosi.clfd.conts.bod.model.Bod;
import kr.co.jinwoosi.clfd.conts.bod.model.BodArti;
import kr.co.jinwoosi.clfd.conts.bod.model.BodArtiSearch;
import kr.co.jinwoosi.clfd.conts.bod.service.BodArtiService;
import kr.co.jinwoosi.clfd.conts.bod.service.BodRoleService;
import kr.co.jinwoosi.clfd.conts.bod.service.BodService;
import kr.co.jinwoosi.clfd.conts.cont.service.ContItemService;
import kr.co.jinwoosi.clfd.conts.cont.service.ContService;
import kr.co.jinwoosi.clfd.conts.menu.model.Menu;
import kr.co.jinwoosi.clfd.conts.menu.model.MenuConnHist;
import kr.co.jinwoosi.clfd.conts.menu.model.MenuContSearch;
import kr.co.jinwoosi.clfd.conts.menu.service.MenuConnHistService;
import kr.co.jinwoosi.clfd.conts.menu.service.MenuContService;
import kr.co.jinwoosi.clfd.conts.menu.service.MenuService;
import kr.co.jinwoosi.clfd.conts.site.model.Site;
import kr.co.jinwoosi.clfd.conts.site.service.SiteService;
import kr.co.jinwoosi.clfd.framework.util.HttpUtil;
import kr.co.jinwoosi.clfd.framework.util.StrUtil;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
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.servlet.LocaleResolver;
import org.springframework.web.servlet.support.RequestContextUtils;

import kr.co.jinwoosi.clfd.framework.base.web.BaseController;
import kr.co.jinwoosi.clfd.framework.file.model.FileItemSearch;
import kr.co.jinwoosi.clfd.framework.file.service.FileItemService;
import kr.co.jinwoosi.clfd.framework.security.model.User;
import kr.co.jinwoosi.clfd.framework.security.model.UserSearch;
import kr.co.jinwoosi.clfd.framework.security.service.UserService;

@Controller
public class CmsController extends BaseController {

	@Resource (name="siteService")
	private SiteService siteService;
	
	@Resource (name="cmsMenuService")
	private MenuService menuService;
	
	@Resource (name="cmsMenuConnHistService")
	private MenuConnHistService menuConnHistService;
	
	@Resource (name="bodService")
	private BodService bodService;
	
	@Resource (name="bodArtiService")
	private BodArtiService bodArtiService;
	
	@Resource (name="bodRoleService")
	private BodRoleService bodRoleService;
	
	@Resource (name="cmsMenuContService")
	private MenuContService menuContService;
	
	@Resource(name = "contService")
	private ContService contService;
	
	@Resource(name = "contItemService")
	private ContItemService contItemService;
	
	@Resource(name = "userService")
	private UserService userService;
	
	@Resource (name="bannerService")
	private BannerService bannerService;
	
	@Resource (name="fileItemService")
	private FileItemService fileItemService;
		
	@RequestMapping ("/login.do")
	public String login (HttpServletRequest request, HttpServletResponse response, Model model) {
		Site site = getSite(request, response, model);
		model.addAttribute("menuList", menuService.selectJson(site.getSiteId()));
		
		HttpServletRequest httpRequest = (HttpServletRequest)request;
		HttpSession session = httpRequest.getSession();
		session.setAttribute ("loginRequestURL","login");
		
		return "cms/login/login";
	}
	
	/**
	 * 로그인 페이지 이동
	 */
	@RequestMapping ("/{depth1}/login.do")
	public String login (HttpServletRequest request, HttpServletResponse response, @PathVariable String depth1, Model model) {
		Site site = getSite(request, response, model);
		model.addAttribute("menuList", menuService.selectJson(site.getSiteId()));
		
		HttpServletRequest httpRequest = (HttpServletRequest)request;
		HttpSession session = httpRequest.getSession();
		session.setAttribute ("loginRequestURL","login");
		
		return "cms/login/login";
	}
	
	@RequestMapping ("/findPw.do")
	public String findPw (HttpServletRequest request, HttpServletResponse response, Model model) {
		Site site = getSite(request, response, model);
		model.addAttribute("menuList", menuService.selectJson(site.getSiteId()));
		return "cms/login/findPw";
	}
	
	@RequestMapping ("/{depth1}/findPw.do")
	public String findPw (HttpServletRequest request, HttpServletResponse response, @PathVariable String depth1, Model model) {
		Site site = getSite(request, response, model);
		model.addAttribute("menuList", menuService.selectJson(site.getSiteId()));
		return "cms/login/findPw";
	}
	
	@RequestMapping ("/findId.do")
	public String findId (HttpServletRequest request, HttpServletResponse response, Model model) {
		Site site = getSite(request, response, model);
		model.addAttribute("menuList", menuService.selectJson(site.getSiteId()));
		return "cms/login/findId";
	}
	
	@RequestMapping ("/{depth1}/findId.do")
	public String findId (HttpServletRequest request, HttpServletResponse response, @PathVariable String depth1, Model model) {
		Site site = getSite(request, response, model);
		model.addAttribute("menuList", menuService.selectJson(site.getSiteId()));
		return "cms/login/findId";
	}
	
	@RequestMapping ("/{depth1}/terms.do")
	public String terms (HttpServletRequest request, HttpServletResponse response, @PathVariable String depth1, Model model) {
		Site site = getSite(request, response, model);
		model.addAttribute("menuList", menuService.selectJson(site.getSiteId()));
		return "cms/login/terms";
	}
	
	@RequestMapping ("/{depth1}/signUp.do")
	public String signUp (HttpServletRequest request, HttpServletResponse response, @PathVariable String depth1, Model model) {
		Site site = getSite(request, response, model);
		model.addAttribute("menuList", menuService.selectJson(site.getSiteId()));
		return "cms/login/signUp";
	}
	
	@RequestMapping (value="/public/user/duplicate.json", method=RequestMethod.POST) 
	@ResponseBody
	public Map<String, String> checkIdDuplicate (UserSearch userSearch) {
		Map<String, String> result = new HashMap <String, String> ();
		if (userService.checkIdDuplicate(userSearch) > 0) {
			result.put("result", "exist");
			result.put("message", "사용 중입니다.");
		} else {
			result.put("result", "nonExist");
			result.put("message", "사용 가능합니다.");
		}
		return result;
		
	}
	
	@RequestMapping ("/user/insert.do")
	public String userInsert (HttpServletRequest request, HttpServletResponse response, Model model) {
		Site site = getSite(request, response, model);
		model.addAttribute("menuList", menuService.selectJson(site.getSiteId()));
		return "cms/login/insert";
	}
	
	@RequestMapping ("/{depth1}/user/insert.do")
	public String userInsert (HttpServletRequest request, HttpServletResponse response, @PathVariable String depth1, Model model) {
		Site site = getSite(request, response, model);
		model.addAttribute("menuList", menuService.selectJson(site.getSiteId()));
		return "cms/login/insert";
	}
	
	@RequestMapping ("/user/myPage.do")
	public String myPage (HttpServletRequest request, HttpServletResponse response,  Model model) {
		Site site = getSite(request, response, model);
		model.addAttribute("menuList", menuService.selectJson(site.getSiteId()));
		HttpSession session = request.getSession();
		User user = (User) session.getAttribute("user");
		
		UserSearch userSearch = new UserSearch();
		userSearch.setUserId(user.getUserId());
		model.addAttribute("Selectuser", userService.select(userSearch) );
		return "cms/login/myPage";
	}
	
	@RequestMapping ("/{depth1}/user/myPage.do")
	public String myPage (HttpServletRequest request, HttpServletResponse response, @PathVariable String depth1, Model model) {
		Site site = getSite(request, response, model);
		model.addAttribute("menuList", menuService.selectJson(site.getSiteId()));
		
		HttpSession session = request.getSession();
		User user = (User) session.getAttribute("user");
		UserSearch userSearch = new UserSearch();
		userSearch.setUserId(user.getUserId());
		model.addAttribute("Selectuser", userService.select(userSearch) );
		return "cms/login/myPage";
	}
	
	@RequestMapping ("/{depth1}.do")
	public String dynamic (HttpServletRequest request, HttpServletResponse response, @PathVariable String depth1, Model model) {
		if (request != null && response != null && model != null) {
			Site site = getSite(request, response, model);
			model.addAttribute("menuList", menuService.selectJson(site.getSiteId()));
			Menu menu = getMenu(site, request, model);
			model.addAttribute ("menuId", menu.getMenuId ());
			return forwardMenu(site, menu, model, request);
		} else {
			return "";
		}
	}
	
	@RequestMapping ("/{depth1}/{depth2}.do")
	public String dynamic (HttpServletRequest request, HttpServletResponse response, @PathVariable String depth1, @PathVariable String depth2, Model model) {
		if (request != null && response != null && model != null) {
			Site site = getSite(request, response, model);
			model.addAttribute("menuList", menuService.selectJson(site.getSiteId()));
			Menu menu = getMenu(site, request, model);
			model.addAttribute ("menuId", menu.getMenuId ());
			return forwardMenu(site, menu, model, request);
		} else {
			return "";
		}
	}
	
	@RequestMapping ("/{depth1}/{depth2}/{depth3}.do")
	public String dynamic (HttpServletRequest request, HttpServletResponse response, @PathVariable String depth1, @PathVariable String depth2, @PathVariable String depth3, Model model) {
		if (request != null && response != null && model != null) {
			Site site = getSite(request, response, model);
			model.addAttribute("menuList", menuService.selectJson(site.getSiteId()));
			Menu menu = getMenu(site, request, model);
			return forwardMenu(site, menu, model, request);
		} else {
			return "";
		}
	}
	
	@RequestMapping ("/{depth1}/{depth2}/{depth3}/{depth4}.do")
	public String dynamic (HttpServletRequest request, HttpServletResponse response, @PathVariable String depth1, @PathVariable String depth2, @PathVariable String depth3, @PathVariable String depth4, Model model) {
		if (request != null && response != null && model != null) {
			Site site = getSite(request, response, model);
			model.addAttribute("menuList", menuService.selectJson(site.getSiteId()));
			Menu menu = getMenu(site, request, model);
			return forwardMenu(site, menu, model, request);
		} else {
			return "";
		}
	}
	
	@RequestMapping ("/{depth1}/{depth2}/{depth3}/{depth4}/{depth5}.do")
	public String dynamic (HttpServletRequest request, HttpServletResponse response, @PathVariable String depth1, @PathVariable String depth2, @PathVariable String depth3, @PathVariable String depth4, @PathVariable String depth5, Model model) {
		if (request != null && response != null && model != null) {
			Site site = getSite(request, response, model);
			model.addAttribute("menuList", menuService.selectJson(site.getSiteId()));
			Menu menu = getMenu(site, request, model);
			return forwardMenu(site, menu, model, request);
		} else {
			return "";
		}
	}
	
	/**
	 * 현재 접속 한 사이트를 얻어온다.
	 */
	public Site getSite(HttpServletRequest request, HttpServletResponse response, Model model) {
		Site result = null;
		
		if (request != null && response != null && model != null) {
			String servletPath = request.getServletPath();
			String domain = request.getServerName();
			if(request.getServerPort() != 80) {
				domain += ":"+request.getServerPort();
			}
			
			String[] urlArray = servletPath.split("/");
			String contextPath = urlArray[1];
		
			List<Site> siteList = siteService.selectJson();
			
			/* 멀티 사이트 */
			for(Site site : siteList) {
				String[] domainArray = site.getDomain().split(",");
				for(int i=0;i<domainArray.length;i++){
					if(domain.equals(domainArray[i].trim()) && StrUtil.isEmpty(site.getStartUrl())) {
						result = site;
						break;
					}
				}
			}
			
			for(Site site : siteList) {
				String[] domainArray = site.getDomain().split(",");
				for(int i=0;i<domainArray.length;i++){
					/**
					 * 2021-02-15 홍석진
					 * 도메인이 '*' 일때는 도메인 판별 안하도록 변경
					 * 도메인 판별 기능은 보안을 위해 추후 사용
					 * ex) 도청내부에서만 접속 가능하도록 허용시킬 경우
					 *  **/
					if (StringUtils.isEmpty(site.getDomain()) || site.getDomain().equals("*")) {
						if(contextPath.equals(site.getStartUrl())) {
							result = site;
							break;
						}
					} else {
						if(domain.equals(domainArray[i].trim()) && contextPath.equals(site.getStartUrl())) {
							result = site;
							break;
						}
					}
				}
			}
			
			//사이트에 설정 된 언어에 따라 Locale변경
			Locale locale = new Locale(result.getLang().getLangTp());
			LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request);
			localeResolver.setLocale(request, response, locale);
	
			//관련사이트 조회
			//RelSiteSearch relSiteSearch = new RelSiteSearch();
			//relSiteSearch.setSiteId (result.getSiteId ());
			//model.addAttribute ("relSite",relsiteService.selectList(relSiteSearch));
	
			model.addAttribute("currentSite", result);
			model.addAttribute("siteList", siteList);
		}
		return result;
		
	}

	/**
	 * 현재 접속 한 메뉴정보를 얻어온다.
	 */
	public Menu getMenu(Site site, HttpServletRequest request, Model model) {
		Menu menu = null;
		
		if (request != null && model != null) {
			String servletPath = request.getServletPath();
			if(!StrUtil.isEmpty(site.getStartUrl())) servletPath = servletPath.substring(site.getStartUrl().length()+1);
			servletPath = servletPath.replace(".do", "");
			servletPath = servletPath.substring(1);
	
			menu = menuService.selectCurrentMenu(site.getSiteId(), servletPath);
			
			/**
			 * 사이드 메뉴 정보 생성
			 */
			model.addAttribute("sideMenu", menuService.selectParentMenu(site.getSiteId(), menu));
		}
		return menu;
	}

	public String forwardMenu(Site site, Menu menu, Model model, HttpServletRequest request) {
		if (request != null && model != null) {
			model.addAttribute("menu", menu);
			//메뉴 접속 정보 저장
			MenuConnHist menuConnHist = new MenuConnHist();
			menuConnHist.setMenuId(menu.getMenuId());
			menuConnHist.setMenuConnIp(HttpUtil.getClientIp(request));
			menuConnHist.setRegId(getUserId());
			menuConnHistService.insert(menuConnHist); //메뉴 접속 정보 저장
			System.out.println("menu.getMenuTp()=" + menu.getMenuTp());
			
			/**
			 * 메뉴에서 프로그램 정보를 토대로작업
			 * cms/framweork : 지하수홈페이지
			 * obsvsystem : 관측망시스템
			 * */
			
			Menu rootMenu = menu.getRootMenu();
			Menu upperMenu = menu.getUpperMenu();

			String viewName = null;
			String startUrl = site.getStartUrl();

			if (startUrl.equals("front")) {
				// JCMS의 기본 사이트
				viewName = getFrontViewName(menu, site, model, request);
			}

			if (viewName!=null) {
				return viewName;
			}
		}
		return "system/main";
	}

	private String getFrontViewName(Menu menu, Site site, Model model, HttpServletRequest request) {
		if(site.getStartUrl().equals("front")){ //민원

			if("pgm".equals(menu.getMenuTp().trim())){
				if(menu.getUpperMenuId() != null){
					return "front/"+menu.getUpperMenu().getMenuUrl()+"/"+menu.getMenuUrl();
				}else{
					return "front/"+menu.getMenuUrl();
				}
			}
			if("ready".equals(menu.getMenuTp().trim())){
				return "front/preparing";
			}
			if("link".equals(menu.getMenuTp().trim())){
				return  "redirect:"+menu.getLinkUrl();
			}
			if("board".equals(menu.getMenuTp().trim())) { //게시판
				Bod bod = null;
				List<Bod> bodList = bodService.selectJson();
				for(Bod bd : bodList) {
					if(bd.getBodId().compareTo(menu.getBodId()) == 0) {
						bod = bd;
						break;
					}
				}
				model.addAttribute("bod", bod);

				String action = request.getParameter("action");
				if(StrUtil.isEmpty(action)) action = "list";

				if("answ".equals(action)) { //답변
					Long artiId = Long.parseLong(request.getParameter("upperArtiId"));
					BodArtiSearch bodArtiSearch = new BodArtiSearch();
					bodArtiSearch.setArtiId(artiId);
					BodArti upperBodArti = bodArtiService.select(bodArtiSearch);
					model.addAttribute("upperBodArti", upperBodArti);
				}else if("insert".equals(action)) { //등록화면
					model.addAttribute("isAuthNoti", bodService.isAuthNoti(bod.getBodId(), getUserId())); //공지글 게시권한이 있는지 조회
				}else if("view".equals(action) || "update".equals(action)) { //조회, 수정화면
					Long artiId = Long.parseLong(request.getParameter("artiId"));
					BodArtiSearch bodArtiSearch = new BodArtiSearch();
					bodArtiSearch.setArtiId(artiId);
					BodArti bodArti = bodArtiService.select(bodArtiSearch);

					if(bod.getBodTp ().equals ("movie") && action.equals ("view")){
						FileItemSearch fileItemSearch = new FileItemSearch ();
						fileItemSearch.setFileId (bodArti.getFileId ());
						model.addAttribute("file",fileItemService.select (fileItemSearch));
					}

					/*
					 * 비밀글에 대해서 본인여부를 확인한다.
					 */
					if(bodArti.getScrtYn() != null){
						if(bodArti.getScrtYn().equals("Y")) {
							if(!bodArtiService.isAuthScrt(bodArti.getArtiId(), getUserId())) {
								return "cms/error/401";
							}
						}
					}

					model.addAttribute("bodArti", bodArti);
					model.addAttribute("isAuthUpdate", bodArtiService.isAuthUpdate(bodArti, getUserId())); //수정 권한이 있는지 조회
					model.addAttribute("isAuthNoti", bodService.isAuthNoti(bod, getUserId())); //공지글 게시권한이 있는지 조회
					model.addAttribute("isAuthAnsw", bodService.isAuthAnsw(bod, getUserId())); //답변 권한이 있는지 조회

					/*
					 * SNS 공유를 위해 Meta태그 설정
					 */

					String metaImage = "";
					if(request.isSecure()) {
						metaImage += "https://";
					}else {
						metaImage += "http://";
					}

					if("image".equals(bod.getBodTp())) {
						model.addAttribute("metaImage", metaImage+site.getDomain()+"/file/image.do?fileId="+bodArti.getFileId());
					}else if("movie".equals(bod.getBodTp())) {
						model.addAttribute("metaImage", metaImage+site.getDomain()+"/file/movie/preview.do?fileId="+bodArti.getFileId()+"&order="+bodArti.getFilePrview());
					}

					bodArtiService.updateHit(artiId); //조회수 증가
				}else if("list".equals(action)) { //목록
					BodArtiSearch bodArtiSearch = new BodArtiSearch();
					bodArtiSearch.setBodId(bod.getBodId());
					model.addAttribute("artiTotalCnt", bodArtiService.count(bodArtiSearch));

					model.addAttribute("notiList", bodArtiService.selectList(bodArtiSearch));

					model.addAttribute("isAuthInsert", bodService.isAuthInsert(bod, getUserId())); //등록 권한이 있는지 조회
				}

				return "front/bod/"+bod.getBodTp()+"/"+action;
			}

			if("cont".equals(menu.getMenuTp().trim())){
				MenuContSearch menuContSearch = new MenuContSearch();
				menuContSearch.setMenuId(menu.getMenuId());
				//System.out.println("aaa="+menuContService.selectList(menuContSearch, site.getLangId()));
				model.addAttribute("menuContList", menuContService.selectList(menuContSearch, site.getLangId()));
				return "front/cont";
			}

			return "front/main";
		}
		return null;
	}
	
}
