package cokr.xit.fims.payer.web;

import java.util.List;
import java.util.Map;

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

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import cokr.xit.base.code.CommonCode;
import cokr.xit.base.web.ApplicationController;
import cokr.xit.fims.crdn.CrdnQuery;
import cokr.xit.fims.crdn.service.CrdnStngService;
import cokr.xit.fims.payer.Payer;
import cokr.xit.fims.payer.PayerQuery;
import cokr.xit.fims.payer.service.PayerService;
import cokr.xit.fims.task.Task;
import cokr.xit.foundation.data.DataObject;
import cokr.xit.interfaces.lvis.v2406.LvisA01;

/**납부자 서비스의 웹 컨트롤러
 *
 * <p>상세 설명:
 *
 * <pre>
 * ============ 변경 이력 ============
 * 2023-08-18	mjkhan 최초 작성
 * ================================
 * </pre>
 */
@Controller
@RequestMapping(name="납부자", value="/payer")
public class PayerController extends ApplicationController {

    public static final String CLASS_URL = "/payer";

	public class METHOD_URL {
		public static final String
              create                    = "/create.do"                          // 납부자 등록
            , update                    = "/update.do"                          // 납부자 수정
            , remove                    = "/remove.do"                          // 납부자 제거
            , getVehicleOwner           = "/vehicle.do"                         // 차량/납부자 조회
            , getCrdnPayerInfo          = "/crdnPayerInfo.do"                   // 단속, 납부자 정보 조회
            , createCrdnPayer           = "/createCrdnPayer.do"                 // 단속, 납부자 대장 등록
            , getPayerHistorys          = "/getPayerHstrys.do"                  // 납부자 변경 이력 조회
            , getLastPayerAddressInfo   = "/getLastInfo.do"                     // 납부자, 납부자 주소 정보 조회
		;
	}

	/**납부자 서비스*/
	@Resource(name = "payerService")
	private PayerService payerService;
	@Resource(name = "crdnStngService")
	private CrdnStngService crdnStngService;

	/**납부자 관리 메인화면(payer/payer-main)을 연다.
	 * 조건없는 {@link #getPayerList(PayerQuery) 납부자 조회 결과}를 포함시킨다.
	 * @return /payer/payer-main
	 */
	@Task("CMN")
	@RequestMapping(name = "납부자 메인", value = "/main.do")
	public ModelAndView main() {
		ModelAndView mav = getPayerList(new PayerQuery().setPageNum(1));
		mav.setViewName("/payer/payer-main");
		return mav.addObject("payerList", toJson(mav.getModel().get("payerList")));
	}

	/**납부자 목록을 조회하여 반환한다.<br />
	 * {@link PayerService#getPayerList(PayerQuery)} 참고
	 * @param req 납부자 조회 조건
	 * @return jsonView
	 * <pre><code> {
	 *     "payerList": [납부자 목록]
	 *     "payerStart": 납부자 목록 시작 인덱스
	 *     "payerFetch": 한 번에 가져오는 납부자 목록 수
	 *     "payerTotal": 조회 결과 찾은 전체 납부자 수
	 * }</code></pre>
	 */
	@Task("CMN")
	@RequestMapping(name = "납부자 목록 조회", value = "/list.do")
	public ModelAndView getPayerList(PayerQuery req) {
		List<?> result = payerService.getPayerList(setFetchSize(req));
		return setCollectionInfo(new ModelAndView("jsonView"), result, "payer");
	}

	/**납부자를 등록한다.
	 * @param payer 납부자 정보
	 * @return jsonView
	 * <pre><code> {
	 *     "saved": 등록되었으면 true, 그렇지 않으면 false
	 * }</code></pre>
	 */
	@Task("CMN")
	@PostMapping(name = "납부자 등록", value = "/create.do")
	public ModelAndView create(Payer payer) {
		boolean saved = payerService.create(payer);
		return new ModelAndView("jsonView")
			.addObject("saved", saved);
	}

	/**납부자 정보를 수정한다.
	 * @param payer 납부자 정보
	 * @return jsonView
	 * <pre><code> {
	 *     "saved": 수정되었으면 true, 그렇지 않으면 false
	 * }</code></pre>
	 */
	@Task("CMN")
	@PostMapping(name = "납부자 수정", value = "/update.do")
	public ModelAndView update(Payer payer) {
		boolean saved = payerService.update(payer);
		return new ModelAndView("jsonView")
			.addObject("saved", saved);
	}

