package cokr.xit.ens.biz.iup.billpay.service;

import cokr.xit.ens.biz.iup.domain.VKakaoNoticeInfo;
import cokr.xit.ens.biz.iup.domain.VKakaoNoticeInfoSn;
import cokr.xit.ens.core.exception.code.EnsErrCd;
import cokr.xit.ens.core.utils.CmmnUtil;
import cokr.xit.ens.modules.common.ctgy.intgrnbill.kko.model.BillKkoApiRespDTO;
import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillReqSeCd;
import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.code.BillSeCd;
import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.BillHist;
import cokr.xit.ens.modules.common.ctgy.intgrnbill.support.entity.repository.BillHistRepository;
import cokr.xit.ens.modules.common.ctgy.sys.mng.domain.OrgMng;
import cokr.xit.ens.modules.common.domain.support.FieldError;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@Component
public abstract class IupBillKkoPayUseSysService {

    @Autowired
    private BillHistRepository billHistRepository;


    /**
     * 청구서 이력 저장 - 요청
     *
     * @param reqSeCd
     * @param billerUserKey
     * @param orgCd
     * @param mParam
     * @return
     */
    protected BillHist addBillHistByReqInfo(BillReqSeCd reqSeCd, String billerUserKey, String orgCd, String billUid, Map<String, Object> mParam) {
        BillHist billHist = BillHist.builder()
                .billSe(BillSeCd.bpKko)
                .billUid(billUid)
                .reqSe(reqSeCd)
                .orgMng(orgCd == null ? null : OrgMng.builder().orgCd(orgCd).build())
                .linkedUuid(billerUserKey)
                .requestData(CmmnUtil.toJsonString(mParam))
                .build();
        billHistRepository.save(billHist);
        return billHist;
    }

    /**
     * 청구서 이력 저장 - 응답
     *
     * @param billHist
     * @param respData
     * @param errCd
     * @param errMsg
     */
    protected void modifyBillHistByRespInfo(BillHist billHist, Object respData, EnsErrCd errCd, String errMsg) {
        billHist.setResponseData(CmmnUtil.toJsonString(respData));
        billHist.setError(FieldError.initBuilder()
                .errorCode(CmmnUtil.isEmpty(errCd) ? null : errCd.getCode())
                .errorMessage(errMsg)
                .build());
        billHistRepository.save(billHist);
    }

    /**
     * 청구서 조회
     *
     * @param mParam
     * @return
     */
    abstract public BillKkoApiRespDTO findNoticeInfo(Map<String, Object> mParam);

    /**
     * 납부 가능 조회
     *
     * @param mParam
     * @return
     */
    abstract public BillKkoApiRespDTO findPrepayInfo(Map<String, Object> mParam);

    /**
     * 납부결과 저장
     *
     * @param mParam
     * @return
     */
    abstract public BillKkoApiRespDTO addPayReultIfno(Map<String, Object> mParam);


    /**
     * 청구서조회 "강제징수" 응답메시지 매핑
     *
     * @param title
     * @param orgMng
     * @param vKakaoNoticeInfo
     * @return
     */
    protected Map<String, Object> respNoticeData(String title, OrgMng orgMng, VKakaoNoticeInfo vKakaoNoticeInfo) {
        Map<String, Object> mParam = new HashMap<>();
        mParam.put("biller_user_key", vKakaoNoticeInfo.getEnfrcLevMastrId());
        mParam.put("user_birth ", vKakaoNoticeInfo.getUserBirth());
        mParam.put("amount", vKakaoNoticeInfo.getAmount());
        mParam.put("pay_expire_date", vKakaoNoticeInfo.getPayExpireDate());
        mParam.put("detail_pasng_chrge_sm", vKakaoNoticeInfo.getDetailPasngChrgeSm());
        mParam.put("detail_adi_pasng_chrge_sm", vKakaoNoticeInfo.getDetailAdiPasngChrgeSm());
        return this.makeNoticeData(title, orgMng, mParam);
    }

    /**
     * 청구서조회 "단순미납" 응답메시지 매핑
     *
     * @param title
     * @param orgMng
     * @param vKakaoNoticeInfoSn
     * @return
     */
    protected Map<String, Object> respNoticeSnData(String title, OrgMng orgMng, VKakaoNoticeInfoSn vKakaoNoticeInfoSn) {
        Map<String, Object> mParam = new HashMap<>();
        mParam.put("biller_user_key", vKakaoNoticeInfoSn.getDataId());
        mParam.put("user_birth", vKakaoNoticeInfoSn.getUserBirth());
        mParam.put("amount", vKakaoNoticeInfoSn.getAmount());
        mParam.put("pay_expire_date", vKakaoNoticeInfoSn.getPayExpireDate());
        mParam.put("detail_pasng_chrge_sm", vKakaoNoticeInfoSn.getDetailPasngChrgeSm());
        mParam.put("detail_adi_pasng_chrge_sm", vKakaoNoticeInfoSn.getDetailAdiPasngChrgeSm());
        return this.makeNoticeData(title, orgMng, mParam);
    }

    /**
     * 청구서조회 Response 데이터 생성
     *
     * @param title
     * @param orgMng
     * @param mParam
     * @return
     */
    protected Map<String, Object> makeNoticeData(String title, OrgMng orgMng, Map<String, Object> mParam) {

//        Map<String, Object> bank_accounts = new HashMap<>();
//        bank_accounts.put("bank_code", "");
//        bank_accounts.put("account_no", "");
//        bank_accounts.put("holder_name", "");
//        bank_accounts.put("sender_name", "");
//        bank_accounts.put("account_type", "");


        Map<String, Object> result = new HashMap<>();
//        result.put("settlement_code", "");
        result.put("biller_user_key", mParam.get("biller_user_key"));
//        result.put("billed_year_month", "");
//        result.put("ordinal", "");
//        result.put("biller_notice_key", "");
        result.put("title", title);
        result.put("amount", mParam.get("amount"));
//        result.put("tax_free_amount", "");
//        result.put("tax_free_amount", mParam.get("amount")); // 비과세 (카카오에서 답변이 없어서 배포 안함)
//        result.put("vat_amount", "");
        result.put("expire_type", "D1");
        result.put("pay_expire_date", mParam.get("pay_expire_date"));
//        result.put("second_pay_expire_date", "");
//        result.put("bank_accounts", bank_accounts);
        result.put("details", this.makeNoticeDetailsData(mParam));


        Map<String, Object> data = new HashMap<>();
        data.put("result", result);

        return data;
    }

    /**
     * 청구서조회 Response "details" 데이터 생성
     *
     * @param mParam
     * @return
     */
    protected List<Map<String, Object>> makeNoticeDetailsData(Map<String, Object> mParam) {
        Map<String, Object> detail = new HashMap<>();
        detail.put("item_type", "TEXT");
        detail.put("elements", Arrays.asList(String.format("상세 통행료: %s", mParam.get("detail_pasng_chrge_sm"))
                , String.format("상세 부가통행료: %s", mParam.get("detail_adi_pasng_chrge_sm"))));

        List<Map<String, Object>> details = Arrays.asList(detail);
        return details;
    }

}
