package kcg.imis.admin.web;

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

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

import kcg.imis.cmmn.CommConstants;
import kcg.imis.cmmn.excel.ExcelExporter;
import kcg.imis.cmmn.service.CodeService;
import kcg.imis.cmmn.vo.CodeVO;
import kcg.imis.member.service.MemberService;
import kcg.imis.member.vo.MemberSearchVO;
import kcg.imis.member.vo.MemberVO;
import kcg.imis.moniter.service.MoniterService;
import kcg.imis.moniter.vo.MoniterSearchVO;
import kcg.imis.moniter.vo.MoniterVO;
import kcg.imis.sec.LoginSuccessHandler;
import kcg.imis.sec.LoginUserVO;
import kcg.imis.sec.UserUtil;
import kcg.imis.sec.mapper.SecurityMapper;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
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 org.springframework.web.bind.support.SessionStatus;

import egovframework.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;

/**
  * @FileName : AdminController.java
  * @Project : 국제해양프로젝트
  * @Date : 2018. 4. 18. 
  * @작성자 : Moon
  * @변경이력 : 
  * @프로그램 설명 :
 */
@Controller
@RequestMapping("/admin")
public class AdminController {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(AdminController.class);
	
	@Resource(name = "codeService")
	CodeService codeService;
	
	@Resource(name = "memberService")
	MemberService memberService;
	
	@Resource(name = "moniterService")
	MoniterService moniterService;
	
	@RequestMapping(value = "/memberAuth.do")
	public String reportSaveList(final MemberSearchVO searchVO, final Model model) throws Exception{
		
		LoginUserVO user = UserUtil.getMemberInfo();
		
		/* 페이징 처리 정보 */
		searchVO.setPageUnit(20);
		searchVO.setPageSize(15);
		
		/* 페이징 처리 */
		PaginationInfo paginationInfo = new PaginationInfo();
		paginationInfo.setCurrentPageNo(searchVO.getPageIndex());
		paginationInfo.setRecordCountPerPage(searchVO.getPageUnit());
		paginationInfo.setPageSize(searchVO.getPageSize());

		searchVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
		searchVO.setLastIndex(paginationInfo.getLastRecordIndex());
		searchVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
		
		int totSearchCnt = memberService.getMemberListCnt(searchVO);
		paginationInfo.setTotalRecordCount(totSearchCnt);
		model.addAttribute("paginationInfo", paginationInfo);
		
		HashMap<String, Object> result = memberService.getMemberListUserVo(searchVO);
		model.addAttribute("head", result.get("head"));
		model.addAttribute("section", result.get("section"));
		model.addAttribute("resultList", result.get("resultList"));
		model.addAttribute("loginUserVO", user);
		
		String targetPlace1 = searchVO.getPlace1();
		if (StringUtils.isBlank(targetPlace1)) {
			targetPlace1 = user.getPlace1();
		}
		model.addAttribute("targetPlace1", targetPlace1);
		
		List<CodeVO> placeList = codeService.getCodeList(CommConstants.CODE_PLACE1, true);
		model.addAttribute("placeList", placeList);
		
		return "admin/memberAuth.tiles";
	}
	
	/**
	 * 회원 권한을 설정한다.
	 * 
	 * @param memberVO userid, usegrade 정보
	 * @return 결과 : 성공 - 1, 실패 - 0
	 * @throws Exception 기본 예외 처리
	 */
	@ResponseBody
	@RequestMapping(value = "/memberAuth.json")
	public HashMap<String, Object> memberAuth(final MemberVO memberVO) throws Exception {
		HashMap<String, Object> results = new HashMap<String, Object>();
		int result = memberService.updateMemberAuth(memberVO);
		results.put("result", result);
		return results;
	}
	
	/**
	 * 회원 견문권한을 설정한다.
	 * 
	 * @param memberVO userid, usegrade 정보
	 * @return 결과 : 성공 - 1, 실패 - 0
	 * @throws Exception 기본 예외 처리
	 */
	@ResponseBody
	@RequestMapping(value = "/memberRpt.json")
	public HashMap<String, Object> memberRpt(final MemberVO memberVO) throws Exception {
		HashMap<String, Object> results = new HashMap<String, Object>();
		int result = memberService.updateMemberRpt(memberVO);
		results.put("result", result);
		return results;
	}
	
	
	/**
	 * 회원 팀장 권한을 설정한다.
	 * 
	 * @param memberVO userid 정보
	 * @return 결과 : 성공 - 1, 실패 - 0
	 * @throws Exception 기본 예외 처리
	 */
	@ResponseBody
	@RequestMapping(value = "/updateSection.json")
	public HashMap<String, Object> updateSection(final MemberVO memberVO) throws Exception {
		HashMap<String, Object> results = new HashMap<String, Object>();
		int result = memberService.updateSection(memberVO);
		results.put("result", result);
		return results;
	}
	
