package cokr.xit.fims.cvlc.web;

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

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

import org.apache.poi.ss.usermodel.CellStyle;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import cokr.xit.applib.Print;
import cokr.xit.base.code.CommonCode;
import cokr.xit.base.docs.xls.CellDef;
import cokr.xit.base.docs.xls.Format;
import cokr.xit.base.docs.xls.Style;
import cokr.xit.base.docs.xls.XLSWriter;
import cokr.xit.base.file.service.FileQuery;
import cokr.xit.base.file.service.bean.FileBean;
import cokr.xit.base.user.dao.UserMapper;
import cokr.xit.base.web.ApplicationController;
import cokr.xit.fims.base.FimsUser;
import cokr.xit.fims.base.service.bean.OgdpBean;
import cokr.xit.fims.cmmn.FimsPrintOption;
import cokr.xit.fims.cmmn.hwp.format.CvlcptOrgn;
import cokr.xit.fims.cmmn.service.bean.StngBean;
import cokr.xit.fims.cmmn.xls.FormatMaker;
import cokr.xit.fims.cmmn.xls.StyleMaker;
import cokr.xit.fims.crdn.Crdn;
import cokr.xit.fims.crdn.CrdnQuery;
import cokr.xit.fims.crdn.dao.CrdnStngMapper;
import cokr.xit.fims.crdn.service.CrdnService;
import cokr.xit.fims.cvlc.CrdnCvlcpt;
import cokr.xit.fims.cvlc.service.CrdnCvlcptService;
import cokr.xit.fims.cvlc.service.bean.CrdnCvlcptMainBean;
import cokr.xit.fims.mngt.service.bean.TaskProcessor;
import cokr.xit.fims.task.Task;
import cokr.xit.foundation.UserInfo;
import cokr.xit.foundation.data.DataObject;

/**민원접수자료 서비스 웹 컨트롤러.<br />
 * {웹 컨텍스트}/cvlc/cvlc01 로 접근할 수 있다.
 * @author leebj
 */
@Controller
@RequestMapping(name="민원접수자료 관리 업무", value=Cvlc01Controller.CLASS_URL)
public class Cvlc01Controller extends ApplicationController {
	public static final String CLASS_URL = "/cvlc/cvlc01";

	public class METHOD_URL {
		public static final String
		civilComplaintReceiptDataMain           = "/010/main.do",
		getCivilComplaintReceiptDataList        = "/010/list.do",
		removeCivilComplaint                    = "/010/remove.do",
		getCivilComplaintReceiptInitialDataInfo = "/020/info.do",
		saveCivilComplaintProcessSection        = "/020/update.do",
		copyCivilComplaintInfo                  = "/020/create.do",
		sendBackCivilComplaintInfo              = "/020/remove.do",
		getCivilComplaintOriginalInfo           = "/050/info.do",
		makeFileFromHwpFormat                   = "/050/makeFileFromHwpFormat.do"
		;
	}

	@Resource(name="userMapper")
	protected UserMapper userMapper;
	@Resource(name="crdnService")
	private CrdnService crdnService;
	@Resource(name="crdnCvlcptService")
	private CrdnCvlcptService crdnCvlcptService;
	@Resource(name = "stngBean")
	private StngBean stngBean;
	@Resource(name = "fileBean")
	private FileBean fileBean;
	@Resource(name = "ogdpBean")
	private OgdpBean ogdpBean;
	@Resource(name = "crdnCvlcptMainBean")
	private CrdnCvlcptMainBean crdnCvlcptMainBean;
	@Resource(name="crdnStngMapper")
	private CrdnStngMapper crdnStngMapper;

	/** 민원 접수 자료 메인화면을 연다.
	 * @return fims/cvlc/cvlc01010-main
	 */
	@RequestMapping(name="민원 접수 자료 메인", value=METHOD_URL.civilComplaintReceiptDataMain)
	public ModelAndView civilComplaintReceiptDataMain() {
		Map<String, List<CommonCode>> commonCodes = getCodesOf("FIM026","FIM054");

		ModelAndView mav = new ModelAndView("fims/cvlc/cvlc01010-main")
			.addObject("pageName", "cvlc01010")
			.addObject("FIM054List", commonCodes.get("FIM054"))
			.addObject("TaskListForSgg", stngBean.filterTaskSectionCodeForSgg(commonCodes.get("FIM054")))
			.addObject("currentUserName", UserInfo.current().getName());
		return addCodes(commonCodes, mav, "FIM026");
	}

