package com.oqpo.api.service.loanmng;


import com.oqpo.api.entity.loanmng.LoanMgntBaseInfoEntity;
import com.oqpo.api.entity.loanmng.LoanMgntDsptProcEntity;
import com.oqpo.api.entity.loanmng.LoanMgntDtlHstEntity;
import com.oqpo.api.entity.oper.UserMngEntity;
import com.oqpo.api.enums.DpstPayDvsn;
import com.oqpo.api.enums.DpstStCd;
import com.oqpo.api.enums.MediaDvsn;
import com.oqpo.api.exception.GlobalException;
import com.oqpo.api.mapper.loanmng.DsptMngMapper;
import com.oqpo.api.mapper.oper.UserMngMapper;
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.loanmng.ApproveDsptRequest;
import com.oqpo.api.web.dto.request.loanmng.RejectDsptRequest;
import com.oqpo.api.web.dto.request.loanmng.RemoveDsptRequest;
import com.oqpo.api.web.dto.request.loanmng.ReqDsptRequest;
import com.oqpo.api.web.dto.response.GridResponse;
import com.oqpo.api.web.dto.response.loanmng.DsptMngInfoResponse;
import com.oqpo.api.web.dto.response.loanmng.DsptMngListResponse;
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 DsptMngService extends CommonService {

    @Autowired
    private DsptMngMapper dsptMngMapper;

    @Autowired
    private UserMngMapper userMngMapper;

    /*
      입금관리 그리드 리스트 조회
     */
    public GridResponse selectDsptMngGridList(String sBrandId, String sStoreId, String sDpstStCd, 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 = dsptMngMapper.selectDsptMngGridCnt(sBrandId, sStoreId, sDpstStCd, fromDt, toDt);
        int gridTotal = fnCalculateGridTotal(gridSize, gridRecords);
        List<LoanMgntDsptProcEntity> entities = dsptMngMapper.selectDsptMngGridList(sBrandId, sStoreId, sDpstStCd, fromDt, toDt, gridRequest);
        List<Object> gridRows = entities.stream()
                .map(m -> DsptMngListResponse.builder()
                        .viewCd("R")
                        .dsptMgntNo(m.getDsptMgntNo())
                        .reqDt(m.getReqDt())
                        .reqTm(m.getReqTm())
                        .dpstAmt(m.getDpstAmt())
                        .dpstDt(m.getDpstDt())
                        .dpstNm(m.getDpstNm())
                        .rcvAcctNo(m.getRcvAcctNo())
                        .dpstBnkCd(m.getDpstBnkCd())
                        .dpstBnkNm(m.getDpstBnkNm())
                        .dpstStCd(m.getDpstStCd())
                        .dpstStNm(m.getDpstStNm())
                        .dpstAuthId(m.getDpstAuthId())
                        .dpstAuthNm(m.getDpstAuthNm())
                        .dpstAuthDt(m.getDpstAuthDt())
                        .dpstAuthTm(m.getDpstAuthTm())
                        .dsptRjctDt(m.getDsptRjctDt())
                        .dsptRjctTm(m.getDsptRjctTm())
                        .storeId(m.getStoreId())
                        .storeNm(m.getStoreNm())
                        .brandId(m.getBrandId())
                        .brandNm(m.getBrandNm())
                        .dpstAuthYn(m.getDpstAuthYn())
                        .dsptRjctRsn(m.getDsptRjctRsn())
                        .loanDvsn(m.getLoanDvsn())
                        .loanDvsnNm(m.getLoanDvsnNm())
                        .build())
                .collect(Collectors.toList());
        return GridResponse.toDTO(gridPage, gridTotal, gridRecords, gridRows);
    }

    /* 입금관리 정보 조회 */
    public DsptMngInfoResponse selectDsptMngInfo(String dsptMgntNo) throws Exception {
        LoanMgntDsptProcEntity entity = dsptMngMapper.selectLoanMgntDsptProcInfo(dsptMgntNo);
        return DsptMngInfoResponse.toDTO(entity);
    }

    /* 신규입금 요청 */
    @Transactional
    public void requestDspt(String userId, ReqDsptRequest reqDsptRequest) throws Exception {
        try {
            reqDsptRequest.setDpstDt(reqDsptRequest.getDpstDt().replace(".", ""));

            // 사용자 정보 조회
            UserMngEntity user = userMngMapper.selectUserInfo(userId);

            // 여신관리입금처리
            LoanMgntDsptProcEntity entity = new LoanMgntDsptProcEntity();
            entity.setDsptMgntNo(fnGetDealNo(21, "")); // 입금관리번호
            entity.setReqDt(DateUtil.getCurrentDate());
            entity.setReqTm(DateUtil.getCurrentTime());
            entity.setDpstAmt(reqDsptRequest.getDpstAmt());
            entity.setDpstDt(reqDsptRequest.getDpstDt());
            entity.setDpstNm(reqDsptRequest.getDpstNm());
            entity.setRcvAcctNo(reqDsptRequest.getRcvAcctNo());
            entity.setDpstBnkCd(reqDsptRequest.getDpstBnkCd());
            entity.setDpstStCd(DpstStCd.DPST_REQ.getCd());
            entity.setDpstReqId(userId);
            entity.setDpstReqNm(user.getUserNm());
            entity.setStoreId(reqDsptRequest.getStoreId());
            entity.setBrandId(reqDsptRequest.getBrandId());
            dsptMngMapper.insertLoanMgntDsptProcInfo(userId, entity);
        } catch (GlobalException e) {
            e.getStackTrace();
            throw new GlobalException(e.getSystemMessageCode());
        } catch (Exception e) {
            e.getStackTrace();
            throw new RuntimeException();
        }
    }

    /* 입금승인 */
    @Transactional
    public void approveDspt(String userId, ApproveDsptRequest approveDsptRequest) throws Exception {
        // 사용자 정보 조회
        UserMngEntity user = userMngMapper.selectUserInfo(userId);
        List<String> list = approveDsptRequest.getDsptMgntNoList();

        for (String dsptMgntNo : list) {
            // 여신관리입금처리 데이터 조회
            LoanMgntDsptProcEntity procEntity = dsptMngMapper.selectLoanMgntDsptProcInfo4Org(dsptMgntNo);

            // 매장의 여신관리기본정보 조회 - 없으면 에러 처리
            LoanMgntBaseInfoEntity infoEntity = dsptMngMapper.selectLoanMgntBaseInfo(procEntity.getBrandId(), procEntity.getStoreId());

            // 여신관리기본정보 (계좌잔액 증가)
            long trscBfBal = infoEntity.getAcctBal();
            long trscAfBal = infoEntity.getAcctBal() + procEntity.getDpstAmt();
            infoEntity.setAcctBal(trscAfBal); // 계좌잔액
            dsptMngMapper.updateLoanMgntBaseInfo4AcctBal(userId, infoEntity);

            // 여신관리상세이력 등록
            LoanMgntDtlHstEntity hstEntity = new LoanMgntDtlHstEntity();
            hstEntity.setLoanMgntUnqNo(infoEntity.getLoanMgntUnqNo());
            hstEntity.setLoanRegDt(DateUtil.getCurrentDate());
            hstEntity.setLoanRegTm(DateUtil.getCurrentTime());
            hstEntity.setDpstPayDvsn(DpstPayDvsn.DEPOSIT.getCd());
            hstEntity.setTrscAmt(procEntity.getDpstAmt()); // 거래금액
            hstEntity.setTrscBfBal(trscBfBal);
            hstEntity.setTrscAfBal(trscAfBal);
            hstEntity.setMediaDvsn(MediaDvsn.BANKING.getCd());
            hstEntity.setRcvAcctNo(procEntity.getRcvAcctNo()); // 입금계좌번호 - 매장 송금계좌
            hstEntity.setDpstDt(procEntity.getDpstDt());
            hstEntity.setDpstNm(procEntity.getDpstNm());
            hstEntity.setDpstBnkCd(procEntity.getDpstBnkCd());
            hstEntity.setDsptMgntNo(procEntity.getDsptMgntNo());
            dsptMngMapper.insertLoanMgntDtlHst(userId, hstEntity);

            // 여신관리입금처리
            LoanMgntDsptProcEntity entity = new LoanMgntDsptProcEntity();
            entity.setDsptMgntNo(dsptMgntNo);
            entity.setDpstStCd(DpstStCd.DPST_APPROVE.getCd()); // 입금승인
            entity.setDpstAuthId(userId);
            entity.setDpstAuthNm(user.getUserNm());
            entity.setDpstAuthDt(DateUtil.getCurrentDate());
            entity.setDpstAuthTm(DateUtil.getCurrentTime());
            entity.setDpstAuthYn("Y"); // 입금승인여부
            dsptMngMapper.updateLoanMgntDsptProcInfo4Approve(userId, entity);
        }
    }

    /* 입금반려 */
    @Transactional
    public void rejectDspt(String userId, RejectDsptRequest rejectDsptRequest) throws Exception {
        try {
            // 여신관리입금처리
            List<String> list = rejectDsptRequest.getDsptMgntNoList();

            for (String dsptMgntNo : list) {
                LoanMgntDsptProcEntity entity = new LoanMgntDsptProcEntity();
                entity.setDsptMgntNo(dsptMgntNo);
                entity.setDpstStCd(DpstStCd.DPST_REJECT.getCd()); // 입금반려
                entity.setDsptRjctDt(DateUtil.getCurrentDate());
                entity.setDsptRjctTm(DateUtil.getCurrentTime());
                entity.setDsptRjctRsn(rejectDsptRequest.getDsptRjctRsn());
                entity.setDpstAuthYn("N"); // 입금승인여부
                dsptMngMapper.updateLoanMgntDsptProcInfo4Reject(userId, entity);
            }
        } catch (GlobalException e) {
            e.getStackTrace();
            throw new GlobalException(e.getSystemMessageCode());
        } catch (Exception e) {
            e.getStackTrace();
            throw new RuntimeException();
        }
    }

    /* 입금요청 삭제 */
    @Transactional
    public void removeDspt(String userId, RemoveDsptRequest removeDsptRequest) throws Exception {
        try {
            // 여신관리입금처리
            LoanMgntDsptProcEntity entity = new LoanMgntDsptProcEntity();
            entity.setDsptMgntNo(removeDsptRequest.getDsptMgntNo());
            dsptMngMapper.deleteLoanMgntDsptProcInfo(userId, entity);
        } catch (GlobalException e) {
            e.getStackTrace();
            throw new GlobalException(e.getSystemMessageCode());
        } catch (Exception e) {
            e.getStackTrace();
            throw new RuntimeException();
        }
    }

}
