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

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import cokr.xit.fims.payer.Payer;
import cokr.xit.fims.payer.PayerQuery;
import cokr.xit.fims.payer.dao.PayerMapper;
import cokr.xit.foundation.AbstractComponent;
import cokr.xit.foundation.data.DataObject;
import cokr.xit.interfaces.lvis.service.bean.VehicleInfoBean;
import cokr.xit.interfaces.lvis.service.reg.BasicInfoRequest;
import cokr.xit.interfaces.lvis.service.reg.BasicInfoResponse;

/**납부자 정보 관리 Bean
 *
 * <p>상세 설명:
 *
 * <pre>
 * ============ 변경 이력 ============
 * 2023-08-18	mjkhan 최초 작성
 * ================================
 * </pre>
 */
@Component("payerBean")
public class PayerBean extends AbstractComponent {
	/** 납부자 정보 DAO */
	@Resource(name = "payerMapper")
	private PayerMapper payerMapper;
	@Resource(name = "vehicleInfoBean")
	private VehicleInfoBean vehicleInfoBean;

	/**지정한 조건에 따라 납부자 목록을 조회하여 반환한다.
	 * @param req 납부자 조회 조건
	 * @return 납부자 목록
	 */
	public List<DataObject> getPayerList(PayerQuery req) {
		return payerMapper.selectPayerList(req);
	}

	/**지정한 조건에 따라 납부자 객체들을 반환한다.
	 * @param req 납부자 조회 조건
	 * @return 납부자 객체 목록
	 */
	public List<Payer> getPayers(PayerQuery req) {
		return payerMapper.selectPayers(req);
	}

	public Payer getPayer(String vhrno, String rtpyrNo) {
		PayerQuery req = new PayerQuery().setVhrno(vhrno).setRtpyrNo(rtpyrNo);
		List<Payer> payers = getPayers(req);
		return !payers.isEmpty() ? payers.get(0) : null;
	}

	/**납부자 정보를 등록한다.
	 * @param payer 납부자
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public boolean create(Payer payer) {
		DataObject params = new DataObject()
			.set("roadNmCd", payer.getRoadNmCd())
			.set("udgdSeCd", payer.getUdgdSeCd())
			.set("bmno", payer.getBmno())
			.set("bsno", payer.getBsno());
		DataObject info = payerMapper.selectAddrInfo(params);
		if (info != null) {
			payer.setAddrSeCd("02");
			payer.setZip(info.string("ZIP"));
			payer.setBldgMngNo(info.string("BLDG_MNG_NO"));
		}
		return payerMapper.insert(payer);
	}

	/**납부자 정보를 수정한다.
	 * @param payer 납부자
	 * @return 저장 여부
	 * <ul><li>저장됐으면 true</li>
	 *     <li>그렇지 않으면 false</li>
	 * </ul>
	 */
	public boolean update(Payer payer) {
		return payerMapper.update(payer);
	}

	/**납부자 정보를 삭제한다.
	 * @param rtpyrIds 납부자 아이디
	 * @return 저장된 정보수
	 */
	public int remove(String... rtpyrIds) {
		return payerMapper.delete(rtpyrIds);
	}

	public List<Payer> getVehicleOwners(List<BasicInfoRequest> reqs) {
		Map<String, BasicInfoResponse> vehicleMap = vehicleInfoBean.getBasicInfo(reqs).stream()
			.collect(Collectors.toMap(resp -> resp.getBasicInfo().getKey(), resp -> resp));

		return vehicleMap.values().stream()
			.map(resp -> getPayer(resp.getBasicInfo()))
			.toList();
	}

	/**시군구 코드와 차량 기본정보에서 납부자 정보를 생성하거나, 등록정보에서 조회하여 반환한다.(차량번호 / 납부자 번호 / 시군구 기준)
	 * @param basicInfo 차량 기본정보
	 * @return 납부자 정보
	 */
	private Payer getPayer(BasicInfoResponse.BasicInfo basicInfo) {
		Payer payer = new Payer();

		payer.setSggCd(basicInfo.getSggCd());
		String vhrno = basicInfo.getVhrno();
		payer.setVhrno(vhrno);
		payer.setRtpyrSeCd(basicInfo.getMber_se_code());
		String rtpyrNo = basicInfo.getMber_se_no();
		payer.setRtpyrNo(rtpyrNo);
		payer.setRtpyrNm(basicInfo.getMber_nm());
		payer.setRtpyrTelno(basicInfo.getTelno());
		payer.setRoadNmCd(basicInfo.getUse_strnghld_road_nm_code());
		payer.setUdgdSeCd(basicInfo.getUsgsrhld_undgrnd_buld_se_code());
		String str = basicInfo.getUse_strnghld_buld_main_no();
		if (!isEmpty(str))
			payer.setBmno(toInt(str));
		str = basicInfo.getUse_strnghld_buld_sub_no();
		if (!isEmpty(str))
			payer.setBsno(toInt(str));
		payer.setStdgCd(basicInfo.getUse_strnghld_legaldong_code());
		payer.setDongCd(basicInfo.getUse_strnghld_adstrd_code());
		payer.setMtnSeCd(basicInfo.getUse_strnghld_mntn());
		str = basicInfo.getUse_strnghld_lnbr();
		if (!isEmpty(str))
			payer.setMno(toInt(str));
		str = basicInfo.getUse_strnghld_ho();
		if (!isEmpty(str))
			payer.setSno(toInt(str));
		payer.setDtlAddr(basicInfo.getUse_strnghld_adres_nm());
		payer.setWholAddr(basicInfo.getOwner_adres_full());

		Payer result = create(payer) ? payer : getPayer(vhrno, rtpyrNo);
		if (result != null)
			result.setVehicleInfo(basicInfo);
		return result;
	}
}