	/**민원접수자료 목록을 조회한다.<br />
	 * {@link CrdnService#getCrackdownList(CrdnQuery)} 참고
	 * @param query 민원접수자료 목록 조회 조건
	 * @return jsonView
	 */
	@Task
	@RequestMapping(name="민원접수자료 목록 조회", value=METHOD_URL.getCivilComplaintReceiptDataList)
	public ModelAndView getCivilComplaintReceiptDataList(CrdnQuery query) {
		setFetchSize(query.setGridType("receiptData"));
		query.setSggCd(currentUser().getOrgID());

		if("xls".equals(query.getDownload())) {
			List<CellDef> cellDefs = fromJson(query.getCellDefs(), CellDef.listType());

			XLSWriter xlsx = new XLSWriter().worksheet(0);
			Format format = new Format(xlsx);
			CellStyle center = format.cellStyle(Style.CENTER);
			CellStyle left = format.cellStyle(Style.LEFT);
			CellStyle dateYMD = format.yyyy_mm_dd();
			CellStyle dateDT = format.yyyy_mm_dd_hh_mm_ss();

			Map<String, Object> valueMap = new HashMap<String, Object>();
            valueMap.put("접수번호", center);
            valueMap.put("목록번호", center);
            valueMap.put("등록구분", format.of("CRDN_REG_SE_NM").style(center));
            valueMap.put("신고자", center);
            valueMap.put("담당자", center);
            valueMap.put("담당자전화번호", center);
            valueMap.put("접수일자", FormatMaker.yyyy_mm_dd(format,"CVLCPT_RCPT_YMD").style(dateYMD));
            valueMap.put("처리기한", FormatMaker.yyyy_mm_dd_hh_mm_ss(format,"CVLCPT_PRCS_PRNMNT_DT").style(dateDT));
            valueMap.put("위반일시", FormatMaker.yyyy_mm_dd_hh_mm_ss(format,"CRDN_YMD_TM").style(dateDT));
            valueMap.put("위반내용", center);
            valueMap.put("차량번호", left);
            valueMap.put("사진건수", center);
			CellDef.setValues(cellDefs, valueMap);

			List<DataObject> list = crdnCvlcptService.getCivilComplaintList(query.setFetchSize(0));

			xlsx.cell(0, 0).value("민원접수자료 목록").value(center).merge(0, cellDefs.size()-1)
				.cell(3, 0).rowValues(CellDef.header(cellDefs, () -> StyleMaker.headerStyle(xlsx)))
				.cell(4, 0).values(list, CellDef.values(cellDefs.stream().map(i -> {if(i.getValue() instanceof Format) {i.setField(null);}; return i;}).toList()));

			return new ModelAndView("downloadView")
				.addObject("download", xlsx.getDownloadable().setFilename("민원접수자료 목록.xlsx"))
				.addObject("downloadData", list)
				.addObject("dataNames", cellDefs.stream().map(CellDef::getLabel).toList());
		}

		return setPagingInfo(new ModelAndView("jsonView"), crdnCvlcptService.getCivilComplaintList(query),"");
	}

	/**지정한 민원자료를 제거한다.
	 * @param crdnIds 단속대장 아이디 목록
	 * @return jsonView
	 * <pre><code> {
	 *     "affected": 저장된 정보수
	 *     "saved": 저장되었으면 true, 그렇지 않으면 false
	 * }</code></pre>
	 */
	@Task
	@RequestMapping(name="민원자료 제거", value=METHOD_URL.removeCivilComplaint)
	public ModelAndView removeCivilComplaint(String[] crdnIds) {
		String rtnMsg = crdnService.remove(crdnIds);
		return new ModelAndView("jsonView")
			.addObject("saved", rtnMsg.contains("S"));
	}

