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

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.springframework.core.io.ClassPathResource;
import org.springframework.stereotype.Component;

import cokr.xit.base.docs.xls.XLSReader;
import cokr.xit.base.docs.xls.XLSWriter;
import cokr.xit.fims.sndb.SndbQuery;
import cokr.xit.fims.sndb.Sndng;
import cokr.xit.fims.sndb.SndngDtl;
import cokr.xit.fims.sndb.dao.SndngDtlMapper;
import cokr.xit.fims.sndb.dao.SndngMapper;
import cokr.xit.fims.wpm.WoopyonMoa;
import cokr.xit.fims.wpm.WoopyonMoaRequest;
import cokr.xit.foundation.Downloadable;
import cokr.xit.foundation.component.AbstractBean;
import cokr.xit.foundation.data.DataObject;

@Component("woopyonMoaBean")
public class WoopyonMoaBean extends AbstractBean {
	/** 발송 상세 정보 Bean */
	@Resource(name = "sndngMapper")
	private SndngMapper sndngMapper;
	/** 발송 상세 정보 Bean */
	@Resource(name = "sndngDtlMapper")
	private SndngDtlMapper sndngDtlMapper;

	public Downloadable downloadRequest(WoopyonMoaRequest req) {
		try (InputStream input = getTemplate(req.getTemplate())) {
			int rowIndex = 1;
    		XLSWriter xlsx = new XLSWriter().template(input).worksheet(0);

            Sndng sndng = new Sndng();
/*
            sndng.setConKey(epostRcptReg.getConKey()); // 외부연계식별키
            sndng.setDivKb(epostRcptReg.getDivKb());   // 취급 구분
//            sndng.setEpostNoticeId();                // 전자우편 안내문 ID
 */
            sndng.setDivKb(req.getDivKb());   // 취급 구분
            sndng.setSndngSttsCd("03");              // 발송 상태 코드(FIM049) - 03 전송, 01 발송 대기
            sndng.setSndngId(req.getSndngId());      // 발송 ID

            ArrayList<SndngDtl> sndngDtls = new ArrayList<>();

    		for (DataObject row: req.getSndngDtlList()) {
    			xlsx.cell(rowIndex, 0)
					.rowValues(List.of(req.getStandardYN(), req.getWeight(), req.getPieceCount())) // 규격, 중량, 통수
    				.cell(rowIndex, 3)
    				.rowValues(List.of(
    					row.get("RCPN_NM"),                       // 수취인
    					row.get("RCPN_ZIP"),                      // 우편번호
    					row.get("RCPN_ADDR"),                     // 기본주소
    					row.get("RCPN_DTL_ADDR"),                 // 상세주소
    					blankIfEmpty(row.get("RTPYR_MBL_TELNO")), // 휴대폰
    					row.get("SNDNG_DTL_ID"),                  // 문서번호 <- 발송상세아이디
    					row.get("TTL_NM"),                        // 문서제목
    					blankIfEmpty(row.get("ETC_CN"))           // 비고
    				));

    			SndngDtl sndngDtl = new SndngDtl();
/*
                sndngDtl.setConKey(conKey);                        // 외부연계식별키
                sndngDtl.setRgNo(rgstNmbr);                        // 등기 번호
*/
                sndngDtl.setSndngDtlSttsCd("03");                  // 발송 상세 상태 코드(FIM050) - 03 발송
                sndngDtl.setSndngDtlId(row.string("SNDNG_DTL_ID"));

                sndngDtls.add(sndngDtl);

    			++rowIndex;
    		}
    		sndngMapper.updateSndngSttsCd(sndng);
    		for (SndngDtl sndngDtl: sndngDtls) {
                sndngDtlMapper.updateSndngDtlEPost(sndngDtl); // 전자우편 발송상세 내역 수정
    		}
            return xlsx.getDownloadable();
		} catch (Exception e) {
			throw runtimeException(e);
		}
	}

	private InputStream getTemplate(String template) throws Exception {
		return new ClassPathResource("template/" + template).getInputStream();
	}

	public int updateStatus(InputStream input) {
		List<WoopyonMoa> parsed = parse(input);
		if (isEmpty(parsed)) return 0;

		// 발송상세 조회 및 업데이트
		List<String> idList = parsed.stream().map(WoopyonMoa::getDocNo).toList(); // 발송상세ID
		SndbQuery sreq = new SndbQuery().setSndngDtlIds(idList.toArray(new String[idList.size()]));
		List<SndngDtl> details = sndngDtlMapper.selectSndngDetails(sreq);
		if (details.isEmpty()) return 0;

		Map<String, SndngDtl> byDtlId = details.stream().collect(Collectors.toMap(
			SndngDtl::getSndngDtlId,
			sndngDtl -> sndngDtl
		));
		for (WoopyonMoa wpm: parsed) {
			SndngDtl detail = byDtlId.get(wpm.getDocNo());
			if (detail == null) continue;

			wpm.update(detail);
		}

		int affected = 0;

		for (SndngDtl detail: details) {
			affected += sndngDtlMapper.updateSndngDtl(detail);
		}

		return affected;
	}

	static List<WoopyonMoa> parse(InputStream input) {
		XLSReader xlsx = new XLSReader().open(input).worksheet(0);

		List<BiConsumer<WoopyonMoa, String>> setters = WoopyonMoa.setters(xlsx.rowValues(1));
		return xlsx.readValues(2, WoopyonMoa::new, (row, index, str) -> setters.get(index).accept(row, str), null)
			.filter(row -> !isEmpty(row.getDocNo()))
			.toList();
	}
}