package cokr.xit.fims.base.web;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import cokr.xit.base.user.Department;
import cokr.xit.base.user.Sigungu;
import cokr.xit.base.user.SigunguQuery;
import cokr.xit.base.user.service.SigunguDepartmentService;
import cokr.xit.base.user.web.SigunguDepartmentController;
import cokr.xit.base.web.ApplicationController;
import cokr.xit.fims.base.FimsDepartment;
import cokr.xit.fims.base.FimsSigungu;
import cokr.xit.fims.base.OgdpQuery;
import cokr.xit.fims.base.service.bean.OgdpBean;
import cokr.xit.fims.cmmn.CmmnQuery;
import cokr.xit.fims.cmmn.service.StngService;
import cokr.xit.fims.mngt.Task;
import cokr.xit.fims.mngt.VltnQuery;
import cokr.xit.fims.mngt.service.bean.TaskBean;
import cokr.xit.fims.mngt.service.bean.VltnBean;
import cokr.xit.foundation.UserInfo;
import cokr.xit.foundation.data.DataObject;

@Controller
@RequestMapping(name = "시군구,기관,부서", value = "/ogdp")
public class OgdpController extends ApplicationController {

	public class METHOD_URL {
		public static final String
			sggStngMain      = "/sggStngMain.do",
			getSggStngInfo   = "/getSggStngInfo.do",
			getTasks         = "/getTasks.do",
			getVltns         = "/getVltns.do",
			updateSggStng    = "/updateSggStng.do",
			updateTaskStng   = "/updateTaskStng.do",
			createTaskStng   = "/createTaskStng.do",
			deptStngMain     = "/deptStngMain.do",
			getDeptStngList  = "/getDeptStngList.do",
			getDeptStngInfo  = "/getDeptStngInfo.do",
			updateDeptStng   = "/updateDeptStng.do"
		;
	}

	@Controller
	public class DefaultOgdpController extends SigunguDepartmentController<Sigungu, Department> {}

	@Resource(name="sigunguDepartmentService")
	private SigunguDepartmentService sggDeptService;
	@Resource(name="ogdpBean")
	private OgdpBean ogdpBean;
	/** 설정 정보 서비스 */
	@Resource(name = "stngService")
	private StngService stngService;
	/** 업무 정보 Bean */
	@Resource(name = "taskBean")
	private TaskBean taskBean;
	/** 위반 정보 Bean */
	@Resource(name = "vltnBean")
	private VltnBean vltnBean;

	/** 시군구 설정 관리 메인화면을 연다.
	 * @return fims/ogdp/ogdp01010-main
	 */
	@RequestMapping(name="시군구 설정 정보 관리 메인", value=METHOD_URL.sggStngMain)
	public ModelAndView sggStngMain(String sggCd) {
		UserInfo userInfo = currentUser();

		if ("ADMIN00".equals(userInfo.getInstitute())) {
			if (isEmpty(sggCd)) {
				List<DataObject> sggList = sggDeptService.getSigunguList(new SigunguQuery()) ;

				return new ModelAndView("fims/ogdp/select-sgg")
					.addObject("pageName", "selectSgg")
					.addObject("sggList", sggList);

			} else {
				return new ModelAndView("fims/ogdp/ogdp01010-main")
					.addObject("pageName", "ogdp01010")
					.addObject("sggCd", sggCd);
			}
		} else {
			ogdpBean.initUserInfo(userInfo);
			return new ModelAndView("fims/ogdp/ogdp01010-main")
				.addObject("pageName", "ogdp01010")
				.addObject("sggCd", userInfo.getInfo().get("sggCd"));
		}
	}

	/**지정하는 시군구의 설정 정보를 가져온다.<br />
	 * @param req
	 * @return jsonView
	 */
	@RequestMapping(name="시군구 설정 조회", value=METHOD_URL.getSggStngInfo)
	public ModelAndView getSggStngInfo(OgdpQuery req) {
		DataObject sggInfo = ogdpBean.getSggStngInfo(req);
		return new ModelAndView("jsonView").addObject("sggInfo", sggInfo);
	}

	/**지정하는 시군구의 업무 설정 정보를 가져온다.<br />
	 * @param req
	 * @return jsonView
	 */
	@RequestMapping(name="업무 조회", value=METHOD_URL.getTasks)
	public ModelAndView getTasks(CmmnQuery req) {
		List<DataObject> result = taskBean.getTasks(req);

		return setPagingInfo(new ModelAndView("jsonView"), result, "task");
	}

	/**지정하는 시군구와 업무의 위반 설정 정보를 가져온다.<br />
	 * @return 위반 설정 정보
	 */
	@RequestMapping(name="위반정보 조회", value=METHOD_URL.getVltns)
	public ModelAndView getVltns(VltnQuery req) {
		List<DataObject> result = vltnBean.getVltns(req);
		return setPagingInfo(new ModelAndView("jsonView"), result, "vltn");
	}