	/** 민원내역 원본 보기 팝업 화면을 연다.
	 * @return fims/cvlc/cvlc01050-info
	 */
	@Task
	@RequestMapping(name="민원내역 원본 보기", value=METHOD_URL.getCivilComplaintOriginalInfo)
	public ModelAndView getCivilComplaintOriginalInfo(HttpServletRequest hReq, CrdnQuery query) {
		Map<String, List<CommonCode>> commonCodes = getCodesOf("FIM039");
		DataObject info = crdnCvlcptService.getCivilComplaintOriginalInfo(query);

		boolean json = jsonResponse();
		return new ModelAndView(json ? "jsonView" : "fims/cvlc/cvlc01050-info")
			.addObject("pageName", "cvlc01050")
			.addObject("taskSeCd", hReq.getParameter("taskSeCd"))
//			.addObject("taskSeCd", hReq.getServletPath().split("/")[1])
			.addObject("FIM039List", commonCodes.get("FIM039"))
			.addObject("cvlcptInfo", json ? info : toJson(info));
	}

	/** 민원내역 원본을 한글 파일로 작성한다.
	 * @return hwp파일
	 */
	@Task
	@RequestMapping(name="민원내역 원본 한글 파일 생성", value=METHOD_URL.makeFileFromHwpFormat)
	public ModelAndView makeFileFromHwpFormat(CrdnQuery query) {
		UserInfo userInfo = currentUser();
		ogdpBean.initUserInfo(userInfo);

		DataObject dataObject = crdnCvlcptMainBean.getCivilComplaintOriginalInfo(query);
		List<DataObject> dataObjectList = new ArrayList<DataObject>();
		dataObjectList.add(dataObject);

		String linkTblNm = dataObject.string("LINK_TBL_NM");
		if(!isEmpty(linkTblNm)) {
			FileQuery fileQuery = new FileQuery()
				.setInfoType(
					switch (linkTblNm) {
					case "TB_ESB_INTERFACE" -> "010";
					case "TB_SAEOL_CVLCPT_DTL" -> "020";
					default -> throw new RuntimeException("한글 파일 출력 중 오류가 발생하였습니다.");
					}
				)
				.setInfoKeys(dataObject.string("LINK_ID"));

			List<DataObject> fileInfoList = fileBean.getFileList(fileQuery);
			fileInfoList = fileInfoList.stream()
				.filter(fileInfo -> fileInfo.string("MIME_TYPE").startsWith("image"))
				.toList();

			int photoCnt = fileInfoList != null ? fileInfoList.size() : 0;
			for (int i=0; i < photoCnt; i++) {
				dataObject.put("PHOTO"+i, fileInfoList.get(i).string("URL"));
			}
			dataObject.put("ORGN_PHOTO_CNT", photoCnt);
		}

		Print print = new Print();
		print.setPrintRequestUserInfo(userInfo);
		CvlcptOrgn hwpFormat = new CvlcptOrgn(print, new FimsPrintOption(), dataObjectList);
		HashMap<String, Object> result = hwpFormat.makeFile().andDownload();
		return new ModelAndView("downloadView")
			.addAllObjects(result);
	}

	/**민원접수 초기자료 상세조회 팝업 화면을 연다.<br />
	 * @return fims/cvlc/cvlc01020-info
	 */
	@Task
	@RequestMapping(name="민원접수 초기자료 조회", value=METHOD_URL.getCivilComplaintReceiptInitialDataInfo)
	public ModelAndView getCivilComplaintReceiptInitialDataInfo(HttpServletRequest hReq, CrdnQuery query) {
		String urlTaskSeCd = hReq.getParameter("taskSeCd");
//		String urlTaskSeCd = hReq.getServletPath().split("/")[1];
		DataObject info = crdnCvlcptService.getCivilComplaintReceiptInitialDataInfo(query);

		FimsUser currentUser = (FimsUser) currentUser().getUser();
		String sggCd = currentUser.getOrgID();
		List<String> stdgNmList = crdnStngMapper.selectStdgNmList(sggCd);

		TaskProcessor taskProcessor = TaskProcessor.get();
		String vltnByTask = taskProcessor.getVltnCdGrp(urlTaskSeCd);
		Map<String, List<CommonCode>> commonCodes = getCodesOf("FIM011","FIM053","LVS005",vltnByTask);

		boolean json = jsonResponse();
		ModelAndView mav = new ModelAndView(json ? "jsonView" : "fims/cvlc/cvlc01020-info")
			.addObject("pageName", "cvlc01020")
			.addObject("taskSeCd", urlTaskSeCd)
			.addObject("crdnInfo", json ? info : toJson(info))
			.addObject("stdgNmList", stdgNmList)

			.addObject("FIM011List", commonCodes.get("FIM011"))
			.addObject("FIM053List", commonCodes.get("FIM053"))
			.addObject("LVS005List", commonCodes.get("LVS005"))
			.addObject("VLTNList", commonCodes.get(vltnByTask));

		String[] extraCodeGroups = taskProcessor.getExtraCdGrps(urlTaskSeCd);
		if (!isEmpty(extraCodeGroups)) {
			commonCodes = getCodesOf(extraCodeGroups);
			commonCodes.forEach((codeGroup, codes) -> {
				mav.addObject(codeGroup + "List", codes);
			});
		}
		return mav;
	}

