package cokr.xit.fims.wpm;

import java.util.List;
import java.util.function.BiConsumer;

import cokr.xit.fims.sndb.SndngDtl;
import cokr.xit.foundation.AbstractObject;
import lombok.Getter;
import lombok.Setter;

/**우편모아 종적파일 정보
 * <ul><li>no - 번호</li>
 *     <li>mailType - 우편구분</li>
 *     <li>registPostOffice - 접수우체국</li>
 *     <li>deliveryStatus - 발송상태</li>
 *     <li>generalNo - 일반번호</li>
 *     <li>registrationNo - 창구접수등기번호</li>
 *     <li>registeredNo - 등기번호</li>
 *     <li>returnYN - 환부여부</li>
 *     <li>standardYN - 규격여부</li>
 *     <li>weight - 중량</li>
 *     <li>pieceCount - 통수</li>
 *     <li>fee - 요금</li>
 *     <li>remark - 비고</li>
 *     <li>payee - 수취인</li>
 *     <li>zipCode - 우편번호</li>
 *     <li>address - 기본주소</li>
 *     <li>detailAddress - 상세주소</li>
 *     <li>docNo - 문서번호</li>
 *     <li>docTitle - 문서제목</li>
 *     <li>deptName - 담당부서</li>
 *     <li>manager - 담당자</li>
 *     <li>deliveryPostOffice - 배달우체국</li>
 *     <li>deliveryResult - 배달결과</li>
 *     <li>returnReason - 반송사유</li>
 *     <li>deliveryDate - 배달일</li>
 *     <li>recipient - 수령인</li>
 *     <li>recipientRelation - 수령인과의 관계</li>
 *     <li>contact - 연락처</li>
 *     <li>mailingDate - 발송일</li>
 *     <li>recipientTelno - 수취인 전화번호</li>
 *     <li>recipientMobileNo - 수취인 핸드폰번호</li>
 *     <li>createdAt - 등록일</li>
 *     <li>useYN - 사용여부</li>
 * </ul>
 * @author mjkhan
 */
@Getter
@Setter
public class WoopyonMoa extends AbstractObject {
	public static final List<BiConsumer<WoopyonMoa, String>> setters(List<String> headers) {
		return headers.stream()
			.map(header -> {
				BiConsumer<WoopyonMoa, String> setter = switch (header) {
				case "번호" -> (row, str) -> {if (!isEmpty(str)) row.setNo(toInt(str));};
				case "우편구분" -> (row, str) -> row.setMailType(str);
				case "접수우체국" -> (row, str) -> row.setRegistPostOffice(str);
				case "발송상태" -> (row, str) -> row.setDeliveryStatus(str);
				case "일반번호" -> (row, str) -> row.setGeneralNo(str);
				case "창구접수등기번호" -> (row, str) -> row.setRegistrationNo(str);
				case "등기번호"  -> (row, str) -> row.setRegisteredNo(str);
				case "환부여부" -> (row, str) -> row.setReturnYN(str);
				case "규격", "규격여부" -> (row, str) -> row.setStandardYN(str);
				case "중량" -> (row, str) -> {if (!isEmpty(str)) row.setWeight(toInt(str));};
				case "통수" -> (row, str) -> {if (!isEmpty(str)) row.setPieceCount(toInt(str));};
				case "요금" -> (row, str) -> {if (!isEmpty(str)) row.setFee(toLong(str));};
				case "비고" -> (row, str) -> row.setRemark(str);
				case "수취인" -> (row, str) -> row.setPayee(str);
				case "우편번호" -> (row, str) -> row.setZipCode(str);
				case "기본주소" -> (row, str) -> row.setAddress(str);
				case "상세주소" -> (row, str) -> row.setDetailAddress(str);
				case "문서번호" -> (row, str) -> row.setDocNo(str);
				case "문서제목" -> (row, str) -> row.setDocTitle(str);
				case "담당부서" -> (row, str) -> row.setDeptName(str);
				case "담당자" -> (row, str) -> row.setManager(str);
				case "배달우체국" -> (row, str) -> row.setDeliveryPostOffice(str);
				case "배달결과" -> (row, str) -> row.setDeliveryResult(str);
				case "반송사유" -> (row, str) -> row.setReturnReason(str);
				case "배달일" -> (row, str) -> row.setDeliveryDate(str);
				case "수령인" -> (row, str) -> row.setRecipient(str);
				case "수령인과의 관계" -> (row, str) -> row.setRecipientRelation(str);
				case "등록일" -> (row, str) -> row.setCreatedAt(str);
				case "연락처" -> (row, str) -> row.setContact(str);
				case "발송일" -> (row, str) -> row.setMailingDate(str);
				case "수취인 전화번호" -> (row, str) -> row.setRecipientTelno(str);
				case "휴대폰", "수취인 핸드폰번호" -> (row, str) -> row.setRecipientMobileNo(str);
				default -> null;
				};
				return setter;
			})
			.filter(setter -> setter != null)
			.toList();
	}