	/**
	 * 회원 담당관 권한을 설정한다.
	 * 
	 * @param memberVO userid 정보
	 * @return 결과 : 성공 - 1, 실패 - 0
	 * @throws Exception 기본 예외 처리
	 */
	@ResponseBody
	@RequestMapping(value = "/updateHead.json")
	public HashMap<String, Object> updateHead(final MemberVO memberVO) throws Exception {
		HashMap<String, Object> results = new HashMap<String, Object>();
		int result = memberService.updateHead(memberVO);
		results.put("result", result);
		return results;
	}

	
	@Autowired
	private SessionRegistry sessionRegistry;
	@Resource(name="securityMapper")
	private SecurityMapper securityMapper;
	@Resource(name="userService")
	private UserDetailsService securityService;
	@Resource(name="loginSuccessHandler")
	private AuthenticationSuccessHandler successHandler;
	
	/**
	 * 사용자 접속을 해지한다.
	 * 
	 * @param searchVO 검색, 페이지 정보 객체
	 * @param model 모델 객체
	 * @return 접속설정 정보 화면
	 * @throws Exception 기본 예외 처리
	 */
	@RequestMapping("/loginUser.do")
	public void loginUser(final HttpServletRequest request, final HttpServletResponse response, final String userid) throws Exception {
		Authentication authentication = null;
		if (userid != null) {
			authentication = login(userid);
		} else {
			authentication = UserUtil.getCurrentAuthentication();
		}
		successHandler.onAuthenticationSuccess(request, response, authentication);
	}
	
