package com.oqpo.api.service.stinfo;


import com.oqpo.api.entity.CodeEntity;
import com.oqpo.api.entity.oper.FileEntity;
import com.oqpo.api.entity.stinfo.*;
import com.oqpo.api.enums.SystemMessageCode;
import com.oqpo.api.exception.GlobalException;
import com.oqpo.api.mapper.FileMapper;
import com.oqpo.api.mapper.stinfo.ItemMapper;
import com.oqpo.api.mapper.stinfo.ItemUnitMapper;
import com.oqpo.api.mapper.stinfo.StoreItemUnitMapper;
import com.oqpo.api.service.CommonService;
import com.oqpo.api.web.dto.request.GridRequest;
import com.oqpo.api.web.dto.request.stinfo.item.DelItemInfolRequest;
import com.oqpo.api.web.dto.request.stinfo.item.SaveItemClassMngInfolRequest;
import com.oqpo.api.web.dto.request.stinfo.item.SaveItemInfolRequest;
import com.oqpo.api.web.dto.request.stinfo.itemUnit.SaveItemUnitInfolRequest;
import com.oqpo.api.web.dto.request.stinfo.itemUnit.SaveStoreItemUnitInfolRequest;
import com.oqpo.api.web.dto.request.stinfo.itemUnit.StoreItemUnitInfolRequest;
import com.oqpo.api.web.dto.response.GridResponse;
import com.oqpo.api.web.dto.response.code.CodeSearchListResponse;
import com.oqpo.api.web.dto.response.stinfo.item.*;
import com.oqpo.api.web.dto.response.stinfo.itemUnit.ItemUnitInfoResponse;
import com.oqpo.api.web.dto.response.stinfo.itemUnit.ItemUnitSearchResponse;
import com.oqpo.api.web.dto.response.stinfo.itemUnit.StoreItemUnitInfoResponse;
import com.oqpo.api.web.dto.response.stinfo.itemUnit.StoreItemUnitSearchResponse;
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.lang.reflect.GenericDeclaration;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ItemUnitService extends CommonService {
    @Autowired
    private ItemUnitMapper itemUnitMapper;

    @Autowired
    private StoreItemUnitMapper storeItemUnitMapper;


    @Autowired
    private FileMapper fileMapper;

    /*
      브랜드 공급사 단가 리스트 조회

     */
    public GridResponse selectItemUnitGridList(String sBrandId, String fromDt, String toDt,String sUnitStCd, String sSpplyId, String sClass1, String sClass2, String sClass3, String sClass4, 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 = itemUnitMapper.selectItemUnitGridCnt( sBrandId, fromDt,  toDt, sUnitStCd, sSpplyId, sClass1, sClass2, sClass3, sClass4,sItemNm );
        int gridTotal = fnCalculateGridTotal(gridSize, gridRecords);
        List<ItemUnitEntity> entities = itemUnitMapper.selectItemUnitGridList(sBrandId, fromDt,  toDt, sUnitStCd, sSpplyId, sClass1, sClass2, sClass3, sClass4,sItemNm, gridRequest);
        List<Object> gridRows = entities.stream()
                .map(m -> ItemUnitSearchResponse.builder()
                        .viewCd("R")
                        .brandUnitUnqNo(m.getBrandUnitUnqNo())
                        .brandId(m.getBrandId())
                        .itemId(m.getItemId())
                        .itemNm(m.getItemNm())
                        .spplyId(m.getSpplyId())
                        .spplyNm(m.getSpplyNm())
                        .contSttDt(m.getContSttDt() == null ? "" :m.getContSttDt())
                        .contEndDt(m.getContEndDt() == null ? "" :m.getContEndDt())
                        .curr(m.getCurr() == null ? "" :m.getCurr())
                        .currNm(m.getCurrNm() == null ? "" :m.getCurrNm() )
                        .unit(m.getUnit() == null ? "" :m.getUnit())
                        .unitNm(m.getUnitNm() == null ? "" :m.getUnitNm())
                        .unitAmt(m.getUnitAmt() == null ? 0 :m.getUnitAmt())
                        .leadTime(m.getLeadTime() == null ? 0 :m.getLeadTime())
                        .spplyItemId(m.getSpplyItemId() == null ? "" :m.getSpplyItemId())
                        .unitStCd(m.getUnitStCd() == null ? "" :m.getUnitStCd())
                        .unitStNm(m.getUnitStNm() == null ? "" :m.getUnitStNm())
                        .stddQty(m.getStddQty() == null ? 0 :m.getStddQty() )
                        .build())
                .collect(Collectors.toList());
        return GridResponse.toDTO(gridPage, gridTotal, gridRecords, gridRows);
    }

    /*
      공급사단가 리스트 조회

     */
    public GridResponse selectSpplyItemUnitGridList(String sBrandId, String fromDt, String toDt,String sUnitStCd, String sSpplyId, 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 = itemUnitMapper.selectItemUnitGridCnt( sBrandId, fromDt,  toDt, sUnitStCd, sSpplyId, "", "", "", "",sItemNm );
        int gridTotal = fnCalculateGridTotal(gridSize, gridRecords);
        List<ItemUnitEntity> entities = itemUnitMapper.selectItemUnitGridList(sBrandId, fromDt,  toDt, sUnitStCd, sSpplyId, "", "", "", "",sItemNm, gridRequest);
        List<Object> gridRows = entities.stream()
                .map(m -> ItemUnitSearchResponse.builder()
                        .viewCd("R")
                        .brandUnitUnqNo(m.getBrandUnitUnqNo())
                        .brandId(m.getBrandId())
                        .itemId(m.getItemId())
                        .itemNm(m.getItemNm())
                        .spplyId(m.getSpplyId())
                        .spplyNm(m.getSpplyNm())
                        .contSttDt(m.getContSttDt() == null ? "" :m.getContSttDt())
                        .contEndDt(m.getContEndDt() == null ? "" :m.getContEndDt())
                        .curr(m.getCurr() == null ? "" :m.getCurr())
                        .currNm(m.getCurrNm() == null ? "" :m.getCurrNm() )
                        .unit(m.getUnit() == null ? "" :m.getUnit())
                        .unitNm(m.getUnitNm() == null ? "" :m.getUnitNm())
                        .unitAmt(m.getUnitAmt() == null ? 0 :m.getUnitAmt())
                        .leadTime(m.getLeadTime() == null ? 0 :m.getLeadTime())
                        .spplyItemId(m.getSpplyItemId() == null ? "" :m.getSpplyItemId())
                        .unitStCd(m.getUnitStCd() == null ? "" :m.getUnitStCd())
                        .unitStNm(m.getUnitStNm() == null ? "" :m.getUnitStNm())
                        .stddQty(m.getStddQty() == null ? 0 :m.getStddQty() )
                        .build())
                .collect(Collectors.toList());
        return GridResponse.toDTO(gridPage, gridTotal, gridRecords, gridRows);
    }



    /* 공급사 단가 정보 */
    public ItemUnitInfoResponse selectItemUnitInfo(String brandId, String brandUnitUnqNo) throws Exception {

        ItemUnitEntity entity = itemUnitMapper.selectItemUnitInfo( brandId, brandUnitUnqNo);
        List<FileEntity> fileContInfoList = null;

        if (!"".equals(entity.getShortContFileNo())) {
            fileContInfoList = fileMapper.selectFileList(entity.getShortContFileNo()) ;
        } else {
            fileContInfoList = new ArrayList<FileEntity>();
        }

        return ItemUnitInfoResponse.toDTO(entity,fileContInfoList );

    }

    /* 공급사 단가 저장 */
    @Transactional
    public void saveItemUnitInfo(String userId, SaveItemUnitInfolRequest saveItemUnitInfolRequest) throws Exception {
        try {

            ItemUnitEntity entity = new ItemUnitEntity();
            entity.setBrandUnitUnqNo(saveItemUnitInfolRequest.getBrandUnitUnqNo());
            entity.setBrandId(saveItemUnitInfolRequest.getBrandId());
            entity.setBrandNm(saveItemUnitInfolRequest.getBrandNm());
            entity.setItemId(saveItemUnitInfolRequest.getItemId());
            entity.setItemNm(saveItemUnitInfolRequest.getItemNm());
            entity.setSpplyId(saveItemUnitInfolRequest.getSpplyId());
            entity.setSpplyNm(saveItemUnitInfolRequest.getSpplyNm());
            entity.setContSttDt(saveItemUnitInfolRequest.getContSttDt().replaceAll("\\.",""));
            entity.setContEndDt(saveItemUnitInfolRequest.getContEndDt().replaceAll("\\.",""));
            entity.setCurr(saveItemUnitInfolRequest.getCurr());
            entity.setUnit(saveItemUnitInfolRequest.getUnit());
            entity.setUnitAmt(saveItemUnitInfolRequest.getUnitAmt());
            entity.setLeadTime(saveItemUnitInfolRequest.getLeadTime());
            entity.setDlvCndt(saveItemUnitInfolRequest.getDlvCndt());
            entity.setShortContFileNo(saveItemUnitInfolRequest.getShortContFileNo());
            entity.setSpplyItemId(saveItemUnitInfolRequest.getSpplyItemId());
            entity.setUnitStCd(saveItemUnitInfolRequest.getUnitStCd());
            entity.setStddQty(saveItemUnitInfolRequest.getStddQty());
            entity.setStoreSaleStddQty(saveItemUnitInfolRequest.getStoreSaleStddQty());
            entity.setStoreSaleUnitAmt(saveItemUnitInfolRequest.getStoreSaleUnitAmt());

            if ("C".equals(saveItemUnitInfolRequest.getViewCd())) {
                //selectItemUnitDupContInfoNo  날짜 기준 계약 존재여부 파악
                int dupCnt = itemUnitMapper.selectItemUnitDupCnt(entity.getBrandId(), entity.getSpplyId(), entity.getItemId(), entity.getContSttDt());

                if (dupCnt != 0) {
                    // 이미 진행중인 계약단가가 있습니다.
                    throw new GlobalException(SystemMessageCode.ERR_EXISTUNIT);
                }
            } else {
                String passChk = itemUnitMapper.selectItemUnitChaPass(entity.getBrandUnitUnqNo(),entity.getContSttDt());

                if ("N".equals(passChk)) {
                    // 시작일은 변경 불가
                    throw new GlobalException(SystemMessageCode.ERR_NOTCHGDT);
                }
            }

            if ("".equals(entity.getBrandUnitUnqNo())) {
                itemUnitMapper.insertItemUnitInfo(userId, entity);
            } else {
                itemUnitMapper.updateItemUnitInfo(userId, entity);
            }
        } catch (GlobalException e) {
            e.printStackTrace();
            //e.getStackTrace();
            throw new GlobalException(e.getSystemMessageCode());
        } catch (Exception e) {
            e.printStackTrace();
            //e.getStackTrace();
            throw new RuntimeException();
        }
    }


    /*
      브랜드 매장 단가 리스트 조회
     */
    public GridResponse selectStoreItemUnitGridList(String sBrandId, String sStoreNm,  GridRequest gridRequest) throws Exception {
        int gridPage = gridRequest.getGridPage();
        int gridSize = gridRequest.getGridSize();

        int gridRecords = storeItemUnitMapper.selectStoreItemUnitGridCnt( sBrandId, sStoreNm );
        int gridTotal = fnCalculateGridTotal(gridSize, gridRecords);
        List<StoreItemUnitEntity> entities = storeItemUnitMapper.selectStoreItemUnitGridList(sBrandId, sStoreNm, gridRequest);
        List<Object> gridRows = entities.stream()
                .map(m -> StoreItemUnitSearchResponse.builder()
                        .viewCd("R")
                        .brandId(m.getBrandId())
                        .brandNm(m.getBrandNm())
                        .storeId(m.getStoreId())
                        .storeNm(m.getStoreNm())
                        .contSttDt(m.getContSttDt())
                        .contEndDt(m.getContEndDt())
                        .sysRegDttm(m.getSysRegDttm())
                        .itemCnt(m.getItemCnt())
                        .build())
                .collect(Collectors.toList());
        return GridResponse.toDTO(gridPage, gridTotal, gridRecords, gridRows);
    }

    /*
      매장용 매장 단가 리스트 조회
     */
    /*
    public GridResponse selectSstoreItemUnitGridList(String sBrandId, String sStoreId,  GridRequest gridRequest) throws Exception {
        int gridPage = gridRequest.getGridPage();
        int gridSize = gridRequest.getGridSize();

        int gridRecords = storeItemUnitMapper.selectSstoreItemUnitGridCnt( sBrandId, sStoreId );
        int gridTotal = fnCalculateGridTotal(gridSize, gridRecords);
        List<StoreItemUnitEntity> entities = storeItemUnitMapper.selectSstoreItemUnitGridList(sBrandId, sStoreId, gridRequest);
        List<Object> gridRows = entities.stream()
                .map(m -> StoreItemUnitSearchResponse.builder()
                        .viewCd("R")
                        .brandId(m.getBrandId())
                        .brandNm(m.getBrandNm())
                        .storeId(m.getStoreId())
                        .storeNm(m.getStoreNm())
                        .contSttDt(m.getContSttDt())
                        .contEndDt(m.getContEndDt())
                        .sysRegDttm(m.getSysRegDttm())
                        .itemCnt(m.getItemCnt())
                        .build())
                .collect(Collectors.toList());
        return GridResponse.toDTO(gridPage, gridTotal, gridRecords, gridRows);
    }
    */
    /* 신규 매장단가 정보 초기 세팅값 */


    /* 매장 단가 정보 */
    public StoreItemUnitInfoResponse selectStoreNewItemUnitInfo(String brandId) throws Exception {

        List<StoreItemUnitEntity> entities = storeItemUnitMapper.selectStoreNewItemUnitInfo( brandId);
        return StoreItemUnitInfoResponse.toDTO(entities);

    }


    /* 매장 단가 정보 */
    public StoreItemUnitInfoResponse selectStoreItemUnitInfo(StoreItemUnitInfolRequest storeItemUnitInfolRequest) throws Exception {
        String brandId  = storeItemUnitInfolRequest.getBrandId();
        String storeId  = storeItemUnitInfolRequest.getStoreId();
        String contSttDt = storeItemUnitInfolRequest.getContSttDt();
        String contEndDt = storeItemUnitInfolRequest.getContEndDt();

        contSttDt = contSttDt == null ? null : contSttDt.replace(".", "");
        contEndDt = contEndDt == null ? null : contEndDt.replace(".", "");

        List<StoreItemUnitEntity> entities = storeItemUnitMapper.selectStoreItemUnitInfo( brandId, storeId, contSttDt, contEndDt);
        return StoreItemUnitInfoResponse.toDTO(entities);

    }


    /* 매장 단가 저장 */
    @Transactional
    public void saveStroeItemUnitInfo(String userId, SaveStoreItemUnitInfolRequest saveStoreItemUnitInfolRequest) throws Exception {
        try {

            StoreItemUnitEntity entity = new StoreItemUnitEntity();
            entity.setBrandId(saveStoreItemUnitInfolRequest.getBrandId());
            entity.setStoreId(saveStoreItemUnitInfolRequest.getStoreId());

            entity.setContSttDt(saveStoreItemUnitInfolRequest.getContSttDt().replaceAll("\\.",""));
            entity.setContEndDt(saveStoreItemUnitInfolRequest.getContEndDt().replaceAll("\\.",""));

            //신규
            // 종료일짜 변경 여부 확인
            String chgEndDtYn = "N";
            if ("U".toString().equals(saveStoreItemUnitInfolRequest.getViewCd())) {
                String lastEndDt = storeItemUnitMapper.selectStoreItemUnitEndDtInfo(entity.getBrandId(), entity.getStoreId(), entity.getContSttDt());

                if (!lastEndDt.equals(entity.getContEndDt())) {
                    chgEndDtYn = "Y";
                }
            }

            List<StoreItemUnitEntity> gridUpdateData = saveStoreItemUnitInfolRequest.toCodeEntities(saveStoreItemUnitInfolRequest.getGridUpdateData());
            List<StoreItemUnitEntity> gridInsertData = saveStoreItemUnitInfolRequest.toCodeEntities(saveStoreItemUnitInfolRequest.getGridInsertData());


            if (gridInsertData.size() > 0) {
                for (int k = 0; k < gridInsertData.size(); k++) {
                    if ("C".toString().equals(saveStoreItemUnitInfolRequest.getViewCd())) {
                        gridInsertData.get(k).setContSttDt(entity.getContSttDt());
                        gridInsertData.get(k).setContEndDt(entity.getContEndDt());
                    } else {
                        gridInsertData.get(k).setContSttDt(gridInsertData.get(k).getContSttDt().replaceAll("\\.",""));
                        gridInsertData.get(k).setContEndDt(gridInsertData.get(k).getContEndDt().replaceAll("\\.",""));
                    }
                }
            }

            if (gridUpdateData.size() > 0) {
                for (int k = 0; k < gridUpdateData.size(); k++) {
                    gridUpdateData.get(k).setContSttDt(gridUpdateData.get(k).getContSttDt().replaceAll("\\.",""));
                    gridUpdateData.get(k).setContEndDt(gridUpdateData.get(k).getContEndDt().replaceAll("\\.",""));
                }
            }

            // 신규일경우 계약기간 날짜 체크함
            if ("C".toString().equals(saveStoreItemUnitInfolRequest.getViewCd())) {
                SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMdd");
                Date chkenddate = formatter.parse(entity.getContEndDt());
                Date chksttdate = formatter.parse(entity.getContSttDt());
                int result1 = chkenddate.compareTo(chksttdate);
                // 시작일과 종료일이 반대기간으로 되어져있을 경우
                if (result1 < 0) {
                    throw new GlobalException(SystemMessageCode.ERR_CHGDTOPP);
                }

                StoreItemUnitEntity dtEntity = storeItemUnitMapper.selectStoreItemUnitContDtInfo(entity.getBrandId(), entity.getStoreId());


                if (dtEntity.getContSttDt() != null && !dtEntity.getContSttDt().equals("")) {
                    // 서로 상이하면 기존 종료일자는 전송시작일보다 클경우 오류


                    // 문자열 -> Date
                    Date dtEnddate = formatter.parse(dtEntity.getContEndDt());
                    Date sttdate = formatter.parse(entity.getContSttDt());
                    int result = dtEnddate.compareTo(sttdate);

                    if (result > 0) {
                        // 진행중 단가계약이 있습니다.
                        throw new GlobalException(SystemMessageCode.ERR_EXISTUNIT);
                    }
                }
            }

            if (gridInsertData.size() > 0) {
                storeItemUnitMapper.insertStoreItemUnitInfo(userId, entity.getBrandId(), entity.getStoreId(), entity.getContSttDt(),entity.getContEndDt(), gridInsertData) ;
            }

            if (gridUpdateData.size() > 0) {

                storeItemUnitMapper.updateStoreItemUnitInfo(userId, entity.getBrandId(), entity.getStoreId(), entity.getContSttDt(),entity.getContEndDt(), gridUpdateData) ;
            }


            // 수정에 대해 날짜 변동시 전체 변동처리함
            if ("Y".toString().equals(chgEndDtYn)) {
                storeItemUnitMapper.updateStoreItemUnitChgContEnd(entity.getBrandId(), entity.getStoreId(), entity.getContSttDt(), entity.getContEndDt() );
            }

            //selectStoreItemUnitEndDtInfo  , updateStoreItemUnitChgContEnd
        } catch (GlobalException e) {
            e.getStackTrace();
            throw new GlobalException(e.getSystemMessageCode());
        } catch (Exception e) {
//            e.getStackTrace();
            e.printStackTrace();
            throw new RuntimeException();
        }
    }

}