	/** 번호 */
	private int no;
	/** 우편구분 */
	private String mailType;
	/** 접수우체국 */
	private String registPostOffice;
	/** 발송상태 */
	private String deliveryStatus;
	/** 일반번호 */
	private String generalNo;
	/** 창구접수등기번호 */
	private String registrationNo;
	/** 등기번호 */
	private String registeredNo;
	/** 환부여부 */
	private String returnYN;
	/** 규격여부 */
	private String standardYN;
	/** 중량 */
	private int weight;
	/** 통수 */
	private int pieceCount;
	/** 요금 */
	private long fee;
	/** 비고 */
	private String remark;
	/** 수취인 */
	private String payee;
	/** 우편번호 */
	private String zipCode;
	/** 기본주소 */
	private String address;
	/** 상세주소 */
	private String detailAddress;
	/** 문서번호 */
	private String docNo;
	/** 문서제목 */
	private String docTitle;
	/** 담당부서 */
	private String deptName;
	/** 담당자 */
	private String manager;
	/** 배달우체국 */
	private String deliveryPostOffice;
	/** 배달결과 */
	private String deliveryResult;
	/** 반송사유 */
	private String returnReason;
	/** 배달일 */
	private String deliveryDate;
	/** 수령인 */
	private String recipient;
	/** 수령인과의 관계 */
	private String recipientRelation;
	/** 연락처 */
	private String contact;
	/** 발송일 */
	private String mailingDate;
	/** 수취인 전화번호 */
	private String recipientTelno;
	/** 수취인 핸드폰번호 */
	private String recipientMobileNo;
	/** 등록일 */
	private String createdAt;
	/** 사용여부 */
	private String useYN;

	public void update(SndngDtl sndngDtl) {
		sndngDtl.setRgNo(ifEmpty(registeredNo, registrationNo));         // 등기번호
		String dlvrYmd = blankIfEmpty(deliveryDate).replace("-", "");
		sndngDtl.setDlvrYmd(dlvrYmd.length() > 8 ? dlvrYmd.substring(0, 8) : dlvrYmd); // 배달일
		sndngDtl.setActlRcpnNm(recipient);        // 실제 수령인
		sndngDtl.setRcpnRelNm(recipientRelation); // 수령인 관계명
		setUndelivered(sndngDtl);                 // 미배달 사유
		setSndngDtlSttsCd(sndngDtl);              // 상세상태코드
	}

	private void setUndelivered(SndngDtl sndngDtl) {
		if (isEmpty(returnReason)) return;

		sndngDtl.setUndlvrRsnNm(returnReason); // 미배달사유 이름
		// 반송사유: 수취인부재, 주소불명, 수취인불명, 이사불명, 수취거절, 배달누락, 기타, 폐문부재
		String code = switch (returnReason) { // EGP010
		case "수취인부재" -> "5";
		case "주소불명" -> "4";
		case "수취인불명" -> "10";
		case "이사불명" -> "8";
		case "수취거절" -> "1";
		case "배달누락" -> "11";
		case "폐문부재" -> "12";
		default -> "7";
		};
		sndngDtl.setUndlvrRsnCd(code); // 미배달사유 코드
	}

	private void setSndngDtlSttsCd(SndngDtl sndngDtl) {
/*
		발송상태: 발송대기, 발송요청, 검수확인, 우체국발송, 배달완료
		배달결과: 배달완료, 반송, 환부불능, 기타
*/
		String delivery = deliveryStatus;
		if (!"배달완료".equals(delivery))
			delivery = deliveryResult;

		String code = null;
		if ("배달완료".equals(delivery))
			code = "04"; // 발송확인(FIM050)
		else if ("반송".equals(delivery))
			code = "05";
		else if (!isEmpty(returnReason))
			code = "05"; //반송
		else code = "03"; //발송
		if (isEmpty(code)) return;

		sndngDtl.setSndngDtlSttsCd(code);
	}
}