package cokr.xit.fims.cvlc.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 com.fasterxml.jackson.databind.ObjectMapper;

import cokr.xit.base.code.dao.CodeMapper;
import cokr.xit.base.code.service.CodeQuery;
import cokr.xit.base.user.dao.UserMapper;
import cokr.xit.fims.base.FimsUser;
import cokr.xit.fims.crdn.CrdnQuery;
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.cvlc.CrdnCvlcpt;
import cokr.xit.fims.cvlc.dao.AnswerWordsMapper;
import cokr.xit.fims.cvlc.dao.CrdnCvlcptMapper;
import cokr.xit.fims.cvlc.dao.SoCvlcptIndviDmndMapper;
import cokr.xit.fims.mngt.service.bean.TaskProcessor;
import cokr.xit.foundation.UserInfo;
import cokr.xit.foundation.component.AbstractBean;
import cokr.xit.foundation.data.DataObject;
import cokr.xit.interfaces.smg.Petition;
import cokr.xit.interfaces.smg.service.bean.SmgSenderBean;

/** 민원 주 기능 Bean
 * @author leebj
 */
@Component("crdnCvlcptMainBean")
public class CrdnCvlcptMainBean extends AbstractBean {
	@Resource(name="smgSenderBean")
	protected SmgSenderBean smgSenderBean;
	@Resource(name = "codeMapper")
	private CodeMapper codeMapper;
	@Resource(name = "userMapper")
	private UserMapper userMapper;
	@Resource(name = "crdnCvlcptMapper")
	private CrdnCvlcptMapper crdnCvlcptMapper;
	@Resource(name = "answerWordsMapper")
	private AnswerWordsMapper answerWordsMapper;
	@Resource(name = "soCvlcptIndviDmndMapper")
	SoCvlcptIndviDmndMapper soCvlcptIndviDmndMapper;
	@Resource(name = "crdnInfoMapper")
	private CrdnInfoMapper crdnInfoMapper;
	@Resource(name = "crdnInstMapper")
	private CrdnInstMapper crdnInstMapper;
	@Resource(name = "crdnUpdtMapper")
	private CrdnUpdtMapper crdnUpdtMapper;

	/**민원 원본 정보를 조회한다.
	 * @param query 조회 요청
	 * @return 민원 원본 정보
	 */
	public DataObject getCivilComplaintOriginalInfo(CrdnQuery query) {
		return crdnCvlcptMapper.selectCivilComplaintOriginalInfo(query);
	}

