package kcg.faics.tg.web;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.Arrays;
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 kcg.faics.cmmn.bbs.BaseBbsService;
import kcg.faics.cmmn.bbs.PageType;
import kcg.faics.cmmn.file.FileResponser;
import kcg.faics.cmmn.service.CodeService;
import kcg.faics.sec.LoginUserVO;
import kcg.faics.sec.UserUtil;
import kcg.faics.tg.FerryRouteType;
import kcg.faics.tg.FerryRunTermType;
import kcg.faics.tg.service.impl.FerryServiceImpl;
import kcg.faics.tg.vo.FerrySearchVO;
import kcg.faics.tg.vo.FerryVO;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.FileCopyUtils;
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.support.SessionStatus;
import org.springframework.web.multipart.MultipartFile;
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;

/**
 * 국제여객선 컨트롤러.
 * 
 * @author kimnomin
 *
 */
@Controller
@RequestMapping("/target/ferry")
public class FerryController {
	/**
	 * properties값을 가져오는 인터페이스.
	 **/
	@Resource(name = "propertiesService")
	private EgovPropertyService propertiesService;

	/**
	 * message.properties의 값을 가져오는 인터페이스.
	 */
	@Autowired
	private MessageSource messageSource;
	
	/**
	 * Validator - 유효성 검사.
	 **/
	@Resource(name = "beanValidator")
	private DefaultBeanValidator beanValidator;

	/**
	 * 코드관련 정보 인터페이스.
	 */
	@Resource(name = "codeService")
	private CodeService codeService;
	
	/**
	 * 국제여객선 비지니스 로직 클래스.
	 */
	@Resource(name = "ferryService")
	private BaseBbsService<FerrySearchVO, FerryVO> ferryService;
	
	/**
	 * Redirect URI를 조합하여 반환한다.
	 * 
	 * @param pageType
	 *            화면구분
	 * @param vo
	 *            국제여객선 VO
	 * @return Redirect URI
	 */
	private String makeRedirectUri(final PageType pageType, final FerryVO vo) {
		String uri = "redirect:/target/ferry";
		
		switch (pageType) {
		case View:
			uri = String.format("%s/view.do?serNo=%s", uri, vo.getSerNo());
			break;
		case List:
			uri = String.format("%s/list.do?route=%s", uri, vo.getFerryRoute());
			break;
		default:
			break;
		}
		
		return uri;
	}
	
	/**
	 * 국제여객선 정보 조회화면을 반환한다.
	 * 
	 * @param model
	 *            Model 객체
	 * @param ferryVO
	 *            국제여객선 VO
	 * @return 국제여객선 정보 조회화면
	 * @throws Exception
	 *             기본 예외 처리 
	 */
	@RequestMapping(value = "/view.do")
	public String view(final Model model, final FerryVO ferryVO) throws Exception {
		LoginUserVO loginUserVO = UserUtil.getMemberInfo();
		model.addAttribute("loginUserVO", loginUserVO);
		
		FerryVO vo = ferryService.select(ferryVO);
		model.addAttribute("ferryVO", vo);
		
		return "/tg/ferryView.tiles";
	}
	
