package com.oqpo.api.service.sttlmng;


import com.oqpo.api.entity.loanmng.LoanMgntBaseInfoEntity;
import com.oqpo.api.entity.loanmng.LoanMgntDtlHstEntity;
import com.oqpo.api.entity.settmng.StlMgntBaseInfoEntity;
import com.oqpo.api.enums.DpstPayDvsn;
import com.oqpo.api.enums.MediaDvsn;
import com.oqpo.api.enums.PayType;
import com.oqpo.api.enums.SttlStCd;
import com.oqpo.api.mapper.loanmng.DsptMngMapper;
import com.oqpo.api.mapper.loanmng.UnpaidMngMapper;
import com.oqpo.api.mapper.sttlmng.SttlReqMapper;
import com.oqpo.api.mapper.sttlmng.SttlStateMapper;
import com.oqpo.api.service.CommonService;
import com.oqpo.api.util.DateUtil;
import com.oqpo.api.web.dto.request.GridRequest;
import com.oqpo.api.web.dto.request.sttlmng.SttlConfirmRequest;
import com.oqpo.api.web.dto.response.GridResponse;
import com.oqpo.api.web.dto.response.sttlmng.SttlStateGridResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

@Service
@Slf4j
public class SttlStateService extends CommonService {

    @Autowired
    private SttlStateMapper sttlStateMapper;

    @Autowired
    private SttlReqMapper sttlReqMapper;

    @Autowired
    private DsptMngMapper dsptMngMapper;

    @Autowired
    private UnpaidMngMapper unpaidMngMapper;

    /*
      정산요청 그리드 리스트 조회
     */
    public GridResponse selectSttlStateGridList(String sGubun, String sBrandId, String sStoreId, String sSpplyId, String sItemNm,
                                                String sSttlStCd, String fromDt, String toDt, GridRequest gridRequest) throws Exception {
        int gridPage = gridRequest.getGridPage();
        int gridSize = gridRequest.getGridSize();

        fromDt = fromDt == null ? null : fromDt.replace(".", "");
        toDt = toDt == null ? null : toDt.replace(".", "");

        int gridRecords = sttlStateMapper.selectSttlStateGridCnt(sGubun, sBrandId, sStoreId, sSpplyId, sItemNm, sSttlStCd, fromDt, toDt);
        int gridTotal = fnCalculateGridTotal(gridSize, gridRecords);
        List<StlMgntBaseInfoEntity> entities = sttlStateMapper.selectSttlStateGridList(sGubun, sBrandId, sStoreId, sSpplyId, sItemNm, sSttlStCd, fromDt, toDt, gridRequest);
        List<Object> gridRows = entities.stream()
                .map(m -> SttlStateGridResponse.builder()
                        .viewCd("R")
                        .sttlMgntUnqNo(m.getSttlMgntUnqNo())        /* 정산관리고유번호 */
                        .brandId(m.getBrandId())
                        .brandNm(m.getBrandNm())
                        .storeId(m.getStoreId())
                        .storeNm(m.getStoreNm())
                        .spplyId(m.getSpplyNm())
                        .spplyNm(m.getSpplyNm())
                        .sttlStCd(m.getSttlStCd())          /* 정산상태코드 */
                        .sttlStNm(m.getSttlStNm())          /* 정산상태명 */
                        .sttlReqDt(m.getSttlReqDt())        /* 정산요청일자 */
                        .sttlDt(m.getSttlDt())              /* 정산확정일자 */
                        .sttlReqAmt(m.getSttlReqAmt())
                        .sttlAmt(m.getSttlAmt())
                        .unpaidAmt(m.getUnpaidAmt())
                        .sttlRegMgrId(m.getSttlRegMgrId())
                        .sttlRegMgrNm(m.getSttlRegMgrNm())
                        .loanDvsn(m.getLoanDvsn())
                        .loanDvsnNm(m.getLoanDvsnNm())
                        .build())
                .collect(Collectors.toList());
        return GridResponse.toDTO(gridPage, gridTotal, gridRecords, gridRows);
    }

