package kcg.imis.notice.web;

import java.util.HashMap;
import java.util.List;

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

import kcg.imis.notice.service.NoticeService;
import kcg.imis.notice.vo.NoticeSearchVO;
import kcg.imis.notice.vo.NoticeVO;
import kcg.imis.sec.LoginUserVO;
import kcg.imis.sec.UserUtil;

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.SessionAttributes;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springmodules.validation.commons.DefaultBeanValidator;

import egovframework.rte.fdl.property.EgovPropertyService;
import egovframework.rte.fdl.security.userdetails.util.EgovUserDetailsHelper;
import egovframework.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;

/**
 * 
 * @FileName : BoardController.java
 * @Project : 국제해양프로젝트
 * @Date : 2018. 3. 21.
 * @작성자 : Moon
 * @변경이력 :
 * @프로그램 설명 : 게시판 컨트롤러
 */
@Controller
@SessionAttributes(types = NoticeVO.class)
@RequestMapping("/notice")
public class NoticeController {

	/**
	 * EgovPropertyService - properties값을 가져오는 인터페이스.
	 **/
	@Resource(name = "propertiesService")
	private EgovPropertyService propertiesService;

	/**
	 * Validator - 유효성 검사.
	 **/
	@Resource(name = "beanValidator")
	private DefaultBeanValidator beanValidator;

	/**
	 * NoticeService - 게시판 데이터처리에 관한 인터페이스.
	 **/
	@Resource(name = "noticeService")
	private NoticeService noticeService;

	/**
	 * 게시판 목록 화면을 반환한다.
	 *
	 * @param req
	 *            Request 객체
	 * @param searchVO
	 *            검색, 페이지 정보 객체
	 * @param model
	 *            모델 객체
	 * @return 게시판 목록 화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/list.do")
	public String noticeList(final HttpServletRequest req, @ModelAttribute("searchVO") final NoticeSearchVO searchVO, final Model model) throws Exception {

		try {
			/* 페이징 처리 정보 */
			searchVO.setPageUnit(propertiesService.getInt("pageUnit"));
			searchVO.setPageSize(propertiesService.getInt("pageSize"));

			/* 페이징 처리 */
			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 = noticeService.selectListCnt(searchVO);
			paginationInfo.setTotalRecordCount(totSearchCnt);
			model.addAttribute("paginationInfo", paginationInfo);

			/* 게시판 리스트 */
			List<NoticeVO> noticeList = noticeService.selectList(searchVO);
			model.addAttribute("resultList", noticeList);

