package kcg.faics.tg.web;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import kcg.faics.cmmn.file.FileResponser;
import kcg.faics.cmmn.service.CodeService;
import kcg.faics.cmmn.vo.CodeVO;
import kcg.faics.sec.LoginUserVO;
import kcg.faics.sec.UserUtil;
import kcg.faics.tg.service.WeakPlaceService;
import kcg.faics.tg.vo.WeakPlaceSearchVO;
import kcg.faics.tg.vo.WeakPlaceVO;

import org.apache.commons.io.FilenameUtils;
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.ui.ModelMap;
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/weakplace")
public class WeakPlaceController {
	/**
	 * properties값을 가져오는 인터페이스.
	 **/
	@Resource(name = "propertiesService")
	private EgovPropertyService propertiesService;

	/**
	 * message.properties의 값을 가져오는 인터페이스.
	 */
	@Autowired
	private MessageSource messageSource;

	/**
	 * 코드관련 정보 인터페이스.
	 */
	@Resource(name = "codeService")
	private CodeService codeService;

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

	/**
	 * 외사취약지 비지니스 로직 클래스.
	 */
	@Resource(name = "weakPlaceService")
	private WeakPlaceService weakPlaceService;

	/**
	 * 외사취약지 조회 화면을 반환한다.
	 * 
	 * @param vo
	 *            검색할 외사취약지 VO
	 * @param model
	 *            Model 객체
	 * @return 외사취약지 조회 화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/view.do")
	public String view(final WeakPlaceVO vo, final ModelMap model)
			throws Exception {
		
		LoginUserVO loginUserVO = UserUtil.getMemberInfo();
		model.addAttribute("loginUserVO", loginUserVO);
		
		WeakPlaceVO weakPlaceVO = weakPlaceService.select(vo);
		model.addAttribute("weakPlaceVO", weakPlaceVO);
		
		String filename1Ext = "";
		String filename1 = weakPlaceVO.getFilename1();
		if (!StringUtils.isBlank(filename1)) {
			filename1Ext = FilenameUtils.getExtension(filename1).toLowerCase();
		}
		model.addAttribute("filename1Ext", filename1Ext);

		return "/tg/weakPlaceView.tiles";
	}
	
	/**
	 * 외사취약지 목록 화면을 반환한다.
	 *
	 * @param searchVO
	 *            검색정보 VO
	 * @param model
	 *            Model 객체
	 * @return 외사취약지 목록화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/list.do")
	public String list(@ModelAttribute("searchVO") final WeakPlaceSearchVO searchVO,
			final ModelMap model) throws Exception {
		
		LoginUserVO loginUserVO = UserUtil.getMemberInfo();
		model.addAttribute("loginUserVO", loginUserVO);
		
		List<CodeVO> placeList = codeService.getPlace1List(CodeService.POLICE_STATION_LIST);
		model.addAttribute("placeList", placeList);		
		
		List<HashMap<String, Object>> statsPerPlace = weakPlaceService.selectStatsPerPlace();
		model.addAttribute("statsPerPlace", statsPerPlace);		
		
		List<WeakPlaceVO> weakPlaceList = weakPlaceService.selectList(searchVO);
		model.addAttribute("weakPlaceList", weakPlaceList);
		
		Date today = new Date();
		SimpleDateFormat simpleDate = new SimpleDateFormat("yyyy. MM. dd.");
		String todayStr = simpleDate.format(today);
		model.addAttribute("today", todayStr);
		
		
		return "/tg/weakPlaceList.tiles";
	}
	
	/**
	 * 외사취약지 입력화면을 반환한다.
	 * 
	 * @param model
	 *            Model 객체
	 * @param weakPlaceVO
	 *            입력할 외사취약지 VO
	 * @return 외사취약지 입력화면
	 * @throws Exception
	 *             기본예외처리
	 */
	@RequestMapping(value = "/add.do")
	public String add(final Model model, final WeakPlaceVO weakPlaceVO) throws Exception {
		LoginUserVO loginUserVO = UserUtil.getMemberInfo();
		WeakPlaceVO vo;
		if (weakPlaceVO == null) {
			vo = new WeakPlaceVO();
		} else {
			vo = weakPlaceVO;
		}
		vo.setWriter(loginUserVO.getUserid());
		vo.setPlace1(loginUserVO.getPlace1());
		vo.setPlace1str(loginUserVO.getPlace1Str());

		List<CodeVO> placeList = codeService.getPlace1List(CodeService.POLICE_STATION_LIST);
		
		int tempWpNo = 0;
		String tempPlace1Code = "";
		HashMap<String, Integer> wpNoMap = new HashMap<String, Integer>();
		for (int i = 0; i < CodeService.POLICE_STATION_LIST.length; i++) {
			tempWpNo = 0;
			tempPlace1Code = CodeService.POLICE_STATION_LIST[i];
			tempWpNo = weakPlaceService.selectMaxWpNo(tempPlace1Code);
			wpNoMap.put(tempPlace1Code, ++tempWpNo);
			
			// 중앙부처 사용자는 placeList의 첫번째 기관의 wpno 값을 기본으로 한다.
			if ("PS00".equalsIgnoreCase(vo.getPlace1())
					&& tempPlace1Code.equalsIgnoreCase(placeList.get(0).getCode2())) {
				vo.setWpNo(tempWpNo);
			} else if (tempPlace1Code.equalsIgnoreCase(vo.getPlace1())) {
				vo.setWpNo(tempWpNo);
			}
		}
		model.addAttribute("wpNoMap", wpNoMap);
		
		model.addAttribute("placeList", placeList);	
		model.addAttribute("weakPlaceVO", vo);
		model.addAttribute("loginUserVO", "loginUserVO");
		model.addAttribute("registerFlag", "create");
		
		return "/tg/weakPlaceAdd.tiles";
	}
	