	/**
	 * 국제여객선 목록화면을 반환한다.
	 * 
	 * @param model
	 *            Model 객체
	 * @param locale
	 *            Locale 객체
	 * @param searchVO
	 *            검색조건 VO            
	 * @return 국제여객선 목록화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/list.do")
	public String list(final Model model, final Locale locale,
			@ModelAttribute("searchVO") final FerrySearchVO searchVO)
			throws Exception {
		LoginUserVO loginUserVO = UserUtil.getMemberInfo();
		model.addAttribute("loginUserVO", loginUserVO);
		
		List<FerryRouteType> routeList = Arrays.asList(FerryRouteType.values());
		model.addAttribute("routeList", routeList);
		
		if (StringUtils.isBlank(searchVO.getFerryRoute())) {
			searchVO.setFerryRoute(FerryRouteType.KR_CH.getCode());
		}
		List<FerryVO> ferryList = ferryService.selectList(searchVO);
		model.addAttribute("ferryList", ferryList);
		
		return "/tg/ferryList.tiles";
	}
	
	/**
	 * 국제여객선 입력화면을 반환한다.
	 * 
	 * @param model
	 *            Model 객체
	 * @param ferryVO
	 *            국제여객선 VO
	 * @return 국제여객선 입력화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/add.do")
	public String add(final Model model, final FerryVO ferryVO)
			throws Exception {
		Boolean isAuthenticated = EgovUserDetailsHelper.isAuthenticated();

		if (isAuthenticated && UserUtil.isAdmin()) {
			model.addAttribute("registerFlag", "create");
			
			LoginUserVO loginUserVO = UserUtil.getMemberInfo();
			model.addAttribute("loginUserVO", loginUserVO);
			
			List<FerryRouteType> routeList = FerryRouteType.values(FerryRouteType.KP);
			model.addAttribute("routeList", routeList);
			
			List<FerryRunTermType> runTermList = Arrays.asList(FerryRunTermType.values());
			model.addAttribute("runTermList", runTermList);
			
			ferryVO.setWriter(loginUserVO.getUserid());
			
			return "/tg/ferryAdd.tiles";
		} else {
			return makeRedirectUri(PageType.List, ferryVO);
		}
	}
	
	/**
	 * 국제여객선 정보를 입력한다.
	 *
	 * @param ferryVO
	 *            국제여객선 VO
	 * @param bindingResult
	 *            BindingResult 객체
	 * @param model
	 *            Model 객체
	 * @param status
	 *            SessionStatus 객체
	 * @param multiRequest
	 *            MultipartHttpServletRequest 객체
	 * @return 국제여객선 정보 조회화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/add.do", method = RequestMethod.POST)
	public String add(@ModelAttribute("ferryVO") final FerryVO ferryVO,
			final BindingResult bindingResult, final Model model,
			final SessionStatus status,
			final MultipartHttpServletRequest multiRequest) throws Exception {
		// 사용자 인증 검사
		Boolean isAuthenticated = EgovUserDetailsHelper.isAuthenticated();
		if (isAuthenticated && UserUtil.isAdmin()) {
			// 유효성 검사
			beanValidator.validate(ferryVO, bindingResult);
			if (bindingResult.hasErrors()) {
				return add(model, ferryVO);
			}

			final Map<String, MultipartFile> fileMap = multiRequest.getFileMap();
			HashMap<String, Object> resultMap = ferryService.insert(ferryVO, fileMap);
			
			if ((Integer) resultMap.get("result") == 1) {
				status.setComplete();
				return makeRedirectUri(PageType.View, ferryVO);
			}
		}
		return "error/bizError";
	}
	
	/**
	 * 국제여객선 수정화면을 반환한다.
	 * 
	 * @param ferryVO
	 *            국제여객선 VO
	 * @param model
	 *            Model 객체
	 * @return 국제여객선 수정화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/update.do")
	public String update(final FerryVO ferryVO, final Model model) throws Exception {
		if (UserUtil.isAdmin()) {
			model.addAttribute("registerFlag", "modify");
			
			FerryVO vo = ferryService.select(ferryVO);
			model.addAttribute("ferryVO", vo);
			
			LoginUserVO loginUserVO = UserUtil.getMemberInfo();
			model.addAttribute("loginUserVO", loginUserVO);
			
			List<FerryRouteType> routeList = FerryRouteType.values(FerryRouteType.KP);
			model.addAttribute("routeList", routeList);
			
			List<FerryRunTermType> runTermList = Arrays.asList(FerryRunTermType.values());
			model.addAttribute("runTermList", runTermList);
			
			return "/tg/ferryAdd.tiles";
		}
		
		return makeRedirectUri(PageType.View, ferryVO);
	}
	
	/**
	 * 국제여객선 정보를 수정한다.
	 * 
	 * @param ferryVO
	 *            국제여객선 VO
	 * @param bindingResult
	 *            BindingResult 객체
	 * @param model
	 *            Model 객체
	 * @param status
	 *            SessionStatus 객체
	 * @param multiRequest
	 *            MultipartHttpServletRequest 객체
	 * @return 국제여객선 조회화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/update.do", method = RequestMethod.POST)
	public String update(@ModelAttribute("ferryVO") final FerryVO ferryVO,
			final BindingResult bindingResult, final Model model,
			final SessionStatus status,
			final MultipartHttpServletRequest multiRequest) throws Exception {
		// 사용자 인증 검사
		Boolean isAuthenticated = EgovUserDetailsHelper.isAuthenticated();
		if (isAuthenticated && UserUtil.isAdmin()) {
			// 유효성 검사
			beanValidator.validate(ferryVO, bindingResult);
			if (bindingResult.hasErrors()) {
				return update(ferryVO, model);
			}
			
			String[] deleteFiles = multiRequest.getParameterValues("deleteFile");
			final Map<String, MultipartFile> fileMap = multiRequest.getFileMap();
			HashMap<String, Object> resultMap = ferryService.update(ferryVO, fileMap, deleteFiles);
			
			if ((Integer) resultMap.get("result") > 0) {
				status.setComplete();
				return makeRedirectUri(PageType.View, ferryVO);
			}
		}
		
		return update(ferryVO, model);
	}
	
	/**
	 * 국제여객선 정보를 삭제한다.
	 * 
	 * @param ferryVO
	 *            국제여객선 VO
	 * @param model
	 *            Model 객체
	 * @param status
	 *            SessionStatus 객체
	 * @return 국제여객선 목록화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/delete.do", method = RequestMethod.POST)
	public String delete(final FerryVO ferryVO, final Model model,
			final SessionStatus status) throws Exception {

		if (UserUtil.isAdmin()) {
			FerryVO vo = ferryService.select(ferryVO);
			if (vo != null) {
				HashMap<String, Object> map = ferryService.delete(vo);
				if ((Integer) map.get("result") > 0) {
					return makeRedirectUri(PageType.List, vo);
				}
			}
		}
		
		return makeRedirectUri(PageType.View, ferryVO);
	}
	
	/**
	 * 파일을 반환한다.
	 * 
	 * @param ferryVO
	 *            국제여객선 VO
	 * @param request
	 *            HttpServletRequest 객체
	 * @param response
	 *            HttpServletResponse 객체
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/download.do")
	public void fileResponse(final FerryVO ferryVO,
			final HttpServletRequest request, final HttpServletResponse response)
			throws Exception {
		FerryVO vo = ferryService.select(ferryVO);
		String filename = vo.getImgFile();

		if (StringUtils.isNotBlank(filename)) {
			String fileFullPath = propertiesService
					.getString(FerryServiceImpl.FILE_PATH_KEYWORD) + filename;
			File file = new File(fileFullPath);
			if (file.exists()) {
				FileResponser.setResponse(file, filename, request, response);
				BufferedInputStream in = null;
				try {
					in = new BufferedInputStream(new FileInputStream(file));
					FileCopyUtils.copy(in, response.getOutputStream());
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					if (in != null) {
						try {
							in.close();
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}
			} else {
				response.setStatus(HttpStatus.NOT_FOUND.value());
				throw new Exception();
			}
		}
	}
}