	@Task("CMN")
	@PostMapping(name = "차량/납부자 조회", value = "/vehicle.do")
	public ModelAndView getVehicleOwner(HttpServletRequest hreq) {
		String sggCd = ifEmpty(hreq.getParameter("sggCd"), currentUser()::getOrgID);
		String levy_stdde = hreq.getParameter("levy_stdde");
		String vhrno = hreq.getParameter("vhrno");
		String vin = hreq.getParameter("vin");

		LvisA01.A01Request req = new LvisA01.A01Request().init(null, levy_stdde, vhrno, vin);

		Payer payer = payerService.findVehicleOwner(req);
/*
		//행공센 연계 여부
		if(ifEmpty(FimsConf.get().getPublicInfoCarYn(),() -> "Y").equals("Y")) {
			BasicInfoExtRequest req = new BasicInfoExtRequest();
			req.setInqire_se_code(hreq.getParameter("inqire_se_code"));
			req.setLevy_stdde(levy_stdde);
			req.setVhrno(vhrno);
			req.setVin(vin);
			payer = payerService.findVehicleOwner(req);
		} else {
			BasicInfoRequest req = new BasicInfoRequest();
			req.setSggCd(sggCd);
			req.setInqire_se_code(hreq.getParameter("inqire_se_code"));
			req.setLevy_stdde(levy_stdde);
			req.setOwner_mber_no(hreq.getParameter("owner_mber_no"));
			req.setVhrno(vhrno);
			req.setVin(vin);
			payer = payerService.findVehicleOwner(req);
		}
*/
		boolean found = payer != null,
				exempted = !crdnStngService.getExemptionVehicleList(new CrdnQuery()
					.setVhrno(vhrno)
					.setCrdnYmd(levy_stdde)
					.setSggCd(sggCd)
				).isEmpty(); // 면제차량 여부

		return new ModelAndView("jsonView")
			.addObject("found", found)
			.addObject("exempted", exempted)
			.addObject("rtpyrId", found ? payer.getRtpyrId() : null)
			.addObject("addrSn", found ? payer.getAddrSn() : null)
			.addObject("vehicle", found ? payer.getVehicleInfo() : null);
	}

	/**납부자 정보를 반환한다.
	 * @param
	 * @return fims/payer/payer01020-info 또는 jsonView
	 * <pre>{
	 *     "payerInfo": 납부자 정보
	 * }</pre>
	 */
	@Task("CMN")
	@RequestMapping(name="납부자 정보 조회", value=METHOD_URL.getCrdnPayerInfo)
	public ModelAndView getCrdnPayerInfo(HttpServletRequest hReq, PayerQuery req) {
		DataObject payerInfo = payerService.getCrdnPayerInfo(req);
		// View(jsp)에서 사용할 공통코드를 조회
        Map<String, List<CommonCode>> commonCodes = getCodesOf("FIM011", "FIM014");

        boolean json = jsonResponse();
        return new ModelAndView(json ? "jsonView" : "fims/payer/payer01020-info")
            .addObject("pageName", "payer01020")                            // jsp pageName
            .addObject("prefixUrl", CLASS_URL)                              // prefixUrl
            .addObject("FIM011List", commonCodes.get("FIM011"))             // 납부자 구분 코드(RTPYR_SE_CD)
            .addObject("FIM014List", commonCodes.get("FIM014"))             // 납부자 상태 코드(RTPYR_STTS_CD)
            .addObject("Info", json ? payerInfo : toJson(payerInfo))
        ;
 	}

	/**납부자 대장를 등록한다.
	 * @param Payer 납부자 대장 정보
	 * @return jsonView
	 * <pre><code> {
	 *     "saved": 등록되었으면 true, 그렇지 않으면 false
	 * }</code></pre>
	 */
	@Task("CMN")
	@RequestMapping(name="단속 납부자 등록", value=METHOD_URL.createCrdnPayer)
	public ModelAndView createCrdnPayer(Payer payer) {
		String rtnMsg = payerService.createCrdnPayer(payer);

		return new ModelAndView("jsonView")
			.addObject("saved", rtnMsg.contains("[S]"))
			.addObject("rtnMsg", rtnMsg);
	}

	/**납부자 변경 이력을 조회하여 반환한다.<br />
	 * {@link PayerService#getPayerList(PayerQuery)} 참고
	 * @param req 납부자 조회 조건
	 * @return jsonView
	 * <pre><code> {
	 *     "payerHstryList": [납부자 변경 이력 목록]
	 * }</code></pre>
	 */
	@Task("CMN")
	@RequestMapping(name="납부자 변경 이력 조회", value=METHOD_URL.getPayerHistorys)
	public ModelAndView getPayerHistorys(PayerQuery req) {
		List<?> result = payerService.getPayerHstrys(req);
		return setCollectionInfo(new ModelAndView("jsonView"), result, "payerHstry");
	}

    /**납부자, 납부자 주소 정보를 반환한다.
     * @param
     * @return jsonView
     * <pre>{
     *     "payerInfo": 납부자 정보
     * }</pre>
     */
	@Task("CMN")
    @RequestMapping(name="납부자, 납부자 주소 정보 조회", value=METHOD_URL.getLastPayerAddressInfo)
    public ModelAndView getLastPayerAddressInfo(HttpServletRequest hReq, PayerQuery req) {
        DataObject payerInfo = payerService.getLastPayerAddrInfo(req);

        return new ModelAndView("jsonView")
        	.addObject("found", payerInfo != null)
        	.addObject("info", payerInfo);
    }
}