package com.oqpo.api.service.stockmng;


import com.oqpo.api.entity.oper.FileEntity;
import com.oqpo.api.entity.stinfo.BrandEntity;
import com.oqpo.api.entity.stockmng.StckCddMgntDtlEntity;
import com.oqpo.api.entity.stockmng.StckCddMgntInfoEntity;
import com.oqpo.api.entity.stockmng.StckMgntBaseInfoEntity;
import com.oqpo.api.entity.stockmng.StckMgntDtlHistEntity;
import com.oqpo.api.enums.ChgDvsn;
import com.oqpo.api.enums.InOutCd;
import com.oqpo.api.exception.GlobalException;
import com.oqpo.api.mapper.CommonMapper;
import com.oqpo.api.mapper.stockmng.StockCddMapper;
import com.oqpo.api.mapper.stockmng.StockMngMapper;
import com.oqpo.api.service.CommonService;
import com.oqpo.api.util.DateUtil;
import com.oqpo.api.util.StringUtil;
import com.oqpo.api.web.dto.request.GridRequest;
import com.oqpo.api.web.dto.request.stockmng.SaveStockCddRequest;
import com.oqpo.api.web.dto.response.GridResponse;
import com.oqpo.api.web.dto.response.stinfo.brand.BrandInfoResponse;
import com.oqpo.api.web.dto.response.stockmng.StockCddDtlListResponse;
import com.oqpo.api.web.dto.response.stockmng.StockCddInfoResponse;
import com.oqpo.api.web.dto.response.stockmng.StockCddListResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Param;
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.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class StockCddService extends CommonService {

    @Autowired
    private StockCddMapper stockCddMapper;

    @Autowired
    private StockMngMapper stockMngMapper;

    /*
      재고실사 그리드 리스트 조회
     */
    public GridResponse selectStockCddGridList(String sBrandId, String sStoreId, String sWhsId, String sLocation,
                                               String sCddDvsn, 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 = stockCddMapper.selectStockCddGridCnt(sBrandId, sStoreId, sWhsId, sLocation, sCddDvsn, fromDt, toDt);
        int gridTotal = fnCalculateGridTotal(gridSize, gridRecords);
        List<StckCddMgntInfoEntity> entities = stockCddMapper.selectStockCddGridList(sBrandId, sStoreId, sWhsId, sLocation, sCddDvsn, fromDt, toDt, gridRequest);
        List<Object> gridRows = entities.stream()
                .map(m -> StockCddListResponse.builder()
                        .viewCd("R")
                        .cddId(m.getCddId())
                        .cddDt(m.getCddDt())
                        .cddTm(m.getCddTm())
                        .cddDvsn(m.getCddDvsn())
                        .cddDvsnNm(m.getCddDvsnNm())
                        .cddMgrNm(m.getCddMgrNm())
                        .brandId(m.getBrandId())
                        .brandNm(m.getBrandNm())
                        .storeId(m.getStoreId())
                        .storeNm(m.getStoreNm())
                        .whsId(m.getWhsId())
                        .whsNm(m.getWhsNm())
                        .location(m.getLocation())
                        .locationNm(m.getLocationNm())
                        .build())
                .collect(Collectors.toList());
        return GridResponse.toDTO(gridPage, gridTotal, gridRecords, gridRows);
    }

    /* 재고 실사 저장 */
    @Transactional
    public void saveStockCdd(String userId, SaveStockCddRequest saveStockCddRequest) throws Exception {
        try {
            // 1. 재고실사기본정보(stck_cdd_mgnt_info) 등록
            StckCddMgntInfoEntity infoEntity = new StckCddMgntInfoEntity();
            infoEntity.setCddId(fnGetDealNo(27, "")); // 실사아이디 채번
            infoEntity.setCddDt(StringUtil.isEmpty(saveStockCddRequest.getCddDt()) ? DateUtil.getCurrentDate() : saveStockCddRequest.getCddDt());
            infoEntity.setCddTm(StringUtil.isEmpty(saveStockCddRequest.getCddTm()) ? DateUtil.getCurrentTime() : saveStockCddRequest.getCddTm());
            infoEntity.setCddDvsn(saveStockCddRequest.getCddDvsn());
            infoEntity.setWhsId(saveStockCddRequest.getWhsId());
            infoEntity.setLocation(saveStockCddRequest.getLocation());
            infoEntity.setBrandId(saveStockCddRequest.getBrandId());
            infoEntity.setStoreId(saveStockCddRequest.getStoreId());

            stockCddMapper.insertStckCddMgntInfo(userId, infoEntity);

            // 2. 재고실사상세정보(stck_cdd_mgnt_dtl) 등록
            List<StckCddMgntDtlEntity> dtlList = saveStockCddRequest.toEntities(saveStockCddRequest.getGridInsertData());
            int idx = 1;
            for (StckCddMgntDtlEntity dtlEntity : dtlList) {
                // 기존수량 조회
                StckMgntBaseInfoEntity baseInfo = stockMngMapper.selectStckMgntBaseInfo(saveStockCddRequest.getBrandId(), saveStockCddRequest.getWhsId(),
                        saveStockCddRequest.getLocation(), dtlEntity.getItemId());

                // 재고실사상세정보 등록
                dtlEntity.setCddId(infoEntity.getCddId());
                dtlEntity.setCddSeq(idx);
                dtlEntity.setUnit(baseInfo.getUnit());
                dtlEntity.setComExstQty(baseInfo.getStckQty()); // 기존재고수량
                dtlEntity.setChgQty(dtlEntity.getCddSeq() - baseInfo.getStckQty()); // 변동수량 = 실사수량 - 기존재고수량
                stockCddMapper.insertStckCddMgntDtl(userId, dtlEntity);

                // 재고관리기본정보(stck_mgnt_base_info) 업데이트
                StckMgntBaseInfoEntity stckEntity = new StckMgntBaseInfoEntity();
                stckEntity.setBrandId(saveStockCddRequest.getBrandId());
                stckEntity.setWhsId(saveStockCddRequest.getWhsId());
                stckEntity.setLocation(saveStockCddRequest.getLocation());
                stckEntity.setItemId(dtlEntity.getItemId());
                stckEntity.setStckQty(dtlEntity.getCddQty()); // 재고수량 : 실사수량
                double curStckRt = Math.round(stckEntity.getStckQty() * 100 / baseInfo.getPrpStckQty() * 100) / 100.0;
                stckEntity.setCurStckRt(BigDecimal.valueOf(curStckRt)); // 현재고비율((재고수량 * 100) / 적정재고)
                stockMngMapper.updateStckMgntBaseInfo4StckProc(userId, stckEntity);

                // 재고관리상세이력(stck_mgnt_dtl_hist) 등록
                int inoutQty = dtlEntity.getCddQty() - baseInfo.getStckQty(); // 입출고수량
                StckMgntDtlHistEntity sourceHist = new StckMgntDtlHistEntity();
                sourceHist.setStckMgntDtlNo(fnGetDealNo(32, "")); // 재고관리상세번호
                sourceHist.setBrandId(stckEntity.getBrandId());
                sourceHist.setWhsId(stckEntity.getWhsId());
                sourceHist.setLocation(stckEntity.getLocation());
                sourceHist.setItemId(stckEntity.getItemId());
                sourceHist.setItemNm(baseInfo.getItemNm());
                sourceHist.setInoutCd(inoutQty >= 0 ? InOutCd.IN.getCd() : InOutCd.OUT.getCd()); // 입출고구분
                sourceHist.setInoutQty(inoutQty); // 입출고수량
                sourceHist.setChgDvsn(ChgDvsn.STOCK_CDD.getCd()); // 재고실사
                stockMngMapper.insertStckMgntDtlHist(userId, sourceHist);

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

    /* 재고실사 정보 */
    public StockCddInfoResponse selectStockCddInfo(String cddId) throws Exception {
        StckCddMgntInfoEntity entity = stockCddMapper.selectStockCddMgntInfo(cddId);
        return StockCddInfoResponse.toDTO(entity);
    }

    /*
      재고실사 품목정보 그리드 리스트 조회
     */
    public GridResponse selectStockCddDtlGridList(String cddId, GridRequest gridRequest) throws Exception {

        int gridPage = gridRequest.getGridPage();
        int gridSize = gridRequest.getGridSize();

        int gridRecords = stockCddMapper.selectStockCddDtlGridCnt(cddId);
        int gridTotal = fnCalculateGridTotal(gridSize, gridRecords);
        List<StckCddMgntDtlEntity> entities = stockCddMapper.selectStockCddDtlGridList(cddId, gridRequest);
        List<Object> gridRows = entities.stream()
                .map(m -> StockCddDtlListResponse.builder()
                        .viewCd("R")
                        .cddId(m.getCddId())
                        .brandId(m.getBrandId())
                        .brandNm(m.getBrandNm())
                        .storeId(m.getStoreId())
                        .storeNm(m.getStoreNm())
                        .whsId(m.getWhsId())
                        .whsNm(m.getWhsNm())
                        .location(m.getLocation())
                        .locationNm(m.getLocationNm())
                        .cddSeq(m.getCddSeq())
                        .itemId(m.getItemId())
                        .itemNm(m.getItemNm())
                        .unit(m.getUnit())
                        .comExstQty(m.getComExstQty())
                        .cddQty(m.getCddQty())
                        .chgQty(m.getChgQty())
                        .build())
                .collect(Collectors.toList());
        return GridResponse.toDTO(gridPage, gridTotal, gridRecords, gridRows);
    }
}