	/**민원 처리 정보를 수정한다.
	 * @param editDataExist 편집 정보 존재 여부, crdnCvlcpt 민원 정보
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public boolean updateCvlcptPrcsSe(boolean editDataExist, CrdnCvlcpt cvlcpt) {
		UserInfo userInfo = currentUser();
		DataObject params = new DataObject()
			.set("currentUser", userInfo)
			.set("crdnCvlcpt", cvlcpt)
			.set("editDataExist", editDataExist ? "Y" : "N");
		return crdnCvlcptMapper.updateCvlcptProcessSection(params) == 1;
	}

	/** 답변전송 인터페이스 테이블에 자료를 등록한다.
	 * @param isSendBack 반송여부, cvlcptLinkId 민원 연계 ID
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public boolean insertTransmitInfo(boolean isSendBack, String cvlcptLinkId) {
		//민원처리정보 조회
		DataObject cvlcptInfo = crdnCvlcptMapper.selectCivilComplaintProcessInfo(cvlcptLinkId);

		//전송 인터페이스 테이블 등록
		final ObjectMapper mapper = new ObjectMapper();
		Map<String,String> cvlcptLink = new HashMap<>();
		this.setLinkObj(cvlcptLink, cvlcptInfo, isSendBack);

		if (!isEmpty(cvlcptInfo.string("INTERFACE_SEQ_N"))) {
			Petition petition = mapper.convertValue(cvlcptLink, Petition.class);
			return smgSenderBean.createReply(petition);
		} else if (!cvlcptInfo.string("DTL_ID").equals("")) {
			return  false;
		} else
			throw new RuntimeException("[F]민원 연계 오류");
	}

	public void setLinkObj(Map<String,String> cvlcptLink, DataObject cvlcptInfo, boolean isSendBack) {
		if (!isEmpty(cvlcptInfo.string("INTERFACE_SEQ_N"))) {
			cvlcptLink.put("interfaceSeqN", cvlcptInfo.string("CVLCPT_LINK_ID"));
			cvlcptLink.put("sysGubunC", "EC010008");                              //시스템 구분("EC010008")
			cvlcptLink.put("petiAncCodeV", cvlcptInfo.string("PETI_ANC_CODE_V")); //민원 기관 코드(최초신청기관코드)
			cvlcptLink.put("petiGubunC", isSendBack ? "140" : "180");
			cvlcptLink.put("sendYnC", isSendBack ? "1" : "2");

			cvlcptLink.put("petiNoC", cvlcptInfo.string("CVLCPT_APLY_NO"));//민원 신청 번호
			cvlcptLink.put("civilNoC", cvlcptInfo.string("CVLCPT_RCPT_NO"));//민원 접수 번호
			cvlcptLink.put("petiTitleV", cvlcptInfo.string("CVLCPT_APLY_TTL_NM"));//민원제목
			cvlcptLink.put("civilGistV", cvlcptInfo.string("CVLCPT_GIST"));//민원요지
			cvlcptLink.put("civilAbstractL", cvlcptInfo.string("CVLCPT_PRCS_SMRY"));//민원 처리 요약
			cvlcptLink.put("ancCodeV", cvlcptInfo.string("CVLCPT_PRCS_NSTT_CD"));//기관 코드
			cvlcptLink.put("pcdDeptV", cvlcptInfo.string("CVLCPT_PRCS_DEPT_CD"));//처리 부서 코드
			cvlcptLink.put("pcdAncCodeV", cvlcptInfo.string("CVLCPT_PRCS_DEPT_CD"));//민원 실 처리 기관 코드
			cvlcptLink.put("pcdDeptNmV", cvlcptInfo.string("CVLCPT_PRCS_DEPT_NM"));//민원 처리 부서명
			cvlcptLink.put("dutyIdV", cvlcptInfo.string("CVLCPT_PRCS_PIC_NM"));//민원 처리 담당자 명
			cvlcptLink.put("pcdEmailV", cvlcptInfo.string("CVLCPT_PRCS_PIC_EMAIL"));//담당자 이메일
			cvlcptLink.put("pcdTelV", cvlcptInfo.string("CVLCPT_PRCS_PIC_TELNO"));//담당자 전화번호
			cvlcptLink.put("pcdRstContL", cvlcptInfo.string("CVLCPT_PRCS_RSLT_CN"));//민원 처리 결과
			cvlcptLink.put("doRegD", cvlcptInfo.string("CVLCPT_PRCS_CMPTN_DT"));//민원 처리 완료 일자

			cvlcptLink.put("regD", (new SimpleDateFormat("yyyyMMddHHmmss")).format(new Date())); // 등록 일자
			//not use
			cvlcptLink.put("pcdRstContAttachYnC", "N");//민원 처리 결과 첨부 여부
			cvlcptLink.put("pcdGubunV", "");//처리 구분1
			cvlcptLink.put("pcdGubun2V", "");//처리 구분2
			cvlcptLink.put("pcdGubun3V", "");//처리 구분3
			//DB --> XML
			cvlcptLink.put("applyGubunC", "N");//완료구분
			cvlcptLink.put("sendD", "");//송신 일자
			cvlcptLink.put("applyD", "");//적용 일자
			cvlcptLink.put("sendInterfaceSeqN", "");//전송인터페이스키
			cvlcptLink.put("sendStatus", "");//전송상태
			cvlcptLink.put("sendStatusMsg", "");//전송상태메시지

		} else if (!isEmpty(cvlcptInfo.get("DTL_ID"))) {
		} else
			throw new RuntimeException("[F]민원 연계 오류");
	}

	/**답변 내용을 초기화한다.
	 * @param cvlcptLinkId 민원 연계 아이디
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public boolean initCvlcptPrcsRsltCn(String cvlcptLinkId) {
		CrdnCvlcpt crdnCvlcpt = new CrdnCvlcpt();
		crdnCvlcpt.setCvlcptLinkId(cvlcptLinkId);

		return crdnCvlcptMapper.initCvlcptPrcsRsltCn(crdnCvlcpt) == 1;
	}


	/**지정한 민원 자료의 답변 예정 문구를 반환한다.
	 * @param crdnId 단속 ID
	 * @return 답변 예정 문구
	 */
	public String mappingAnswerWords(String crdnId, String currentSggCd, String currentUserAcnt) {
		DataObject dataInfo = crdnInfoMapper.selectCrdnInfo(crdnId);

		CrdnQuery crdnQuery = new CrdnQuery()
			.setTaskSeCd(dataInfo.string("TASK_SE_CD"))
			.setSggCd(dataInfo.string("SGG_CD"));

		if (dataInfo.string("CVLCPT_PRCS_CD").equals("02")) {
			crdnQuery.setAnsSeCd("3");
			crdnQuery.setAnsRsnCd("3"+dataInfo.string("VLTN_CD"));

			if ("301".equals(crdnQuery.getAnsRsnCd()) && "Y".equals(dataInfo.string("DSTRBNC_YN"))) {
				crdnQuery.setDstrbncYn("Y");
			}

		} else if (dataInfo.string("CVLCPT_PRCS_CD").equals("03")
			|| dataInfo.string("CVLCPT_PRCS_CD").equals("04")){
			crdnQuery.setAnsSeCd(dataInfo.string("LEVY_EXCL_SE_CD"));
			crdnQuery.setAnsRsnCd(dataInfo.string("LEVY_EXCL_RSN_CD"));
		} else {
			return "";
		}

		DataObject bodyWordsInfo = answerWordsMapper.selectCvlcptAnswerWordsInfo(crdnQuery);
		DataObject basicWordsInfo = answerWordsMapper.selectCvlcptAnswerBasicWordsInfo(crdnQuery);

		if (bodyWordsInfo == null)
			return "";

		String body = bodyWordsInfo.string("PRCS_RSLT_CN");
		String head = basicWordsInfo.string("HEADER_CN");
		String tail = basicWordsInfo.string("FOOTER_CN");

		if (isEmpty(body))
			return "";

		String joinWords = head + "\n\n" + body + "\n\n" + tail;

		FimsUser currentUser = userMapper.getUser(
			new DataObject()
				.set("account", currentUserAcnt)
				.set("orgID", currentSggCd)
		);

		return replaceMacroString(joinWords , currentUser.getPhoneNo(), currentUser.getName());
	}

