package cokr.xit.fims.crdn.service.bean;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import cokr.xit.base.file.FileInfo;
import cokr.xit.base.file.service.bean.FileBean;
import cokr.xit.fims.cmmn.CrdnPayerHstry;
import cokr.xit.fims.cmmn.CrdnSttsHstry;
import cokr.xit.fims.cmmn.service.bean.CrdnPayerHstryBean;
import cokr.xit.fims.cmmn.service.bean.CrdnSttsHstryBean;
import cokr.xit.fims.crdn.Crdn;
import cokr.xit.fims.crdn.dao.CrdnInfoMapper;
import cokr.xit.fims.crdn.dao.CrdnInstMapper;
import cokr.xit.fims.crdn.dao.CrdnUpdtMapper;
import cokr.xit.fims.excl.LevyExcl;
import cokr.xit.fims.excl.service.bean.Excl01Bean;
import cokr.xit.foundation.AbstractComponent;
import cokr.xit.foundation.UserInfo;
import cokr.xit.foundation.data.DataObject;

/** 단속 관리 Bean
 * @author leebj
 */
@Component("crdnBean")
public class CrdnBean extends AbstractComponent {

	@Resource(name = "crdnStngBean")
	private CrdnStngBean crdnStngBean;

	@Resource(name = "excl01Bean")
	private Excl01Bean excl01Bean;

	@Resource(name = "crdnSttsHstryBean")
	private CrdnSttsHstryBean crdnSttsHstryBean;

	@Resource(name = "crdnPayerHstryBean")
	private CrdnPayerHstryBean crdnPayerHstryBean;

	@Resource(name = "fileBean")
	private FileBean fileBean;

	@Resource(name = "crdnInfoMapper")
	private CrdnInfoMapper crdnInfoMapper;

	@Resource(name = "crdnInstMapper")
	private CrdnInstMapper crdnInstMapper;

	@Resource(name = "crdnUpdtMapper")
	private CrdnUpdtMapper crdnUpdtMapper;

	public boolean create(Map<String, Object> nonQueryRequest, Crdn crdn, List<FileInfo> fileInfoList) {
		if(fileInfoList != null && !fileInfoList.isEmpty()) {
			crdn.setAtchFileCnt(fileInfoList.size());
		} else {
			crdn.setAtchFileCnt(0);
		}

		//금액 계산
		int[] basicAmt = crdnStngBean.getBasicAmt(crdn);
		crdn.setFfnlgCrdnAmt(basicAmt[0]);
		crdn.setFfnlgAmt(basicAmt[0]);
		crdn.setAdvntceAmt(basicAmt[1]);

		//TODO : 단속팀 저장
		//if(!ifEmpty(crdn.getTeamId(), () -> "").equals("")) {
		//}


		//TODO : 입력파라미터에 납부자ID가 없고, 납부자명이 있을때 납부자 신규등록
		//TODO : 납부자정보의 납부자ID와 입력파라미터의 납부자ID가 동일하고, 납부자명이 다를때 납부자 신규등록
		//TODO : 납부자정보ID,납부자명이 동일하고, 주소가 다를 때 주소업데이트


		if(ifEmpty(crdn.getCrdnSttsCd(), () -> "").equals("")){
			if(!ifEmpty(crdn.getRtpyrId(), () -> "").equals("")) {
				crdn.setCrdnSttsCd("21");
			} else {
				crdn.setCrdnSttsCd("01");
			}
		}


		boolean result = this.createLedger(crdn);
		if (!result) {
			throw new RuntimeException("단속자료 등록 중 단속자료 등록에 실패하였습니다.");
		}

		SimpleDateFormat yyyyMMdd = new SimpleDateFormat("yyyyMMdd");
		Date curTime = new Date();
		String strCurrentDate = yyyyMMdd.format(curTime);

		String taskDtlId = crdn.getCrdnId();

		if(crdn.getCrdnSttsCd().equals("83")) {
			// 부과제외(TB_LEVY_EXCL) 대장 등록
			LevyExcl excl01 = new LevyExcl();
			excl01.setSggCd(crdn.getSggCd());
			excl01.setTaskSeCd(crdn.getTaskSeCd());
			excl01.setCrdnId(crdn.getCrdnId());
			excl01.setLevyExclYmd(strCurrentDate);
			excl01.setLevyExclSeCd("2");
			excl01.setLevyExclRsnCd("192");
			excl01.setEtcCn("");

			String retMessage = excl01Bean.createLevyExcl(excl01);
			if (retMessage.contains("[F]")) {
				throw new RuntimeException("단속자료 등록 중 부과제외 자료 등록에 실패하였습니다.");
			}

			taskDtlId = excl01.getLevyExclId();
		}

		// 단속상태이력(TB_CRDN_STTS_HSTRY) 대장 등록
		CrdnSttsHstry crdnSttsHstry = new CrdnSttsHstry();
		crdnSttsHstry.setCrdnId(crdn.getCrdnId());
		crdnSttsHstry.setBfrSttsCd("");
		crdnSttsHstry.setBfrSttsChgDt("");
		crdnSttsHstry.setCrdnSttsCd(crdn.getCrdnSttsCd());
		crdnSttsHstry.setTaskDtlId(taskDtlId);
		crdnSttsHstry.setEtcCn("");

		result = crdnSttsHstryBean.create(crdnSttsHstry);
		if (!result) {
			throw new RuntimeException("단속자료 등록 중 단속상태 이력 등록에 실패하였습니다.");
		}

		//단속납부자이력(TB_CRDN_PAYER_HSTRY) 대장 등록
		if(!ifEmpty(crdn.getRtpyrId(), () -> "").equals("")) {
			CrdnPayerHstry crdnPayerHstry = new CrdnPayerHstry();
			crdnPayerHstry.setCrdnId(crdn.getCrdnId());
			crdnPayerHstry.setRtpyrId(crdn.getRtpyrId());
			result = crdnPayerHstryBean.create(crdnPayerHstry);
			if (!result) {
				throw new RuntimeException("단속자료 등록 중 단속납부자 이력 등록에 실패하였습니다.");
			}
		}

		//파일 등록
		if(fileInfoList != null && !fileInfoList.isEmpty()) {
			fileInfoList.forEach(fileInfo -> fileInfo.setInfoType(Crdn.INF_TYPE).setInfoKey(crdn.getCrdnId()));
			int effected = fileBean.create(fileInfoList);
			if(effected == 0) {
				throw new RuntimeException("단속자료 등록 중 파일 등록에 실패하였습니다.");
			}
		}

		return result;
	}

