package com.oqpo.api.service.stockmng;


import com.oqpo.api.entity.CodeEntity;
import com.oqpo.api.entity.stockmng.*;
import com.oqpo.api.enums.SystemMessageCode;
import com.oqpo.api.exception.GlobalException;
import com.oqpo.api.mapper.stockmng.WhsMngMapper;
import com.oqpo.api.service.CommonService;
import com.oqpo.api.web.dto.request.GridRequest;
import com.oqpo.api.web.dto.request.stockmng.SaveWhsInfoRequest;
import com.oqpo.api.web.dto.response.GridResponse;
import com.oqpo.api.web.dto.response.code.CodeSearchListResponse;
import com.oqpo.api.web.dto.response.stockmng.*;
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 WhsMngService extends CommonService {

    @Autowired
    private WhsMngMapper whsMngMapper;

    /*
      창고관리 그리드 리스트 조회
     */
    public GridResponse selectWhsMngGridList(String sBrandId, String sStoreId, String sWhsDvsn, String sWhsStCd,
                                             String sWhsNm, GridRequest gridRequest) throws Exception {
        int gridPage = gridRequest.getGridPage();
        int gridSize = gridRequest.getGridSize();

        int gridRecords = whsMngMapper.selectWhsMngGridCnt(sBrandId, sStoreId, sWhsDvsn, sWhsStCd, sWhsNm);
        int gridTotal = fnCalculateGridTotal(gridSize, gridRecords);
        List<WhsMgntBaseInfoEntity> entities = whsMngMapper.selectWhsMngGridList(sBrandId, sStoreId, sWhsDvsn, sWhsStCd, sWhsNm, gridRequest);
        List<Object> gridRows = entities.stream()
                .map(m -> WhsMngListResponse.builder()
                        .viewCd("R")
                        .brandId(m.getBrandId())
                        .brandNm(m.getBrandNm())
                        .whsId(m.getWhsId())
                        .whsNm(m.getWhsNm())
                        .whsDvsn(m.getWhsDvsn())
                        .whsDvsnNm(m.getWhsDvsnNm())
                        .mgrNm(m.getMgrNm())
                        .mgrTelNo(m.getMgrTelNo())
                        .whsStCd(m.getWhsStCd())
                        .whsStNm(m.getWhsStNm())
                        .storeId(m.getStoreId())
                        .storeNm(m.getStoreNm())
                        .build())
                .collect(Collectors.toList());
        return GridResponse.toDTO(gridPage, gridTotal, gridRecords, gridRows);
    }

    /* 창고관리 정보 조회 */
    public WhsMngInfoResponse selectWhsMngInfo(String brandId, String storeId, String whsId) throws Exception {
        WhsMgntBaseInfoEntity entity = whsMngMapper.selectWhsMgntBaseInfo(brandId, storeId, whsId);
        return WhsMngInfoResponse.toDTO(entity);
    }

    /*
      Location 그리드 리스트 조회
     */
    public GridResponse selectWhsLocGridList(String brandId, String whsId, GridRequest gridRequest) throws Exception {
        int gridPage = gridRequest.getGridPage();
        int gridSize = gridRequest.getGridSize();

        int gridRecords = whsMngMapper.selectWhsLocGridCnt(brandId, whsId);
        int gridTotal = fnCalculateGridTotal(gridSize, gridRecords);
        List<WhsMgntBaseLocEntity> entities = whsMngMapper.selectWhsLocGridList(brandId, whsId, gridRequest);
        List<Object> gridRows = entities.stream()
                .map(m -> LocInfoListResponse.builder()
                        .viewCd("R")
                        .location(m.getLocation())
                        .locationNm(m.getLocationNm())
                        .stckDvsn(m.getStckDvsn())
                        .stckDvsnNm(m.getStckDvsnNm())
                        .locStCd(m.getLocStCd())
                        .locStNm(m.getLocStNm())
                        .build())
                .collect(Collectors.toList());
        return GridResponse.toDTO(gridPage, gridTotal, gridRecords, gridRows);
    }

    /* 창고정보 등록 */
    @Transactional
    public void addWhsInfo(String userId, SaveWhsInfoRequest saveWhsInfoRequest) throws Exception {
        try {
            // 창고관리기본정보
            WhsMgntBaseInfoEntity entity = new WhsMgntBaseInfoEntity();
            entity.setBrandId(saveWhsInfoRequest.getBrandId());
            entity.setWhsId(fnGetDealNo(28, "")); // 창고아이디 채번
            entity.setWhsNm(saveWhsInfoRequest.getWhsNm());
            entity.setWhsDvsn(saveWhsInfoRequest.getWhsDvsn());
            entity.setMgrNm(saveWhsInfoRequest.getMgrNm());
            entity.setMgrTelNo(saveWhsInfoRequest.getMgrTelNo());
            entity.setZipNo(saveWhsInfoRequest.getZipNo());
            entity.setAddr1(saveWhsInfoRequest.getAddr1());
            entity.setAddr2(saveWhsInfoRequest.getAddr2());
            entity.setWhsStCd(saveWhsInfoRequest.getWhsStCd());
            entity.setStoreId(saveWhsInfoRequest.getStoreId());
            whsMngMapper.insertWhsMgntBaseInfo(userId, entity);

            // 창고로케이션정보
            saveWhsInfoRequest.setWhsId(entity.getWhsId()); // 창고번호 지정
            List<WhsMgntBaseLocEntity> locEntities = saveWhsInfoRequest.toEntities(saveWhsInfoRequest.getGridInsertData());
            for (WhsMgntBaseLocEntity locEntity : locEntities) {
                // LOCATION 채번
                locEntity.setLocation(whsMngMapper.selectNextLocation4Whs(locEntity.getBrandId(), locEntity.getWhsId()));
                whsMngMapper.insertWhsMgntBaseLoc(userId, locEntity);
            }
        } catch (GlobalException e) {
            e.getStackTrace();
            throw new GlobalException(e.getSystemMessageCode());
        } catch (Exception e) {
            e.getStackTrace();
            throw new RuntimeException();
        }
    }

    /* 창고정보 수정 */
    @Transactional
    public void modifyWhsInfo(String userId, SaveWhsInfoRequest saveWhsInfoRequest) throws Exception {
        try {
            // 창고관리기본정보
            WhsMgntBaseInfoEntity entity = new WhsMgntBaseInfoEntity();
            entity.setBrandId(saveWhsInfoRequest.getBrandId());
            entity.setWhsId(saveWhsInfoRequest.getWhsId());
            entity.setWhsNm(saveWhsInfoRequest.getWhsNm());
            entity.setWhsDvsn(saveWhsInfoRequest.getWhsDvsn());
            entity.setMgrNm(saveWhsInfoRequest.getMgrNm());
            entity.setMgrTelNo(saveWhsInfoRequest.getMgrTelNo());
            entity.setZipNo(saveWhsInfoRequest.getZipNo());
            entity.setAddr1(saveWhsInfoRequest.getAddr1());
            entity.setAddr2(saveWhsInfoRequest.getAddr2());
            entity.setWhsStCd(saveWhsInfoRequest.getWhsStCd());
            entity.setStoreId(saveWhsInfoRequest.getStoreId());
            whsMngMapper.updateWhsMgntBaseInfo(userId, entity);

            // 창고로케이션정보
            // 삭제
            List<WhsMgntBaseLocEntity> locEntities = saveWhsInfoRequest.toEntities(saveWhsInfoRequest.getGridDeleteData());
            for (WhsMgntBaseLocEntity locEntity : locEntities) {
                whsMngMapper.deleteWhsMgntBaseLoc(userId, locEntity);
            }
            // 수정
            locEntities = saveWhsInfoRequest.toEntities(saveWhsInfoRequest.getGridUpdateData());
            for (WhsMgntBaseLocEntity locEntity : locEntities) {
                whsMngMapper.updateWhsMgntBaseLoc(userId, locEntity);
            }
            // 등록
            locEntities = saveWhsInfoRequest.toEntities(saveWhsInfoRequest.getGridInsertData());
            for (WhsMgntBaseLocEntity locEntity : locEntities) {
                // LOCATION 채번
                locEntity.setLocation(whsMngMapper.selectNextLocation4Whs(locEntity.getBrandId(), locEntity.getWhsId()));
                whsMngMapper.insertWhsMgntBaseLoc(userId, locEntity);
            }
        } catch (GlobalException e) {
            e.getStackTrace();
            throw new GlobalException(e.getSystemMessageCode());
        } catch (Exception e) {
            e.getStackTrace();
            throw new RuntimeException();
        }
    }

    /* 창고정보 삭제 */
    @Transactional
    public void removeWhsInfo(String userId, SaveWhsInfoRequest saveWhsInfoRequest) throws Exception {
        try {
            // 창고관리기본정보
            WhsMgntBaseInfoEntity entity = new WhsMgntBaseInfoEntity();
            entity.setBrandId(saveWhsInfoRequest.getBrandId());
            entity.setWhsId(saveWhsInfoRequest.getWhsId());
            whsMngMapper.deleteWhsMgntBaseInfo(userId, entity);

            // 창고로케이션정보
            whsMngMapper.deleteWhsMgntBaseLoc4Info(userId, entity);
        } catch (GlobalException e) {
            e.getStackTrace();
            throw new GlobalException(e.getSystemMessageCode());
        } catch (Exception e) {
            e.getStackTrace();
            throw new RuntimeException();
        }
    }


    /* 매장등록시 창고 자동 등록 */
    @Transactional
    public void addStoreWhsInfo(String userId, WhsMgntBaseInfoEntity saveWhsInfo, WhsMgntBaseLocEntity saveLocInfo) throws Exception {
        try {
            // 창고관리기본정보
            WhsMgntBaseInfoEntity entity = new WhsMgntBaseInfoEntity();
            entity.setBrandId(saveWhsInfo.getBrandId());
            entity.setWhsId(fnGetDealNo(28, "")); // 창고아이디 채번
            entity.setWhsNm(saveWhsInfo.getWhsNm());
            entity.setWhsDvsn(saveWhsInfo.getWhsDvsn());
            entity.setMgrNm(saveWhsInfo.getMgrNm());
            entity.setMgrTelNo(saveWhsInfo.getMgrTelNo());
            entity.setZipNo(saveWhsInfo.getZipNo());
            entity.setAddr1(saveWhsInfo.getAddr1());
            entity.setAddr2(saveWhsInfo.getAddr2());
            entity.setWhsStCd(saveWhsInfo.getWhsStCd());
            entity.setStoreId(saveWhsInfo.getStoreId());
            whsMngMapper.insertWhsMgntBaseInfo(userId, entity);

            // 창고로케이션정보
            saveLocInfo.setWhsId(entity.getWhsId());
            whsMngMapper.insertWhsMgntBaseLoc(userId, saveLocInfo);

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

    /* 매장창고 상태 값 변경처리 */
    @Transactional
    public void chgStatusStoreWhsInfo(String userId, String brandId, String storeId, String whsStCd, String locStCd) throws Exception {
        try {
            whsMngMapper.updateStoreWhsStatus(userId, brandId, storeId, whsStCd);
            whsMngMapper.updateWhsLocStatus(userId, brandId, storeId, locStCd);

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

    /*
        창고 팝업 검색
     */
    public WhsLocationPopListResponse searchPopWhsLocationList(String sBrandId, String sStoreId, String sWhsNm) throws Exception {

        //창고구분(브랜드 W01/매장 W02)
        String sWhsDvsn = "W01";
        if (!"".equals(sStoreId) && sStoreId != null) {
            sWhsDvsn = "W02";
        }

        List<WhsMgntBaseInfoEntity> entities = whsMngMapper.selectPopWhsLocList(sBrandId, sWhsDvsn, sStoreId, sWhsNm);
        return WhsLocationPopListResponse.toDTO(entities);
    }

}