	/**
	 * 해당 아이디로 로그인한다.
	 * 
	 * @param userid 로그인 대상 아이디
	 * @return Authentication 인증정보객체
	 * @throws Exception 기본 예외 처리
	 */
	private final Authentication login(final String userid) {
		Authentication auth = null; 
		try {
			UserDetails user = securityService.loadUserByUsername(userid);
			auth = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
			SecurityContextHolder.getContext().setAuthentication(auth);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return auth;
	}
	
	@RequestMapping("/placeManage.do")
	public String codeManage(final CodeVO codeVO, final Model model) throws Exception {
		
		if (codeVO.getCode() != null) {
			model.addAttribute("code", codeService.getCode(CommConstants.CODE_PLACE1, codeVO.getCode()));
		}
		model.addAttribute("place1List", codeService.getCodeList(CommConstants.CODE_PLACE1));
		
		return "admin/placeManage.tiles";
	}

	@RequestMapping("/memberList.do")
	public String memberList(@ModelAttribute("memberSearchVO") final MemberSearchVO searchVO, final Model model) throws Exception {
		try {
			/* 페이징 처리 정보 */
			searchVO.setPageUnit(20);
			searchVO.setPageSize(15);
			
			/* 페이징 처리 */
			PaginationInfo paginationInfo = new PaginationInfo();
			paginationInfo.setCurrentPageNo(searchVO.getPageIndex());
			paginationInfo.setRecordCountPerPage(searchVO.getPageUnit());
			paginationInfo.setPageSize(searchVO.getPageSize());

			searchVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
			searchVO.setLastIndex(paginationInfo.getLastRecordIndex());
			searchVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
			
			int totSearchCnt = memberService.getMemberListCnt(searchVO);
			paginationInfo.setTotalRecordCount(totSearchCnt);
			model.addAttribute("paginationInfo", paginationInfo);
			
			/* 게시판 상단 페이지 및 게시물 정보 표현을 위한 데이터 */
			int totCnt = memberService.getMemberListAllCnt(searchVO);
			model.addAttribute("totalCnt", totCnt);
			
			model.addAttribute("resultList", memberService.getMemberList(searchVO));
			model.addAttribute("place1List", codeService.getCodeList(CommConstants.CODE_PLACE1));
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "admin/memberList.tiles";
		
	}
	
	@RequestMapping("/memberInfo.do")
	public String memberInfo(final MemberVO memberVO, final Model model) throws Exception {
		try {
			model.addAttribute("memberVO", memberService.getMemberInfo(memberVO.getUserid()));
			model.addAttribute("isAdmin", UserUtil.isAdmin());
			model.addAttribute("isSysAdmin", UserUtil.isSysAdmin());
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "admin/memberInfo.tiles";
	}
	
	@RequestMapping("/memberUpdateView.do")
	public String memberUpdateView(final MemberVO memberVO, final Model model) throws Exception {
		try {
			model.addAttribute("code", codeService.getCodeList(null));
			model.addAttribute("memberVO", memberService.getMemberInfo(memberVO.getUserid()));
			model.addAttribute("isAdmin", UserUtil.isAdmin());
			model.addAttribute("isSysAdmin", UserUtil.isSysAdmin());
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "admin/memberModify.tiles";
	}
	@RequestMapping(value = {"/memberUpdate.do"}, method = RequestMethod.POST)
	public String memberUpdate(@ModelAttribute("memberVO") final MemberVO memberVO,
			final BindingResult bindingResult, final Model model, final SessionStatus status) throws Exception {
		
		try {
			memberService.updateUserInfo(memberVO);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "redirect:/admin/memberInfo.do?userid="+memberVO.getUserid();
	}
	
	// 20180503 신규회원가입 페이지 이동 부분 추가
	@RequestMapping("/memberNewList.do")
	public String memberNewList(final MemberVO memberVO, final Model model) throws Exception {
		
		try {
			model.addAttribute("code", codeService.getCodeList(null));
			//model.addAttribute("memberVO", memberService.getMemberInfo(memberVO.getUserid()));
			//model.addAttribute("isAdmin", UserUtil.isAdmin());
			model.addAttribute("isSysAdmin", UserUtil.isSysAdmin());
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "admin/memberNewList.tiles";
	}
	
	// 20180503 신규회원가입 저장 부분 추가
	@RequestMapping(value = {"/memberNewSave.do"}, method = RequestMethod.POST)
	public String memberNewSave(@ModelAttribute("memberVO") final MemberVO memberVO,
			final BindingResult bindingResult, final Model model, final SessionStatus status) throws Exception {
		
		try {
			memberService.insertUserInfo(memberVO);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "redirect:/admin/memberInfo.do?userid="+memberVO.getUserid();
	}
	
	
	@RequestMapping("/memberListExcel.do")
	public String faMemberListExcel(@ModelAttribute("memberSearchVO") final MemberSearchVO searchVO, final Model model) throws Exception {
		
		String title = "경찰관리";
		
		List<MemberVO> memberList = memberService.getMemberListForExel(searchVO);
		
		LinkedHashMap<String, String> header = new LinkedHashMap<String, String>();
		header.put("place1Str", "소속");
		header.put("place2Str", "세부소속");
		header.put("dutyStr", "계급");
		header.put("name", "성명");
		header.put("userid", "아이디");
		header.put("usegradeStr", "등급");
		
		model.addAttribute("excel", new ExcelExporter<MemberVO>(header, memberList, title));
		model.addAttribute("filename", title);
		
		return "excelView";
	}
	
	

	@RequestMapping("/moniterManage.do")
	public String moniterManage(final Model model) throws Exception {
		try {
			
			model.addAttribute("isAdmin", UserUtil.isAdmin());
			model.addAttribute("isSysAdmin", UserUtil.isSysAdmin());
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "admin/moniterManage.tiles";
	}
	
	
	@ResponseBody
	@RequestMapping(value = "/moniterList.json")
	public List<Map<String, Object>> moniterList(@RequestParam(value="id", required=false) String id) throws Exception {
		return moniterService.getMoniterTreeList();
	}
	
	@ResponseBody
	@RequestMapping(value = "/saveMoniter.json")
	public MoniterVO saveMoniter(MoniterVO vo) throws Exception {
		return moniterService.saveMoniter(vo);
	}
	
	@ResponseBody
	@RequestMapping(value = "/deleteMoniter.json")
	public int deleteMoniterTree(MoniterSearchVO vo) throws Exception {
		return moniterService.deleteMoniterTree(vo);
	}
}