	/**단속 대장 정보를 등록한다.
	 * @param crdn 단속 대장
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public boolean createLedger(Crdn crdn) {

		int effected = crdnInstMapper.insertCrdn(crdn);
		if(effected != 1) {
			return false;
		}

		effected = crdnInstMapper.insertCrdnAddition(crdn);
		if(effected != 1) {
			return false;
		}

		return true;

	}

	/**단속 대장 정보를 수정한다.
	 * @param nonQueryRequest 수정 요청, crdn 단속 대장
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public boolean updateLedger(Map<String,Object> nonQueryRequest, Crdn crdn) {
		String updateInfomationType = (String)ifEmpty(nonQueryRequest.get("updateInfomationType"), "") ;

		switch (ifEmpty(updateInfomationType, () -> "")) {
			default:
				if(crdnUpdtMapper.updateCrdnAddition(crdn) != 1) {
					return false;
				}
				return crdnUpdtMapper.updateCrdn(crdn) == 1 ? true : false;
		}
	}

	/**단속 정보를 삭제한다.
	 * @param crdnIDs 단속아이디 목록
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public boolean remove(String... crdnIDs) {
		if (isEmpty(crdnIDs)) return false;

		Map<String, Object> paramMap = new HashMap<String, Object>();
		List<String> crdnIdList = Arrays.asList(crdnIDs);
		paramMap.put("crdnIDs", crdnIdList);
		paramMap.put("removedBy", UserInfo.current().getId());

		return crdnUpdtMapper.deleteCrdn(paramMap) >= 1 ? true : false;
	}

	/**단속 정보를 삭제한다.
	 * @param crdnIDs 단속아이디 목록
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public String removeCrackdown(Crdn crdn) {
		// 변수 선언
		boolean retSuccess = false;						// DB 처리 결과
        String retMessage = "";							// 처리 결과 메시지
        int effected = 0;

		// 단속 ID로 단속, 부과제외 정보 조회
		DataObject infoCrdn = crdnInfoMapper.selectCrdnInfo(crdn.getCrdnId());

		// 단속상태이력(TB_CRDN_STTS_HSTRY)
		CrdnSttsHstry crdnSttsHstry = new CrdnSttsHstry();

		crdnSttsHstry.setCrdnId(infoCrdn.string("CRDN_ID"));
		crdnSttsHstry.setBfrSttsCd(infoCrdn.string("CRDN_STTS_CD"));
		crdnSttsHstry.setBfrSttsChgDt(infoCrdn.string("CRDN_STTS_CHG_DT"));
		crdnSttsHstry.setCrdnSttsCd("99");

		// 단속 상태 이력(TB_CRDN_STTS_HSTRY) 대장에 등록 한다.
		retSuccess = crdnSttsHstryBean.createHstryUpdateCrdnSttsCd(crdnSttsHstry);
		if (!retSuccess) {
			// 예외를 발생시켜서 오류메세지를 보내고 DB Rollback
			throw new RuntimeException("단속 삭제 중 단속 대장의 단속상태코드 변경에 실패하였습니다.");
		}

		Map<String, Object> paramMap = new HashMap<String, Object>();
		List<String> crdnIdList = Arrays.asList(crdn.getCrdnId());
		paramMap.put("crdnIDs", crdnIdList);
		paramMap.put("removedBy", UserInfo.current().getId());

        // 단속(TB_CRDN) 대장을 삭제 한다.
		effected = crdnUpdtMapper.deleteCrdn(paramMap);
        if (effected != 1) {
            // 예외를 발생시켜서 오류메세지를 보내고 DB Rollback
            throw new RuntimeException("단속 대장 삭제에 실패하였습니다.");
        }

        // 단속(TB_CRDN) 대장을 삭제 한다.
        effected = crdnUpdtMapper.deleteCrdnAdi(paramMap);
        if (effected != 1) {
            // 예외를 발생시켜서 오류메세지를 보내고 DB Rollback
            throw new RuntimeException("단속 부가 정보 삭제에 실패하였습니다.");
        }

        retMessage = "[S] 작업이 정상 처리 되었습니다.";

        return retMessage;
	}

}