	/**시군구 설정 정보를 수정한다.
	 * @param sgg 시군구 정보, symbol 시군구 상징파일, logo 시군구 로고파일, offcs 시군구 직인파일
	 * @return jsonView
	 * <pre><code> {
	 *     "saved": 수정되었으면 true, 그렇지 않으면 false
	 * }</code></pre>
	 */
	@RequestMapping(name="시군구 설정 정보 수정", value=METHOD_URL.updateSggStng)
	public ModelAndView updateSggStng(FimsSigungu sgg, MultipartFile symbol, MultipartFile logo, MultipartFile offcs) {
		String sggCd = sgg.getSggID();

		if (symbol != null && !symbol.isEmpty() && symbol.getSize() != 0) {
			Map<String,String> newSymbol = this.uploadForSgg(symbol, sggCd, "symbol");
			sgg.setSymbolFilepath(newSymbol.get("filePath"));
			sgg.setSymbolFilename(newSymbol.get("fileName"));
		}
		if (logo != null && !logo.isEmpty() && logo.getSize() != 0) {
			Map<String,String> newLogo = this.uploadForSgg(logo, sggCd, "logo");
			sgg.setLogoFilepath(newLogo.get("filePath"));
			sgg.setLogoFilename(newLogo.get("fileName"));
		}
		if (offcs != null && !offcs.isEmpty() && offcs.getSize() != 0) {
			Map<String,String> newOffcs = this.uploadForSgg(offcs, sggCd, "offcs");
			sgg.setOfficialSealFilepath(newOffcs.get("filePath"));
			sgg.setOfficialSealFilename(newOffcs.get("fileName"));
		}
		boolean saved = ogdpBean.updateSggStng(sgg);

		return new ModelAndView("jsonView")
			.addObject("saved", saved);
	}

	private Map<String, String> uploadForSgg(MultipartFile mf, String sggCd, String fileSe){
		Map<String,String> newFileInfoMap = new HashMap<>();
		String workDirPath = "files/attachment/etc/"+fileSe;

		String ext = FilenameUtils.getExtension(mf.getOriginalFilename());
		String fileName = sggCd+"."+ext;

		ensureDir(workDirPath);
		String newFileFullPath = workDirPath + "/" + fileName;

		try {

			File newFile = new File(newFileFullPath);
			if (newFile.exists()) {
				if (!newFile.delete())
					throw new RuntimeException("[F]이미지 업로드 중 오류가 발생하였습니다.");
			}
			mf.transferTo(newFile);

		} catch (Exception e) {
			throw new RuntimeException("[F]이미지 업로드 중 오류가 발생하였습니다.");
		}

		newFileInfoMap.put("filePath", newFileFullPath);
		newFileInfoMap.put("fileName", mf.getOriginalFilename());
		return newFileInfoMap;
	}

	/**시군구별 업무,위반 설정 정보를 수정한다.
	 * @param sgg 시군구 정보
	 * @return jsonView
	 * <pre><code> {
	 *     "saved": 수정되었으면 true, 그렇지 않으면 false
	 * }</code></pre>
	 */
	@RequestMapping(name="업무 설정 정보 수정", value=METHOD_URL.updateTaskStng)
	public ModelAndView updateTaskStng(Task task) {
		String rtnMsg = stngService.updateTaskStng(task, task.getVltnStngList());
		return new ModelAndView("jsonView")
			.addObject("saved", rtnMsg.contains("[S]"));
	}

	/**시군구별 업무,위반 설정을 추가한다.
	 * @param sggCd 시군구 코드, taskSeCd 업무 구분 코드
	 * @return jsonView
	 * <pre><code> {
	 *     "saved": 수정되었으면 true, 그렇지 않으면 false
	 * }</code></pre>
	 */
	@RequestMapping(name="시군구 과태료 업무 추가", value=METHOD_URL.createTaskStng)
	public ModelAndView createTaskStng(String sggCd, String taskSeCd) {
		String rtnMsg = stngService.createTaskStng(sggCd, taskSeCd);
		return new ModelAndView("jsonView")
			.addObject("saved", rtnMsg.contains("[S]"));
	}

	/** 부서 설정관리 메인화면을 연다.
	 * @return fims/ogdp/ogdp02010-main
	 */
	@RequestMapping(name="부서 설정 정보 관리 메인", value=METHOD_URL.deptStngMain)
	public ModelAndView deptStngMain() {
		List<DataObject> allSggList = sggDeptService.getSigunguList(new SigunguQuery());

		return new ModelAndView("fims/ogdp/ogdp02010-main")
			.addObject("pageName", "ogdp02010")
			.addObject("sggList", allSggList);
	}

	/**부서 설정 목록을 조회한다.<br />
	 * {@link OgdpService#getDeptStngList(CmmnQuery)} 참고
	 * @param query 부서 목록 조회 조건
	 * @return jsonView
	 */
	@RequestMapping(name="부서 설정 목록 조회", value=METHOD_URL.getDeptStngList)
	public ModelAndView getDeptStngList(OgdpQuery query) {
		setFetchSize(query);

		return setPagingInfo(new ModelAndView("jsonView"), ogdpBean.getDeptStngList(query),"");

	}

	/**지정한 ID의 부서 설정 정보(info)를 반환한다.
	 * @param query 부서 조회 조건
	 * @return fims/ogdp/ogdp02020-info 또는 jsonView
	 * <pre>{
	 *     "deptInfo": 부서 정보
	 * }</pre>
	 */
	@RequestMapping(name="부서 설정 상세 조회", value=METHOD_URL.getDeptStngInfo)
	public ModelAndView getDeptStngInfo(OgdpQuery query) {
		DataObject deptInfo = !isEmpty(query.getDeptCd()) ? ogdpBean.getDeptStngInfo(query) : null;

		boolean json = jsonResponse();
		return new ModelAndView(json ? "jsonView" : "fims/ogdp/ogdp02020-info")
			.addObject("pageName", "ogdp02020")
			.addObject("deptInfo", json ? deptInfo : toJson(deptInfo));
	}

	/**부서 설정 정보를 수정한다.
	 * @param dept 부서 정보
	 * @return jsonView
	 * <pre><code> {
	 *     "saved": 저장되었으면 true, 그렇지 않으면 false
	 * }</code></pre>
	 */
	@RequestMapping(name="부서 설정 수정", value=METHOD_URL.updateDeptStng)
	public ModelAndView updateDeptStng(FimsDepartment dept) {
		boolean saved = ogdpBean.updateDeptStng(dept);

		return new ModelAndView("jsonView").addObject("saved", saved);
	}
}