package com.oqpo.api.service.stockmng;


import com.oqpo.api.enums.ChgDvsn;
import com.oqpo.api.enums.InOutCd;
import com.oqpo.api.entity.stockmng.StckMgntBaseInfoEntity;
import com.oqpo.api.entity.stockmng.StckMgntDtlHistEntity;
import com.oqpo.api.exception.GlobalException;
import com.oqpo.api.mapper.stockmng.StockMngMapper;
import com.oqpo.api.service.CommonService;
import com.oqpo.api.web.dto.request.GridRequest;
import com.oqpo.api.web.dto.request.stockmng.ProcStockRequest;
import com.oqpo.api.web.dto.response.GridResponse;
import com.oqpo.api.web.dto.response.stockmng.StockHistListResponse;
import com.oqpo.api.web.dto.response.stockmng.StockMngListResponse;
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.math.BigDecimal;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class StockMngService extends CommonService {

    @Autowired
    private StockMngMapper stockMngMapper;

    /*
      재고관리 그리드 리스트 조회
     */
    public GridResponse selectStockMngGridList(String sBrandId, String sStoreId, String sWhsId, String sLocation,
                                               String sItemClass1, String sItemClass2, String sItemClass3,
                                               String sItemClass4, String sItemId, String sItemNm, 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 = stockMngMapper.selectStockMngGridCnt(sBrandId, sStoreId, sWhsId, sLocation, sItemClass1, sItemClass2, sItemClass3, sItemClass4, sItemId, sItemNm);
        int gridTotal = fnCalculateGridTotal(gridSize, gridRecords);
        List<StckMgntBaseInfoEntity> entities = stockMngMapper.selectStockMngGridList(sBrandId, sStoreId, sWhsId, sLocation, sItemClass1, sItemClass2, sItemClass3, sItemClass4, sItemId, sItemNm, gridRequest);
        List<Object> gridRows = entities.stream()
                .map(m -> StockMngListResponse.builder()
                        .viewCd("R")
                        .brandId(m.getBrandId())
                        .brandNm(m.getBrandNm())
                        .storeId(m.getStoreId())
                        .storeNm(m.getStoreNm())
                        .whsId(m.getWhsId())
                        .whsNm(m.getWhsNm())
                        .location(m.getLocation())
                        .locationNm(m.getLocationNm())
                        .itemId(m.getItemId())
                        .itemNm(m.getItemNm())
                        .unit(m.getUnit())
                        .stckQty(m.getStckQty())
                        .prpStckQty(m.getPrpStckQty())
                        .sftStckRt(m.getSftStckRt())
                        .curStckRt(m.getCurStckRt())
                        .build())
                .collect(Collectors.toList());
        return GridResponse.toDTO(gridPage, gridTotal, gridRecords, gridRows);
    }

    /*
      재고이력 그리드 리스트 조회
     */
    public GridResponse selectStockHistGridList(String sBrandId, String sWhsId, String sLocation,
                                                String sItemId, String sInoutCd, 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 = stockMngMapper.selectStockHistGridCnt(sBrandId, sWhsId, sLocation, sItemId, sInoutCd, fromDt, toDt);
        int gridTotal = fnCalculateGridTotal(gridSize, gridRecords);
        List<StckMgntDtlHistEntity> entities = stockMngMapper.selectStockHistGridList(sBrandId, sWhsId, sLocation, sItemId, sInoutCd, fromDt, toDt, gridRequest);
        List<Object> gridRows = entities.stream()
                .map(m -> StockHistListResponse.builder()
                        .viewCd("R")
                        .inoutCd(m.getInoutCd())
                        .inoutNm(m.getInoutNm())
                        .inoutQty(m.getInoutQty())
                        .chgDvsn(m.getChgDvsn())
                        .chgDvsnNm(m.getChgDvsnNm())
                        .relationNo(m.getRelationNo())
                        .sysRegDttm(m.getSysRegDttm())
                        .build())
                .collect(Collectors.toList());
        return GridResponse.toDTO(gridPage, gridTotal, gridRecords, gridRows);
    }

    /* 재고 처리 */
    @Transactional
    public void procStock(String userId, ProcStockRequest procStockRequest) throws Exception {
        try {
            // 1-1. 소스 재고 정보 (stck_mgnt_base_info) 업데이트
            StckMgntBaseInfoEntity source = stockMngMapper.selectStckMgntBaseInfo(procStockRequest.getBrandId(), procStockRequest.getSourceWhsId(),
                    procStockRequest.getSourceLocation(), procStockRequest.getItemId());
            source.setStckQty(source.getStckQty() - procStockRequest.getMoveQty()); // 재고수량
            double curStckRt = Math.round(source.getStckQty() * 100 / source.getPrpStckQty() * 100) / 100.0;
            source.setCurStckRt(BigDecimal.valueOf(curStckRt)); // 현재고비율((재고수량 * 100) / 적정재고)

            stockMngMapper.updateStckMgntBaseInfo4StckProc(userId, source);

            // 1-2. 소스 이력 등록 (stck_mgnt_dtl_hist)
            StckMgntDtlHistEntity sourceHist = new StckMgntDtlHistEntity();
            sourceHist.setStckMgntDtlNo(fnGetDealNo(32, "")); // 재고관리상세번호
            sourceHist.setBrandId(source.getBrandId());
            sourceHist.setWhsId(source.getWhsId());
            sourceHist.setLocation(source.getLocation());
            sourceHist.setItemId(source.getItemId());
            sourceHist.setItemNm(source.getItemNm());
            sourceHist.setInoutCd(InOutCd.OUT.getCd()); // 출고
            sourceHist.setInoutQty(procStockRequest.getMoveQty());
            sourceHist.setChgDvsn(ChgDvsn.STOCK_MOVE.getCd()); // 재고이동
            stockMngMapper.insertStckMgntDtlHist(userId, sourceHist);

            // 2-1. 타겟 재고 정보 (stck_mgnt_base_info) 업데이트
            StckMgntBaseInfoEntity target = stockMngMapper.selectStckMgntBaseInfo(procStockRequest.getBrandId(), procStockRequest.getTargetWhsId(),
                    procStockRequest.getTargetLocation(), procStockRequest.getItemId());
            if (target == null) {
                target = new StckMgntBaseInfoEntity();
                target.setBrandId(procStockRequest.getBrandId());
                target.setWhsId(procStockRequest.getTargetWhsId());
                target.setLocation(procStockRequest.getTargetLocation());
                target.setItemId(procStockRequest.getItemId());
                target.setItemNm(source.getItemNm()); // 소스와 동일하게
                target.setUnit(source.getUnit()); // 소스와 동일하게
                target.setStckQty(procStockRequest.getMoveQty()); // 재고수량
                target.setPrpStckQty(source.getPrpStckQty()); // 소스와 동일하게
                target.setSftStckRt(source.getSftStckRt()); // 소스와 동일하게
                curStckRt = Math.round(target.getStckQty() * 100 / target.getPrpStckQty() * 100) / 100.0;
                target.setCurStckRt(BigDecimal.valueOf(curStckRt)); // 현재고비율((재고수량 * 100) / 적정재고)
                stockMngMapper.insertStckMgntBaseInfo(userId, target);
            } else {
                target.setStckQty(target.getStckQty() + procStockRequest.getMoveQty()); // 재고수량
                curStckRt = Math.round(target.getStckQty() * 100 / target.getPrpStckQty() * 100) / 100.0;
                target.setCurStckRt(BigDecimal.valueOf(curStckRt)); // 현재고비율((재고수량 * 100) / 적정재고)
                stockMngMapper.updateStckMgntBaseInfo4StckProc(userId, target);
            }

            // 2-2. 타겟 이력 등록 (stck_mgnt_dtl_hist)
            StckMgntDtlHistEntity targetHist = new StckMgntDtlHistEntity();
            targetHist.setStckMgntDtlNo(fnGetDealNo(32, "")); // 재고관리상세번호
            targetHist.setBrandId(target.getBrandId());
            targetHist.setWhsId(target.getWhsId());
            targetHist.setLocation(target.getLocation());
            targetHist.setItemId(target.getItemId());
            targetHist.setItemNm(target.getItemNm());
            targetHist.setInoutCd(InOutCd.IN.getCd()); // 입고
            targetHist.setInoutQty(procStockRequest.getMoveQty());
            targetHist.setChgDvsn(ChgDvsn.STOCK_MOVE.getCd()); // 재고이동
            stockMngMapper.insertStckMgntDtlHist(userId, targetHist);

        } catch (GlobalException e) {
            e.getStackTrace();
            throw new GlobalException(e.getSystemMessageCode());
        } catch (Exception e) {
            e.getStackTrace();
            throw new RuntimeException();
        }
    }

}