	/**문구의 매크로 문자열을 치환한다.
	 * @param joinWords 전체 문구, telNo 담당자 전화번호
	 * @return 치환된 문구
	 */
	private String replaceMacroString(String joinWords, String telNo, String picNm) {
		joinWords = joinWords.replaceAll("＠", "@");
		String[] splited = joinWords.split(CrdnCvlcpt.MACRO_SEQ);
		var seqCount = splited.length - 1;
		if (seqCount > 0){
			int seq = 1;
			for(; seq <= seqCount; seq++){
				joinWords = joinWords.replaceFirst(CrdnCvlcpt.MACRO_SEQ, Integer.toString(seq));
			}
		}

		return joinWords
			.replace(CrdnCvlcpt.MACRO_TELNO, telNo)
			.replace(CrdnCvlcpt.MACRO_PIC_NM, picNm);
	}

	/**민원 답변 기본 문구 설정을 조회한다.
	 * @param query 조회 요청
	 * @return 민원 답변 기본 문구
	 */
	public DataObject selectCvlcptAnswerBasicWordsInfo(CrdnQuery crdnQuery) {
		return answerWordsMapper.selectCvlcptAnswerBasicWordsInfo(crdnQuery);
	}

	/**민원 답변 본문 문구 목록을 조회한다.
	 * @param query 조회 요청, ansSeCd 답변구분코드
	 * @return 민원 답변 본문 문구 목록
	 */
	public List<DataObject> selectAnswerBodyWordsList(CrdnQuery crdnQuery, String ansSeCd) {
		return switch (ansSeCd) {
		case "3" -> answerWordsMapper.selectLevyCaseWordsList(crdnQuery);
		case "2" -> answerWordsMapper.selectWarningCaseWordsList(crdnQuery);
		case "1" -> answerWordsMapper.selectNonlevyCaseWordsList(crdnQuery);
		default -> null;
		};
	}