			/* 게시판 상단 페이지 및 게시물 정보 표현을 위한 데이터 */
			int totCnt = noticeService.selectTotalCnt(searchVO);
			model.addAttribute("totalCnt", totCnt);

		} catch (Exception e) {
			e.printStackTrace();
			return "error/bizError";
		}

		return "notice/noticeList.tiles";

	}

	/**
	 * 게시물의 내용을 확인하는 페이지를 반환한다.
	 * 
	 * @param noticeVO
	 *            게시판 VO
	 * @param model
	 *            모델 객체
	 * @return 게시물 조회 화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/view.do", method = RequestMethod.GET)
	public String noticeView(final NoticeVO noticeVO, final Model model) throws Exception {

		try {
			/* 작성자와 조회자가 다른 경우 조회수 증가 */
			NoticeVO notice = noticeService.select(noticeVO);

			/* 게시판 내용 */
			model.addAttribute("noticeVO", notice);

			/* 세션 사용자 정보 */
			model.addAttribute("loginUserVO", UserUtil.getMemberInfo());
		} catch (Exception e) {
			e.printStackTrace();
			return "error/bizError";
		}

		return "notice/noticeView.tiles";
	}

	/**
	 * 게시물 추가 화면을 반환한다. searchVO
	 * 
	 * @param model
	 *            모델 객체
	 * @param noticeVO
	 *            게시판 VO
	 * @return 게시물 조회 화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/addView.do", method = RequestMethod.GET)
	public String noticeAddView(final Model model) throws Exception {

		NoticeVO modelAttr = new NoticeVO();
		model.addAttribute("noticeVO", modelAttr);
		/* create or modify 플래그 */
		model.addAttribute("registerFlag", "create");

		return "notice/noticeAdd.tiles";

	}

	/**
	 * 게시물을 추가한 후 추가한 게시물 화면으로 이동한다.
	 * 
	 * @param multiRequest
	 *            multpart타입의 요청 객체
	 * @param noticeVO
	 *            게시물 정보 객체
	 * @param bindingResult
	 *            바인딩 객체
	 * @param model
	 *            모델 객체
	 * @param status
	 *            세선 상태 객체
	 * @return 게시물 화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/add.do", method = RequestMethod.POST)
	public String noticeAdd(@ModelAttribute("noticeVO") final NoticeVO noticeVO, final BindingResult bindingResult, final Model model, final SessionStatus status) throws Exception {

		HashMap<String, Object> map = new HashMap<String, Object>();

		/* 인증된 사용자인지 확인 */
		Boolean isAuthenticated = EgovUserDetailsHelper.isAuthenticated();
		if (isAuthenticated) {
			try {

				if (bindingResult.hasErrors()) {
					model.addAttribute("noticeVO", noticeVO);
					return "notice/noticeAdd.tiles";
				}

				/* 사용자 정보 입력 */
				LoginUserVO user = UserUtil.getMemberInfo();
				noticeVO.setNpWriter(user.getUserid());

				map = noticeService.insert(noticeVO);

				status.setComplete();

				int npIdx = (Integer) map.get("npIdx");
				if (npIdx > 0) {
					return "redirect:/notice/list.do";
				}
			} catch (Exception e) {
				e.printStackTrace();
				return "error/bizError";
			}
		}

		return "error/bizError";
	}

	/**
	 * 게시물을 추가한 후 추가한 게시물 화면으로 이동한다.
	 * 
	 * @param noticeVO
	 *            게시판VO 객체
	 * @param model
	 *            모델 객체
	 * @return 게시물 화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/updateView.do", method = RequestMethod.POST)
	public String updateView(final NoticeVO noticeVO, final Model model) throws Exception {

		NoticeVO updateBoard = noticeService.select(noticeVO);
		try {
			/* 글 작성자와 세션 사용자의 아이디를 비교하여 본인여부를 판단한다 */
			if (updateBoard == null || !UserUtil.isEqualMember(updateBoard.getNpWriter()) && !UserUtil.isSysAdmin()) {
				return "redirect:/notice/view.do?npIdx=" + noticeVO.getNpIdx();
			}

			model.addAttribute("noticeVO", updateBoard);
			model.addAttribute("registerFlag", "modify");
		} catch (Exception e) {
			e.printStackTrace();
			return "error/bizError";
		}

		return "notice/noticeAdd.tiles";

	}

	/**
	 * 게시물을 수정한다.
	 * 
	 * @param multiRequest
	 *            multpart타입의 요청 객체
	 * @param noticeVO
	 *            게시물 정보 객체
	 * @param bindingResult
	 *            바인딩 객체
	 * @param model
	 *            모델 객체
	 * @param status
	 *            세선 상태 객체
	 * @return 게시물 화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/update.do", method = RequestMethod.POST)
	public String update(final MultipartHttpServletRequest multiRequest, @ModelAttribute("noticeVO") final NoticeVO noticeVO, final BindingResult bindingResult, final Model model,
			final SessionStatus status) throws Exception {

		try {
			/* 글 작성자와 세션 사용자의 아이디를 비교하여 본인여부를 판단한다 */
			if (!UserUtil.isEqualMember(noticeVO.getNpWriter()) && !UserUtil.isSysAdmin()) {
				return "redirect:/notice/view.do?npIdx=" + noticeVO.getNpIdx();
			}

			if (bindingResult.hasErrors()) {
				model.addAttribute("noticeVO", noticeVO);
				model.addAttribute("registerFlag", "modify");
				return "notice/noticeAdd.tiles";
			}

			HashMap<String, Object> map = new HashMap<String, Object>();

			map = noticeService.update(noticeVO);

			status.setComplete();

			int npIdx = (Integer) map.get("npIdx");
			if (npIdx > 0) {
				return "redirect:/notice/list.do";
			}

		} catch (Exception e) {
			e.printStackTrace();
			return "error/bizError";
		}

		return "redirect:/notice/list.do";
	}

	/**
	 * 게시물을 삭제한다.
	 * 
	 * @param noticeVO
	 *            게시판 VO
	 * @param model
	 *            모델 객체
	 * @param status
	 *            세선 상태 객체
	 * @return 게시물 화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/delete.do", method = RequestMethod.POST)
	public String delete(final NoticeVO noticeVO, final Model model, final SessionStatus status) throws Exception {

		try {
			if (!UserUtil.isEqualMember(noticeVO.getNpWriter()) && !UserUtil.isSysAdmin()) {
				return "redirect:/notice/view.do";
			}

			HashMap<String, Object> map = new HashMap<String, Object>();

			map = noticeService.delete(noticeVO);

			status.setComplete();

			if ((Integer) map.get("result") > 0) {
				return "redirect:/notice/list.do";
			}

		} catch (Exception e) {
			e.printStackTrace();
			return "error/bizError";
		}

		return "redirect:/notice/view.do";
	}

	/**
	 * 게시물을 삭제한다.
	 *
	 * @param bdId
	 *            삭제할 게시판 ID
	 * @param deleteBoard
	 *            모델 객체
	 * @param status
	 *            세선 상태 객체
	 * @return 게시물 화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/selectedDelete.do", method = RequestMethod.POST)
	public String deleteSelected(@RequestParam("id") final String bdId, final int[] deleteBoard, final SessionStatus status) throws Exception {
		/* 관리자만 가능 */
		if (UserUtil.isAdmin()) {
			try {
				/*
				 * NoticeVO noticeVO = NoticeVOHandler.getNoticeVO(bdId, 0); if
				 * (deleteBoard != null) {
				 * noticeService.selectAndDelete(noticeVO, deleteBoard); }
				 */
			} catch (Exception e) {
				e.printStackTrace();
			}
			status.setComplete();
		}
		return "redirect:/notice/list.do";
	}

	@RequestMapping("/popup.do")
	public String loginView(NoticeVO noticeVO, final Model model) throws Exception {

		model.addAttribute("noticeVO", noticeService.select(noticeVO));
		return "notice/noticePop";
	}
}