	/**
	 * 외사취약지 정보를 입력한다.
	 * 
	 * @param multiRequest
	 *            mutipartform 객체
	 * @param weakPlaceVO
	 *            외사취약지 VO
	 * @param bindingResult
	 *            유효성 검사결과 객체
	 * @param model
	 *            모델 객체
	 * @param status
	 *            SessionStatus 객체
	 * @return 외사취약지 조회 화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/add.do", method = RequestMethod.POST)
	public String add(final MultipartHttpServletRequest multiRequest,
			@Valid @ModelAttribute("weakPlaceVO") final WeakPlaceVO weakPlaceVO,
			final BindingResult bindingResult, final Model model,
			final SessionStatus status) throws Exception {
		// 사용자 인증 검사
		Boolean isAuthenticated = EgovUserDetailsHelper.isAuthenticated();
		if (isAuthenticated) {
			// 유효성 검사
			beanValidator.validate(weakPlaceVO, bindingResult);
			if (bindingResult.hasErrors()) {
				model.addAttribute("weakPlaceVO", weakPlaceVO);
				model.addAttribute("registerFlag", "create");
				return "tg/weakPlaceAdd.tiles";
			}
			
			// 파일 저장 및 데이터 입력
			final Map<String, MultipartFile> fileMap = multiRequest.getFileMap();
			HashMap<String, Object> map = weakPlaceService.insert(weakPlaceVO, fileMap);
			
			status.setComplete();
			
			if ((Integer) map.get("result") == 1) {
				return String.format("redirect:/target/weakplace/view.do?place1=%s&wpNo=%s", map.get("place1"), map.get("wpNo"));
			}
		}
		
		return "error/bizError";
	}
	
	/**
	 * 외사취약지 수정화면을 반환한다.
	 * 
	 * @param model
	 *            Model 객체
	 * @param weakPlaceVO
	 *            외사취약지 VO
	 * @return 외사취약지 수정화면
	 * @throws Exception
	 *             기본예외처리
	 */
	@RequestMapping(value = "/update.do", method = RequestMethod.GET)
	public String update(final Model model, final WeakPlaceVO weakPlaceVO) throws Exception {
		LoginUserVO loginUserVO = UserUtil.getMemberInfo();
		
		// 관리자만 수정 가능
		if (loginUserVO.getAuthAdmin() == 1) {
			WeakPlaceVO vo = weakPlaceService.select(weakPlaceVO);
			model.addAttribute("weakPlaceVO", vo);
			model.addAttribute("loginUserVO", loginUserVO);
			model.addAttribute("registerFlag", "modify");
			
			return "/tg/weakPlaceAdd.tiles";
		}
		
		return "redirect:/target/weakplace/view.do?place1="
				+ weakPlaceVO.getPlace1() + "&wpNo=" + weakPlaceVO.getWpNo();

	}
	