	/**지정한 민원 초기자료를 수정한다.
	 * @param hReq 수정 요청, crdnCvlcpt 민원 정보, crdn 단속 정보
	 * @return jsonView
	 * <pre><code> {
	 *     "affected": 저장된 정보수
	 *     "saved": 저장되었으면 true, 그렇지 않으면 false
	 * }</code></pre>
	 */
	@Task
	@RequestMapping(name="민원 정보 수정", value=METHOD_URL.saveCivilComplaintProcessSection)
	public ModelAndView saveCivilComplaintProcessSection(HttpServletRequest hReq, CrdnCvlcpt crdnCvlcpt, Crdn crdn) {
		FimsUser currentUser = (FimsUser) currentUser().getUser();
		String sggCd = currentUser.getOrgID();
		crdn.setSggCd(sggCd);
		crdnCvlcpt.setSggCd(sggCd);

		Map<String, Object> nonQueryRequest = new HashMap<String, Object>();
		String acceptYn = hReq.getParameter("acceptYn");
		if("Y".equals(acceptYn)) {
			nonQueryRequest.put("acceptType", "accept");
		} else {
			String levyExclSeCd = crdn.getLevyExclSeCd();
			if("2".equals(levyExclSeCd)) {
				nonQueryRequest.put("acceptType", "someAccept");
			} else if(levyExclSeCd.equals("1")) {
				nonQueryRequest.put("acceptType", "nonAccept");
			}
		}

		String rtnMsg = crdnCvlcptService.updateCvlcptProcessSection(nonQueryRequest, crdnCvlcpt, crdn);
		return new ModelAndView("jsonView")
			.addObject("saved", rtnMsg.contains("[S]"));
	}

	/**지정한 민원 자료의 복사본을 생성한다.
	 * @param crdnId 단속대장 아이디
	 * @return jsonView
	 * <pre><code> {
	 *     "saved": 저장되었으면 true, 그렇지 않으면 false
	 * }</code></pre>
	 */
	@Task
	@RequestMapping(name="민원 자료 복사", value=METHOD_URL.copyCivilComplaintInfo)
	public ModelAndView copyCivilComplaintInfo(String crdnId) {
		String rtnMsg = crdnCvlcptService.copyCvlcptCrdnInfo(crdnId);
		return new ModelAndView("jsonView")
			.addObject("saved", rtnMsg.contains("[S]"));
	}

	/**지정한 민원 자료를 반송(회수) 처리한다.
	 * @param crdnId 단속 ID
	 * @return jsonView
	 * <pre><code> {
	 *     "saved": 저장되었으면 true, 그렇지 않으면 false
	 * }</code></pre>
	 */
	@Task
	@RequestMapping(name="민원 자료 반송", value=METHOD_URL.sendBackCivilComplaintInfo)
	public ModelAndView sendBackCivilComplaintInfo(String crdnId) {
		String rtnMsg = crdnCvlcptService.sendBackCivilComplaintInfo(crdnId);
		return new ModelAndView("jsonView")
			.addObject("saved", rtnMsg.contains("[S]"));
	}
}