	/**민원답변 기본문구를 저장한다.
	 * @param crdnCvlcpt 민원답변 기본문구 정보
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public boolean saveAnswerBasicWordsInfo(CrdnCvlcpt crdnCvlcpt) {
		CrdnQuery query = new CrdnQuery()
			.setSggCd(crdnCvlcpt.getSggCd())
			.setTaskSeCd(crdnCvlcpt.getTaskSeCd());
		DataObject info = answerWordsMapper.selectCvlcptAnswerBasicWordsInfo(query);

		if (isEmpty(info)) {
			return answerWordsMapper.insertAnswerBasicWordsInfo(crdnCvlcpt) == 1;
		} else {
			return answerWordsMapper.updateAnswerBasicWordsInfo(crdnCvlcpt) == 1;
		}
	}

	/**민원답변 본문문구를 저장한다.
	 * @param crdnCvlcpt 민원답변 본문문구 정보
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public boolean saveAnswerBodyWordsInfo(CrdnCvlcpt crdnCvlcpt) {
		if (isEmpty(crdnCvlcpt.getAnsWordsId())) {
			String codeGroupId = TaskProcessor.get().getVltnCdGrp(crdnCvlcpt.getTaskSeCd());
			String code = "";
			if (crdnCvlcpt.getAnsRsnCd().startsWith("1") || crdnCvlcpt.getAnsRsnCd().startsWith("2")) {
				if (crdnCvlcpt.getAnsRsnCd().startsWith("1")) {
					crdnCvlcpt.setPrcsSmry("과태료 미부과");
				}
				if (crdnCvlcpt.getAnsRsnCd().startsWith("2")) {
					crdnCvlcpt.setPrcsSmry("과태료 계고");
				}

				codeGroupId = "FIM022";
				code = crdnCvlcpt.getAnsRsnCd();

			} else if (crdnCvlcpt.getAnsRsnCd().startsWith("3")) {
				crdnCvlcpt.setPrcsSmry("과태료 부과");

				code = crdnCvlcpt.getAnsRsnCd().substring(1);
			}

			CodeQuery codeQuery = new CodeQuery()
				.setGroupIDs(codeGroupId)
				.setCodes(code);
			List<DataObject> codeList = codeMapper.getCodeList(codeQuery);
			crdnCvlcpt.setAnsRsnNm(codeList.get(0).string("CODE_VAL"));

			return answerWordsMapper.insertAnswerBodyWordsInfo(crdnCvlcpt) == 1;
		} else {
			return answerWordsMapper.updateAnswerBodyWordsInfo(crdnCvlcpt) == 1;
		}
	}

	/**새올 요청 자료 목록을 조회한다.
	 * @param query 조회 요청
	 * @return 새올 요청 자료 목록
	 */
	public List<DataObject> selectDmndDataList(CrdnQuery query) {
		return soCvlcptIndviDmndMapper.selectDmndDataList(query.setOrderBy("INDIV_ID"));
	}

	/**새올 요청 자료를 생성한다.
	 * @param crdnCvlcpt 새올요청자료 정보
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public boolean createDmndDataInfo(CrdnCvlcpt crdnCvlcpt) {
		return soCvlcptIndviDmndMapper.insertDmndDataInfo(crdnCvlcpt) == 1;
	}

	/**새올 요청 자료를 삭제한다.
	 * @param indivIds 개별요청 ID 목록
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public boolean removeDmndDataInfo(String... indivIds) {
		if (isEmpty(indivIds)) return false;

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

		return soCvlcptIndviDmndMapper.deleteDmndDataInfo(paramMap) >= 1;
	}
}