    /* 정산완료  */
    @Transactional
    public void endSttl(String userId, SttlConfirmRequest sttlConfirmRequest) throws Exception {
        // 정산기본정보 조회
        StlMgntBaseInfoEntity entity = sttlReqMapper.selectStlMgntBaseInfo(sttlConfirmRequest.getSttlMgntUnqNo());

        // 정산관리기본정보 - 정산상태코드 변경
        StlMgntBaseInfoEntity stlEntity = new StlMgntBaseInfoEntity();
        stlEntity.setSttlMgntUnqNo(sttlConfirmRequest.getSttlMgntUnqNo());
        stlEntity.setSttlStCd(SttlStCd.STTL_CONFIRM.getCd());
        stlEntity.setSttlDt(DateUtil.getCurrentDate());
        stlEntity.setSttlAmt(entity.getSttlReqAmt()); // 정산요청금액을 정산금액으로 지정한다.
        sttlReqMapper.updateStlMgntBaseInfo4SttlConfirm(userId, stlEntity);

        // 매장의 계좌잔액이 있은 경우 정산지급 처리를 한다.
        // 매장 계좌잔액 조회
        LoanMgntBaseInfoEntity loanEntity = dsptMngMapper.selectLoanMgntBaseInfo(entity.getBrandId(), entity.getStoreId());
        if (loanEntity.getAcctBal() > 0) {
            // 계좌잔액이 정산요청금액 이상인 경우 정산요청금액을 지급처리하고 정산 데이터는 수납처리한다.
            // 계좌잔액이 정산요청금액 미만인 경우 계좌잔액을 지급처리하고 정산 데이터는 일부 수납처리한다. (미납금 발생)
            String rcptYn; // 수납완료여부
            long rcptAmt = 0; // 수납금액
            if (loanEntity.getAcctBal() >= entity.getSttlReqAmt()) {
                rcptAmt = entity.getSttlReqAmt();
                rcptYn = "Y";
            } else {
                rcptAmt = loanEntity.getAcctBal();
                rcptYn = "N";
            }

            // 1. 여신관리기본정보 처리
            long trscBfBal = loanEntity.getAcctBal();
            long trscAfBal = loanEntity.getAcctBal() - rcptAmt;
            loanEntity.setAcctBal(trscAfBal); // 계좌잔액
            loanEntity.setUseAmtTotal(loanEntity.getUseAmtTotal() - rcptAmt); // 사용금액합계 감소
            sttlReqMapper.updateLoanMgntBaseInfo4SttlReqProc(userId, loanEntity);

            // 2. 여신관리상세이력
            LoanMgntDtlHstEntity hstEntity = new LoanMgntDtlHstEntity();
            hstEntity.setLoanMgntUnqNo(loanEntity.getLoanMgntUnqNo());
            hstEntity.setLoanRegDt(DateUtil.getCurrentDate());
            hstEntity.setLoanRegTm(DateUtil.getCurrentTime());
            hstEntity.setDpstPayDvsn(DpstPayDvsn.PAYMENT.getCd());
            hstEntity.setMediaDvsn(MediaDvsn.SETTLMENT.getCd());
            hstEntity.setPayType(PayType.STTL_PAY.getCd());
            hstEntity.setTrscAmt(rcptAmt); // 거래금액
            hstEntity.setTrscBfBal(trscAfBal);
            hstEntity.setTrscAfBal(trscBfBal);
            dsptMngMapper.insertLoanMgntDtlHst(userId, hstEntity);

            // 3. 정산관리기본정보 수납처리
            stlEntity.setRcptYn(rcptYn); // 수납여부
            stlEntity.setRcptAmt(rcptAmt); // 수납금액
            sttlReqMapper.updateStlMgntBaseInfo4Rcpt(userId, stlEntity);
        }
    }

}