	/**
	 * 외사취약지 정보를 수정한다.
	 * 
	 * @param multiRequest
	 *            mutipartform 객체
	 * @param weakPlaceVO
	 *            외사취약지 VO
	 * @param bindingResult
	 *            유효성 검사결과 객체
	 * @param model
	 *            모델 객체
	 * @param status
	 *            SessionStatus 객체
	 * @return 외사취약지 조회 화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/update.do", method = RequestMethod.POST)
	public String update(final MultipartHttpServletRequest multiRequest,
			@Valid @ModelAttribute("weakPlaceVO") final WeakPlaceVO weakPlaceVO,
			final BindingResult bindingResult, final Model model,
			final SessionStatus status) throws Exception {
		LoginUserVO loginUserVO = UserUtil.getMemberInfo();
		
		// 관리자만 수정 가능
		if (loginUserVO.getAuthAdmin() == 1) {
			// 유효성 검사
			beanValidator.validate(weakPlaceVO, bindingResult);
			if (bindingResult.hasErrors()) {
				model.addAttribute("weakPlaceVO", weakPlaceVO);
				model.addAttribute("registerFlag", "modify");				
				return "tg/weakPlaceAdd.tiles";
			}
			
			String[] deleteFiles = multiRequest.getParameterValues("deleteFile");
			final Map<String, MultipartFile> fileMap = multiRequest.getFileMap();
			HashMap<String, Object> map = weakPlaceService.update(weakPlaceVO, fileMap, deleteFiles);
			
			status.setComplete();
			
			if ((Integer) map.get("result") > 0) {
				return "redirect:/target/weakplace/view.do?place1="
						+ weakPlaceVO.getPlace1() + "&wpNo="
						+ weakPlaceVO.getWpNo();
			}
		}
		
		return "redirect:/target/weakplace/view.do?place1="
				+ weakPlaceVO.getPlace1() + "&wpNo=" + weakPlaceVO.getWpNo();
	}
	
	/**
	 * 외사취약지 정보를 삭제한다.
	 * 
	 * @param weakPlaceVO
	 *            외사취약지 VO
	 * @param model
	 *            Model 객체
	 * @param status
	 *            SessionStatus 객체
	 * @return 외사취약지 목록 화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/delete.do", method = RequestMethod.POST)
	public String delete(final WeakPlaceVO weakPlaceVO, final Model model,
			final SessionStatus status) throws Exception {
		LoginUserVO loginUserVO = UserUtil.getMemberInfo();
		
		// 관리자만 삭제 가능
		if (loginUserVO.getAuthAdmin() == 1) {
			WeakPlaceVO vo = weakPlaceService.select(weakPlaceVO);
			if (vo != null) {
				HashMap<String, Object> map = weakPlaceService.delete(weakPlaceVO);
				if ((Integer) map.get("result") > 0) {
					return "redirect:/target/weakplace/list.do";
				}
			}
		}
		
		return "redirect:/susa/incident/view.do?place1="
				+ weakPlaceVO.getPlace1() + "&wpNo=" + weakPlaceVO.getWpNo();
	}
	
	/**
	 * 파일을 반환한다.
	 * 
	 * @param weakPlaceVO
	 *            외사취약지 VO
	 * @param seq
	 *            파일 인덱스
	 * @param request
	 *            HttpServletRequest 객체
	 * @param response
	 *            HttpServletResponse 객체
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = "/download.do")
	public void fileResponse(final WeakPlaceVO weakPlaceVO, final int seq,
			final HttpServletRequest request, final HttpServletResponse response) throws Exception {
		WeakPlaceVO vo = weakPlaceService.select(weakPlaceVO);
		String filename = "";
		if (seq == 1) {
			filename = vo.getFilename1();
		} else if (seq == 2) {
			filename = vo.getFilename2();
		}
		
		if (StringUtils.isNotBlank(filename)) {
			String fileFullPath = propertiesService.getString("Target.wp.fileStorePath") + 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();
			}
		}
	}
}
