package com.style24.core.biz.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.gagaframework.web.parameter.GagaMap;
import com.gagaframework.web.util.GagaFileUtil;
import com.style24.core.biz.dao.TscOrderOcmDao;
import com.style24.core.support.env.TscConstants;
import com.style24.core.support.message.TscMessageByLocale;
import com.style24.persistence.domain.ExtmallOrder;
import com.style24.persistence.domain.Payment;

import lombok.extern.slf4j.Slf4j;

/**
 * 영업망관리 Service
 * 제휴몰 주문등록
 *
 * @author jmh
 * @since 2021. 6. 25
 */
@Service
@Slf4j
public class TscOrderOcmService {

    @Autowired
    private TscMessageByLocale message;

    @Autowired
	private TscKakaotalkService kakaotalkService;

    @Autowired
	private Environment env;

    @Autowired
    private TscOrderOcmDao orderOcmDao;

    @Autowired
	private ObjectMapper mapper;

    /**
     * 스타일 24 주문정보등록
     * 샵링커 주문수집으로 외부몰주문등록된 건 중 '대기'상태인 것들에 대해 주문등록처리를 한다.
     * @param uploadGb, userNo
     * @author jmh
     * @since 2021. 03. 09
     */
    public void createShoplinkerOrder(String uploadGb, int userNo) {
    	Collection<ExtmallOrder> orderList = this.sortOrderList(uploadGb, userNo);

    	if (orderList != null && !orderList.isEmpty()) {
	    	for( ExtmallOrder order : orderList ) {
	    		createShoplinkerOrderSub(order);
	        }
    	}
    }

    /**
     * 스타일 24 주문정보등록
     * @param Order
     * @return Order
     * @author jsh77b
     * @since 2021. 03. 09
     * TscOrderService.createPreOrder 참조
     */
    @SuppressWarnings("unchecked")
    @Transactional("shopTxnManager")
    public void createShoplinkerOrderSub(ExtmallOrder order) {

		GagaMap result = this.orderValidationCheck(order);

		// validation 체크 값
		Collection<ExtmallOrder> newOrderDetailList = (Collection<ExtmallOrder>) result.get("orderDetailList");

		if ("SUCCESS".equals(result.get("message").toString())) {
			// 1. 주문기본정보등록
            orderOcmDao.createOrder(order);

            // 2. 주문배송정보등록
            orderOcmDao.createDeliveryAddr(order);

            // 3. 주문배송비정보등록
            orderOcmDao.createDeliveryFee(order);

			// 4. 주문상세정보등록
            String dtlNos = "";			// 주문상세번호
            String cancelGoodsNms = ""; // 콤마로 구분
            int cancelAmt = 0;
            int payAmt = 0;
            GagaMap vdMap;
			for( ExtmallOrder orderDetail : newOrderDetailList) {

				//vdMap = this.checkGoodsInfo(orderDetail);
				orderDetail.setOrdNo(order.getOrdNo());
				orderDetail.setDelvAddrSq(order.getDelvAddrSq());


				if (!"SUCCESS".equals(orderDetail.getUploadFailReason())){
					cancelGoodsNms += orderDetail.getGoodsNm()+",";
					cancelAmt += orderDetail.getOrdAmt();

					orderDetail.setUploadStat(TscConstants.ExtmallUploadStat.FAIL.value());	// 실패
					orderDetail.setOrdNo(null);
					orderDetail.setUploadFailCd(orderDetail.getUploadFailCd());
					orderDetail.setUploadFailReason(orderDetail.getUploadFailReason());
					orderOcmDao.updateExtmallOrder(orderDetail);

				}else {

					orderDetail.setOrdNo(order.getOrdNo());
					orderDetail.setDelvAddrSq(order.getDelvAddrSq());

					// TODO 총알배송, 구매대행상품여부 체크
					orderOcmDao.createOrderDetail(orderDetail); // 주문상세정보등록
                    orderOcmDao.createOrderDetailHst(orderDetail); // 주문상세이력정보등록

                    Collection<ExtmallOrder> orderDetailItemList = orderOcmDao.getOrderDetailItem(orderDetail); // 주문상세단품정보조회

                    // 주문상세단품단위 금액 등록
                    int length				= orderDetailItemList.size();
                    int index				= 1;
                    int leftOrdAmt 			= orderDetail.getOrdAmt();
                    int leftCpn1DcAmt 		= orderDetail.getCpn1DcAmt();
                    int leftTmtb1DcAmt 		= orderDetail.getTmtb1DcAmt();
                    int leftTmtb2DcAmt 		= orderDetail.getTmtb2DcAmt();
                    int leftGoodsCpnDcAmt 	= orderDetail.getGoodsCpnDcAmt();
                    int leftCartCpnDcAmt 	= orderDetail.getCartCpnDcAmt();
                    int leftPntDcAmt 		= orderDetail.getPntDcAmt();
                    int leftPrePntDcAmt 	= orderDetail.getPrePntDcAmt();
                    int leftSavePntAmt 		= orderDetail.getSavePntAmt();
                    int leftRealOrdAmt 		= orderDetail.getRealOrdAmt();
                    int leftGfcdUseAmt 		= orderDetail.getGfcdUseAmt();

                    for (ExtmallOrder orderDetailItem : orderDetailItemList) {
                        int itemPrice 		= orderDetail.getCurrPrice(); // 제휴몰은 받은금액 그대로 orderDetailItem.getItemPrice();
                        int optAddPrice 	= orderDetailItem.getOptAddPrice();
                        int itemQty 		= orderDetailItem.getItemQty();
                        double currPrice	= orderDetail.getCurrPrice(); // 제휴몰은 받은금액 그대로 orderDetailItem.getCurrPrice();
                        double itemOrdAmt	= (itemPrice + optAddPrice) * itemQty;
                        double tempDivD		= (itemOrdAmt / currPrice) * 100;
                        int tempDiv 		= Integer.parseInt(String.valueOf(Math.round(tempDivD)));

                        if (index == length) {
                        	orderDetailItem.setItemPrice(itemPrice);
                            orderDetailItem.setOrdAmt(leftOrdAmt);
                            orderDetailItem.setCpn1DcAmt(leftCpn1DcAmt);
                            orderDetailItem.setTmtb1DcAmt(leftTmtb1DcAmt);
                            orderDetailItem.setTmtb2DcAmt(leftTmtb2DcAmt);
                            orderDetailItem.setGoodsCpnDcAmt(leftGoodsCpnDcAmt);
                            orderDetailItem.setCartCpnDcAmt(leftCartCpnDcAmt);
                            orderDetailItem.setPntDcAmt(leftPntDcAmt);
                            orderDetailItem.setPrePntDcAmt(leftPrePntDcAmt);
                            orderDetailItem.setSavePntAmt(leftSavePntAmt);
                            orderDetailItem.setRealOrdAmt(leftRealOrdAmt);
                            orderDetailItem.setGfcdUseAmt(leftGfcdUseAmt);
                        } else {
                        	orderDetailItem.setItemPrice(itemPrice);
                            orderDetailItem.setOrdAmt((orderDetail.getOrdAmt() * tempDiv) / 100);
                            orderDetailItem.setCpn1DcAmt((orderDetail.getCpn1DcAmt() * tempDiv) / 100);
                            orderDetailItem.setTmtb1DcAmt((orderDetail.getTmtb1DcAmt() * tempDiv) / 100);
                            orderDetailItem.setTmtb2DcAmt((orderDetail.getTmtb2DcAmt() * tempDiv) / 100);
                            orderDetailItem.setGoodsCpnDcAmt((orderDetail.getGoodsCpnDcAmt() * tempDiv) / 100);
                            orderDetailItem.setCartCpnDcAmt((orderDetail.getCartCpnDcAmt() * tempDiv) / 100);
                            orderDetailItem.setPntDcAmt((orderDetail.getPntDcAmt() * tempDiv) / 100);
                            orderDetailItem.setPrePntDcAmt((orderDetail.getPrePntDcAmt() * tempDiv) / 100);
                            orderDetailItem.setSavePntAmt((orderDetail.getSavePntAmt() * tempDiv) / 100);
                            orderDetailItem.setRealOrdAmt((orderDetail.getRealOrdAmt() * tempDiv) / 100);
                            orderDetailItem.setGfcdUseAmt((orderDetail.getGfcdUseAmt() * tempDiv) / 100);

                            leftOrdAmt 			= leftOrdAmt 			- ((orderDetail.getOrdAmt() * tempDiv) / 100);
                            leftCpn1DcAmt 		= leftCpn1DcAmt 		- ((orderDetail.getCpn1DcAmt() * tempDiv) / 100);
                            leftTmtb1DcAmt 		= leftTmtb1DcAmt 		- ((orderDetail.getTmtb1DcAmt() * tempDiv) / 100);
                            leftTmtb2DcAmt 		= leftTmtb2DcAmt 		- ((orderDetail.getTmtb2DcAmt() * tempDiv) / 100);
                            leftGoodsCpnDcAmt 	= leftGoodsCpnDcAmt 	- ((orderDetail.getGoodsCpnDcAmt() * tempDiv) / 100);
                            leftCartCpnDcAmt 	= leftCartCpnDcAmt 		- ((orderDetail.getCartCpnDcAmt() * tempDiv) / 100);
                            leftPntDcAmt 		= leftPntDcAmt 			- ((orderDetail.getPntDcAmt() * tempDiv) / 100);
                            leftPrePntDcAmt 	= leftPrePntDcAmt 		- ((orderDetail.getPrePntDcAmt() * tempDiv) / 100);
                            leftSavePntAmt 		= leftSavePntAmt 		- ((orderDetail.getSavePntAmt() * tempDiv) / 100);
                            leftRealOrdAmt 		= leftRealOrdAmt 		- ((orderDetail.getRealOrdAmt() * tempDiv) / 100);
                            leftGfcdUseAmt 		= leftGfcdUseAmt 		- ((orderDetail.getGfcdUseAmt() * tempDiv) / 100);
                        }

                        // 2021.05.06 옵션금액 단품 추가
                        orderDetailItem.setOptAddPrice(optAddPrice);
                        orderDetailItem.setCustNo(order.getCustNo());
                        orderDetailItem.setOrdQty(orderDetail.getOrdQty());
                        orderOcmDao.createOrderDetailItem(orderDetailItem); // 주문상세단품정보등록

                        // 2021.06.25 샵링커 주문수집 결제완료 (정산구분값추가)
                        orderDetailItem.setOrdDtlStat(TscConstants.OrdDtlItemStat.SALE_PAYMENT_COMPLETE.value());
                        orderOcmDao.createOrderDetailItemHst(orderDetailItem); // 주문상세단품이력정보등록

                        index++;

                        // 5. 재고등록(샵링커 주문목록을 보면 동일한 몰 주문번호에 동일한 상품(sku)이 수량이 아닌 개별로 있는 데이터가 존재하므로 > 주문번호로 한번에 처리가 아닌 개별로 처리 함)
        				orderDetail.setSellGb(TscConstants.SellGb.ORDER.value());			// 판매구분(10:주문(-),
        				orderOcmDao.createSellQty(orderDetail);

                        // 외부몰 정보 업데이트
        				orderDetail.setUploadStat(TscConstants.ExtmallUploadStat.SUCC.value());	// 성공
    					orderOcmDao.updateExtmallOrder(orderDetail);

    					dtlNos += orderDetail.getOrdDtlNo()+",";
    				}
				}
        	}


			// 6. 주문사은품정보등록
    		dtlNos = dtlNos.substring(0, dtlNos.length()-1);
	        String [] dtlNdsArr = dtlNos.split(",");	// 주문상세번호
	        order.setItemCdArr(dtlNdsArr);
			order.setOrdDtlStat(TscConstants.OrderDetailStat.PAYMENT_COMPLETE.value());		//주문상세상태 - 결제완료처리
			GagaMap giftMap = this.getOrderFreegift(order);

	        if( null != giftMap) {
		        if( null != giftMap.get("freegiftList")) {
		        	if( !"".equals(giftMap.get("freegiftList"))) {

		    			// 상품코드
		        		String dtlGoodsCds = "";	// 사은품관련 상품코드. 콤마로구분
		        		String[] dtlGoodsCdsArr;
		        		Collection<ExtmallOrder> freegiftApplyAmtList = (Collection<ExtmallOrder>) giftMap.get("freegiftApplyAmtList");

		        		for(ExtmallOrder ftMap : freegiftApplyAmtList ) {
		        			dtlGoodsCds += ftMap.getGoodsCd() +",";
		        		}

		        		dtlGoodsCds = dtlGoodsCds.substring(0, dtlGoodsCds.length()-1);
		        		dtlGoodsCdsArr = dtlGoodsCds.split(",");
		        		order.setFreegiftGoodsArr(dtlGoodsCdsArr);

		        		Collection<ExtmallOrder> freegiftList = (Collection<ExtmallOrder>) giftMap.get("freegiftList");
		                ArrayList<Integer> fitValSqArr = new ArrayList<Integer>();
		                for(ExtmallOrder ftMap : freegiftList ) {
		                	fitValSqArr.add(ftMap.getFreegiftValSq());
		                }
		                int[] freegiftValArr = new int[fitValSqArr.size()];
		                for( int i=0; i<fitValSqArr.size(); i++) {
		                	freegiftValArr[i] = fitValSqArr.get(i);
		                }

		                order.setFreegiftValArr(freegiftValArr);
		                order.setCustNo(0);
		                if(order.getFreegiftValArr() != null && order.getFreegiftValArr().length > 0) {
		                    orderOcmDao.createOrdFreegift(order);

		                    // 6. 주문사은품 상품 정보 등록
		                    orderOcmDao.createOrdFreegiftVal(order);

		                    // 7. 주문사은품 주문상세정보 등록
		                    for(ExtmallOrder ftMap : freegiftApplyAmtList ) {
			    		    	order.setFreegiftSq(ftMap.getFreegiftSq());
				    			order.setGoodsCd(ftMap.getGoodsCd());
				    			orderOcmDao.createOrdFreegiftDtl(order);
			    		    }
		                }

		                // 14. 사은품 수량 차감 로직 TB_FREEGIFT_VAL LEFT_QTY
		                orderOcmDao.updateFreegiftValLeftQty(order);

		        	}
		        }
	        }

			// 7. 결제 TB_PAYMENT
            Payment payment = new Payment();
            payment.setOrdNo(order.getOrdNo());
            payment.setPayMeans(TscConstants.PayMeans.EXTMALL.value());					// 결제수단
            payAmt = order.getRealOrdSumAmt() + order.getDelvFee() - cancelAmt;			// 결제금액 = 실결제금액 + 배송비 - 취소금액
            payment.setPayAmt(payAmt);
            payment.setPgCpnAmt(0);														// PG쿠폰금액
            payment.setNpayPntAmt(0);   												// 네이버페이포인트금액
            payment.setPayGb("O");														// 결제구분(O:주문시결제, D:배송시결제, E:에러(강제 결제 태울 때 또는 에러일 때)
            payment.setPayStat(TscConstants.PaymentStat.PAYMENT_COMPLETE.value());		// 결제상태 - 결제완료
            payment.setRegNo(0);
            payment.setUpdNo(0);

            orderOcmDao.insertPayment(payment);

		}else {

			// 주문등록 전체실패시 상태 업데이트
			GagaMap vdMap;
			for( ExtmallOrder orderDetail : order.getOrderDetailList()) {
				vdMap = this.checkGoodsInfo(orderDetail);
				orderDetail.setUploadStat(TscConstants.ExtmallUploadStat.FAIL.value());	// 실패
				orderDetail.setOrdNo(vdMap.getInt("ordNo"));	// 실패
				orderDetail.setUploadFailCd(vdMap.getString("uploadFailCd"));
				orderDetail.setUploadFailReason(vdMap.getString("message"));
				orderOcmDao.updateExtmallOrder(orderDetail);
			}
		}

		// 8. 부분품절상품 - 관리자메모 등록
		if ("SUCCESS".equals(result.get("message").toString())) {
			if( "PART_SUCCESS".equals(result.getString("sendNotiType"))) {
				if( !"".equals(result.getString("failGoods"))) {
					// 부분성공 (실패내용 관리자메모)
					ExtmallOrder adminMemo = new ExtmallOrder();
					adminMemo.setOrdNo(order.getOrdNo());
					adminMemo.setMemo("[품절/재고관련 주문 미등록건] :"+result.getString("failGoodsAdmMsg"));
					adminMemo.setRegNo(0);
					
					orderOcmDao.createOrderMemo(adminMemo);
				}
			}
		}
		
		// 9. 알림톡발송
		try {
			if( "N".equals(order.getCnclsmsSendYn())) {		// Y:제휴몰에서발송, N:자사몰에서발송

				ExtmallOrder sendNoti = new ExtmallOrder();
				sendNoti.setUploadGb(order.getUploadGb());
	    		sendNoti.setExtmallOrderId(order.getExtmallOrderId());
	    		String soldoutGoodsNm = "";
	    		sendNoti.setOrderPhnno(order.getOrdPhnno());
	    		sendNoti.setExtmallNm(order.getExtmallNm());
				if( null != order.getExtmallTel()) {
					sendNoti.setExtmallNm(order.getExtmallNm()+"(" +order.getExtmallTel()+ ")");
				}

	    		if( "ALL_FAIL".equals(result.getString("sendNotiType"))) {
	    			// 알림톡발송-전체실패
	    			soldoutGoodsNm = result.getString("failGoods") + " (총 "+result.getString("stockFailCnt")+" 건)";
	    			sendNoti.setCnclAllSoldoutYn("Y");
	    			sendNoti.setSoldoutGoodsNm(soldoutGoodsNm);
	    			kakaotalkService.sendShoplinkerOrder(sendNoti, 0);

	    		}else if( "PART_SUCCESS".equals(result.getString("sendNotiType"))) {

	    			if( !"".equals(result.getString("failGoods"))) {
	    				// 부분성공 알림톡발송
	    				soldoutGoodsNm = result.getString("failGoods") + " (총 "+result.getString("stockFailCnt")+" 건)";
	    				sendNoti.setCnclAllSoldoutYn("N");
	    				sendNoti.setSoldoutGoodsNm(soldoutGoodsNm);
	    				kakaotalkService.sendShoplinkerOrder(sendNoti, 0);

	    			}else {
	    				// 전체성공
	    			}
	    		}else {
	    			// 발송안함 (ALL_SUCCESS-전체성공 / NOT-이미 발송한건)
	    		}
			}
		}catch(Exception e) {
			// error
		}
    }

    /**
     * 스타일 24 주문정보등록 - 제휴몰주문등록 데이터 정렬
     * @param uploadGb, userNo
     * @return Collection<ExtmallOrder>
     * @author jmh
     * @since 2021. 03. 09
    */
    private Collection<ExtmallOrder> sortOrderList(String uploadGb, int userNo) {

        // 1. 외부몰주문등록 대기목록 조회
        ExtmallOrder params = new ExtmallOrder();
        params.setUploadStat(TscConstants.ExtmallUploadStat.WAIT.value());		// 대기
        params.setUploadGb(uploadGb);											// 등록위치 (S: 샵링커, E: 엑셀)
        if("E".equals(uploadGb)) {
        	params.setRegNo(userNo);					// 등록자(E:엑셀방식일경우 필수)
        }
        Collection<ExtmallOrder> exMastList = orderOcmDao.getRegExtmallMasterOrderList(params);
        Collection<ExtmallOrder> exList = orderOcmDao.getRegExtmallOrderList(params);
        Collection<ExtmallOrder> tmpList = new ArrayList<ExtmallOrder>();

        // 2. 그룹별 주문상세목록 세팅
        // ※ TB_DELIVERY_FEE.DELV_FEE_CD에는 WMS 로들어가야하고, TB_ORDER_DETAIL.DELV_FEE_CD 에는 TB_GOODS.DELV_FEE_CD 에 있는 정보가 들어가야 함
        for( ExtmallOrder ordGroup : exMastList) {

        	// TB_ORDER 추가정보 세팅
        	ordGroup.setSiteCd(TscConstants.Site.STYLE24.value());
        	ordGroup.setCustNo(0);												// 고객번호 - 외부몰 0
        	ordGroup.setCustNm(ordGroup.getOrdNm());							// 주문자명
        	ordGroup.setFrontGb("P");											// PC
        	ordGroup.setDelvFeeGb("G018_10");									// 원주문배송비 코드
        	ordGroup.setDelvFeeCd("WMS"); 										// SHOT 자사총알배송 | WMS 자사일반배송 | RES  자사예약배송
        	ordGroup.setDelvCpnDcAmt(0);										// 배송비쿠폰할인금액
        	ordGroup.setRealDelvAmt(ordGroup.getDelvFee());						// 배송비실결제금액
        	ordGroup.setDelvUsacYn("N");										// 배송비 정산여부

            tmpList = new ArrayList<ExtmallOrder>();
            for(ExtmallOrder ordDtl : exList ) {
            	if(ordGroup.getVendorId().equals(ordDtl.getVendorId())
            		 && ordGroup.getExtmallId().equals(ordDtl.getExtmallId())
            		 && ordGroup.getExtmallOrderId().equals(ordDtl.getExtmallOrderId())
            		 && ordGroup.getOrdNm().equals(ordDtl.getOrdNm())
            		 && ordGroup.getOrdPhnno().equals(ordDtl.getOrdPhnno())
            		 && ordGroup.getRecipNm().equals(ordDtl.getRecipNm())
            		 && ordGroup.getRecipPhnno().equals(ordDtl.getRecipPhnno())
            		 && ordGroup.getRecipBaseAddr().equals(ordDtl.getRecipBaseAddr())
            		 && ordGroup.getRecipDtlAddr().equals(ordDtl.getRecipDtlAddr())
            	 ) {

            		tmpList = ordGroup.getOrderDetailList();
            		if( null == tmpList ) tmpList = new ArrayList<ExtmallOrder>();

            		// 상세 추가정보
            		ordDtl.setOrdExchGb("O");										// 주문교환구분(O:주문,E:교환)
            		ordDtl.setCustNo(ordGroup.getCustNo());							// 고객번호
            		ordDtl.setRegNo(ordGroup.getCustNo());							// 등록자
            		ordDtl.setOrdDtlStat(TscConstants.OrderDetailStat.PAYMENT_COMPLETE.value());	// 주문상세상태=>결제완료 처리
                	ordDtl.setDelvCpnDcAmt(0);										// 1차쿠폰(즉시할인쿠폰)할인금액
                	ordDtl.setRealOrdAmt(ordDtl.getOrdAmt());						// 실주문금액(주문금액 - 취소반품금액 - 1차쿠폰 - 다다익선1 - 다다익선2 - 상품쿠폰 - 장바구니쿠폰 - 포인트할인금액 - 선포인트할인금액)
				    ordDtl.setShotDelvYn("N");										// 총알배송여부
                	ordDtl.setGiftPackYn("N"); 										// 선물포장여부
                	ordDtl.setGiftAddrInpYn("N");									// 선물주소입력여부
                	ordDtl.setSavePntAmt(0);										// 외부몰주문 포인트 적립금 없음

                    if (ordDtl.getSupplyCompCd() != null && !ordDtl.getSupplyCompCd().isEmpty()) {
                    	ordGroup.setSupplyCompCd(ordDtl.getSupplyCompCd());					// 공급업체코드
                    }
                    ordGroup.setExtmallNm(ordDtl.getExtmallNm());							// 제휴몰명
                    ordGroup.setExtmallTel(ordDtl.getExtmallTel());							// 제휴몰고객센터연락처
                    ordGroup.setUploadGb(ordDtl.getUploadGb());								// 업로드타입

            		tmpList.add(ordDtl);
            		ordGroup.setOrderDetailList(tmpList);
            	}
            }
        }

        return exMastList;
    }

    /**
	 * 주문정보유효성체크 >> 개별체크
	 * @param Order
	 * @return Order
	 * @author jmh
	 * @since 2021. 03. 09
	 */
	public GagaMap orderValidationCheck(ExtmallOrder order) {
		GagaMap result = new GagaMap();
		String failGoods = "";			// 고객발송 상품내용
		String failGoodsAdmMsg = "";	// 주문관리자 메모

		// 1. 주문상세체크
		Collection<ExtmallOrder> orderDetailList = order.getOrderDetailList();

		int dtlCnt = orderDetailList.size();
		int succCnt = 0;
		int stockFailCnt = 0;
		
		failGoodsAdmMsg += "\n쇼핑몰주문번호: "+order.getExtmallOrderId();
		failGoodsAdmMsg += "\n샵링커주문번호: ";
		for (ExtmallOrder orderDetail : orderDetailList) {

			GagaMap resultMap = this.checkGoodsInfo(orderDetail);

			orderDetail.setUploadFailCd(resultMap.getString("uploadFailCd"));
			orderDetail.setUploadFailReason(resultMap.getString("message"));

			if ("SUCCESS".equals(resultMap.get("message").toString())) {
				succCnt ++;
			}else {
				// 알림톡 발송 할 목록
				if("Y".equals(resultMap.get("sendNotiYn"))){
					failGoods += resultMap.get("goodsNm") + ",";
					failGoodsAdmMsg += orderDetail.getAgentOrderId()+" ,";
					//failGoodsAdmMsg += "\n상품:"+resultMap.get("goodsNm")+"("+resultMap.get("optCd")+ "),";
					stockFailCnt ++;
				}
			}
		}

		result.set("orderDetailList", orderDetailList);

		// 주문생성 여부
		if( 0 < succCnt ) {
			// 주문등록
			result.put("message", "SUCCESS");
		}else {
			// 주문등록 안함.
			result.put("message", "FAIL");
		}

		// 알림 발송타입
		if( succCnt < 0 ) {
			result.put("sendNotiType", "NOT");				// 미발송-이미처리된 건(동일날짜 주문수집시)
		}else if( 0 == succCnt ) {	// 전체실패

			if( 0 == stockFailCnt ) {
				result.put("sendNotiType", "NOT");			// 미발송-일반실패 또는 이미처리된 건(동일날짜 주문수집시)
			}else if(dtlCnt == stockFailCnt) {
				result.put("sendNotiType", "ALL_FAIL");		// 발송-재고관련 전체실패
			}else {
				result.put("sendNotiType", "PART_SUCCESS");	// 발송-부분성공
			}

		}else if( dtlCnt == succCnt ) {
			result.put("sendNotiType", "ALL_SUCCESS");		// 전체성공
		}else {
			result.put("sendNotiType", "PART_SUCCESS");		// 발송-부분성공
		}

		// 실패상품목록
		if( 0 < failGoods.length()) failGoods = failGoods.substring(0, failGoods.length()-1);
		if( 0 < failGoodsAdmMsg.length()) failGoodsAdmMsg = failGoodsAdmMsg.substring(0, failGoodsAdmMsg.length()-1);
		
		result.put("failGoods", failGoods);			// 실패상품목록
		result.put("failCnt", dtlCnt - succCnt );	// 총 실패건수
		result.put("stockFailCnt", stockFailCnt );	// 재고로인한 실패건수
		result.put("failGoodsAdmMsg", failGoodsAdmMsg);			// 관리자메모 내용
		
		return result;
	}

	/**
	 * 상품마스터 정보 및 재고확인
	 * 단품 : goodsCd, optCd, optCd1, optCd2
	 * 세트 : goodsCd,
	 * @param params
	 */
	public GagaMap checkGoodsInfo(ExtmallOrder param) {
		GagaMap result = new GagaMap();
		result.put("message", "SUCCESS");

		if( null == param.getExtmallId()) {
			result.put("sendNotiYn", "N");	// 알림톡발송 x
			result.put("uploadFailCd", TscConstants.ExtmallUploadFailStat.STORE.value());
			result.put("message", "제휴몰ID 정보가 잘못되었습니다.");
			return result;

		}

		// 검증쿼리
		param.setVendorId(TscConstants.VendorId.SHOPLINKER.value());
		ExtmallOrder dtlOrd = orderOcmDao.getExtmallOrderInfo(param);

		if( null == dtlOrd) {
			result.put("sendNotiYn", "N");	// 알림톡발송 x
			result.put("uploadFailCd", TscConstants.ExtmallUploadFailStat.ETC.value());	// 값이 무조건 존재해야함
			result.put("message", "오류입니다. 관리자확인요청>"+param.getAgentOrderId());
			return result;

		}else if( null != dtlOrd.getOrdNo() ){
			result.put("sendNotiYn", "N");	// 알림톡발송 x
			result.put("uploadFailCd", TscConstants.ExtmallUploadFailStat.ORDER.value());
			result.put("ordNo", dtlOrd.getOrdNo());
			result.put("message", "동일한 주문건이 존재합니다.");
			return result;

		}else if( 0 < dtlOrd.getStockFailHstCnt() ){
			result.put("sendNotiYn", "N");	// 알림톡발송 x
			result.put("uploadFailCd", TscConstants.ExtmallUploadFailStat.STOCK.value());
			result.put("message", "이미 재고 부족으로 인한 고객 알림 발송이 완료된 건입니다.(동일수집 실패)");
			return result;

		} else if( null == dtlOrd.getGoodsCd()) {
			result.put("sendNotiYn", "N");	// 알림톡발송 x
			result.put("uploadFailCd", TscConstants.ExtmallUploadFailStat.GOODS.value());
			result.put("message", "상품코드가 잘못되었습니다.");
			return result;

		} else if( null == dtlOrd.getOptCd()) {
			result.put("sendNotiYn", "N");	// 알림톡발송 x
			result.put("uploadFailCd", TscConstants.ExtmallUploadFailStat.SIZE.value());
			result.put("message", "옵션코드가 잘못되었습니다.");
			return result;

		}
		/* 21.09.27 정과장님 제외요청 상품 상태값 상관없이 주문되어야 한다 함.(재고만 체크하도록 변경요청)
		else if (TscConstants.GoodsStat.SOLDOUT.value().equals(dtlOrd.getGoodsStat())) {
			result.put("goodsNm", dtlOrd.getGoodsNm());
			result.put("optCd", dtlOrd.getOptCd());
			result.put("sendNotiYn", "Y");	// 알림톡발송 o
			result.put("uploadFailCd", TscConstants.ExtmallUploadFailStat.STOCK.value());
			result.put("message", "품절입니다.");
			return result;

		} else if (!TscConstants.GoodsStat.SOLDOUT.value().equals(dtlOrd.getGoodsStat()) && !TscConstants.GoodsStat.APPR.value().equals(dtlOrd.getGoodsStat())) {
			result.put("goodsNm", dtlOrd.getGoodsNm());
			result.put("optCd", dtlOrd.getOptCd());
			result.put("sendNotiYn", "Y");	// 알림톡발송 o
			result.put("uploadFailCd", TscConstants.ExtmallUploadFailStat.STOCK.value());
			result.put("message", "판매중인 상품이 아닙니다.");
			return result;
		}*/

		//상품 재고 확인
		if (null == dtlOrd.getSoldoutYn()) {
			result.put("goodsNm", dtlOrd.getGoodsNm());
			result.put("optCd", dtlOrd.getOptCd());
			result.put("sendNotiYn", "N");	// 알림톡발송 o
			result.put("uploadFailCd", TscConstants.ExtmallUploadFailStat.STOCK.value());
			result.put("message", "재고체크 실패했습니다. 새로고침 후 다시 시도해주세요.");
			return result;
		}
		
		/* 21.09.27 정과장님 제외요청 상품 상태값 상관없이 주문되어야 한다 함.(재고만 체크하도록 변경요청)
		if ("Y".equals(dtlOrd.getSoldoutYn())) {
			result.put("goodsNm", dtlOrd.getGoodsNm());
			result.put("optCd", dtlOrd.getOptCd());
			result.put("sendNotiYn", "Y");	// 알림톡발송 o
			result.put("uploadFailCd", TscConstants.ExtmallUploadFailStat.STOCK.value());
			result.put("message", dtlOrd.getOptCd2() + " 옵션은 품절입니다.");
			return result;
		}*/

		if (param.getOrdQty() > dtlOrd.getCurrStockQty()) {
			result.put("goodsNm", dtlOrd.getGoodsNm());
			result.put("optCd", dtlOrd.getOptCd());
			result.put("sendNotiYn", "Y");	// 알림톡발송 o
			result.put("uploadFailCd", TscConstants.ExtmallUploadFailStat.STOCK.value());
			result.put("message", "옵션의 재고가 충분하지 않습니다.");
			return result;
		}

		return result;
	}

	/**
	 * 사은품정보 조회
	 * @param Order
	 * @return Order
	 * @author jsh77b
	 * @since 2020. 12. 16
	 */
	public GagaMap getOrderFreegift(ExtmallOrder order) {

		GagaMap resultMap = new GagaMap();
		Collection<ExtmallOrder> freegiftGoodsList 	= null;
		Collection<ExtmallOrder> freegiftList 			= null;

		// 1. 장바구니 담긴 상품으로 적용된 사은품 프로모션 정보 조회 (with 상품금액)
		Collection<ExtmallOrder> freegiftApplyAmtList = orderOcmDao.getFreeGiftGoodsApplyAmt(order);

		// 1.1 장바구니 상품으로 적용된 사은품 여부 판단
		if (freegiftApplyAmtList.size() > 0) {

			Collection<ExtmallOrder> freegiftGoodsApplyAmtList = new ArrayList<ExtmallOrder>();
			int tempFreegiftSq 		= 0;
			int index				= 0;
			boolean	temp			 = false;

			// 사은품시퀀스 담기
			for (ExtmallOrder freegiftApplyAmt : freegiftApplyAmtList) {
				temp = true;
				if (freegiftGoodsApplyAmtList.size() > 0) {
					for (ExtmallOrder freegiftGoodsApplyAmt : freegiftGoodsApplyAmtList) {
						if (freegiftApplyAmt.getFreegiftSq() == freegiftGoodsApplyAmt.getFreegiftSq()) {
							temp = false;
						}
					}

					if (temp) {
						freegiftGoodsApplyAmtList.add(freegiftApplyAmt);
					}
				} else {
					freegiftGoodsApplyAmtList.add(freegiftApplyAmt);
				}
			}


			// 사은품시퀀스(FREEGIFT_SQ), 사은품시퀀스합계금액(FREEGIFT_AMT)
			for (ExtmallOrder freegiftGoodsApplyAmt : freegiftGoodsApplyAmtList) {
				// 금액초기화
				freegiftGoodsApplyAmt.setFreegiftAmt(0);

				for (ExtmallOrder freegiftApplyAmt : freegiftApplyAmtList) {
					int ordAmt = (freegiftApplyAmt.getCurrPrice() + freegiftApplyAmt.getOptAddPrice()) * freegiftApplyAmt.getGoodsQty();
					if (freegiftGoodsApplyAmt.getFreegiftSq() == freegiftApplyAmt.getFreegiftSq()) {
						freegiftGoodsApplyAmt.setFreegiftAmt(freegiftGoodsApplyAmt.getFreegiftAmt() + ordAmt);
					}
				}
			}


			// 사은품시퀀스배열생성
			int[] freegiftSqArr = new int[freegiftGoodsApplyAmtList.size()];
			index = 0;

			// 사은품시퀀스(FREEGIFT_SQ), 사은품시퀀스합계금액(FREEGIFT_AMT)
			for (ExtmallOrder fregiftGoodsApplyAmt : freegiftGoodsApplyAmtList) {
				freegiftSqArr[index] = fregiftGoodsApplyAmt.getFreegiftSq();
				index++;
			}

			order.setFreegiftSqArr(freegiftSqArr);

			// 2. 사은품 적용구간 정보 조회
			Collection<ExtmallOrder> freegiftGoodsApplySectionList = orderOcmDao.getFreeGiftGoodsApplySection(order);

			// 2.1 사은품 적용구간이 있는지 판단
			if (freegiftGoodsApplySectionList.size() > 0) {
				int[] freegiftSectionSqArr = new int[freegiftGoodsApplySectionList.size()];

				int tempFreegiftSectionSq = 0;
				int k = 0;

				// 사은품시퀀스(FREEGIFT_SQ), 사은품시퀀스합계금액(FREEGIFT_AMT)
				for (ExtmallOrder freegiftGoodsApplyAmt : freegiftGoodsApplyAmtList) {
					int freegiftAmt 	= freegiftGoodsApplyAmt.getFreegiftAmt();

					// 사은풐구간시퀀스(FREEGIFT_SECTION_SQ, 사은품시퀀스(FREEGIFT_SQ), 사은풐구간금액(SECTION_VAL)
					for (ExtmallOrder freegiftGoodsApplySection : freegiftGoodsApplySectionList) {
						int freegiftSectionSq 	= freegiftGoodsApplySection.getFreegiftSectionSq();
						int sectionVal 			= freegiftGoodsApplySection.getSectionVal();

						// 같은 사은품 프로모션끼리 등록
						if (freegiftGoodsApplyAmt.getFreegiftSq() == freegiftGoodsApplySection.getFreegiftSq()) {
							// 2021.05.07 금액체크는 이상일때 수정
							if (freegiftAmt >= sectionVal) {
								tempFreegiftSectionSq = freegiftSectionSq;
							}
						}
					}

					freegiftSectionSqArr[k] = tempFreegiftSectionSq;
					k++;
				}

				// 3. 사은품 적용구간 의 적용 사은품정보조회
				order.setFreegiftSectionSqArr(freegiftSectionSqArr);
				Collection<ExtmallOrder> freegiftGoodsApplyValList = orderOcmDao.getFreeGiftGoodsApplyVal(order);

				if (freegiftGoodsApplyValList.size() > 0) {
					freegiftList 		= new ArrayList<ExtmallOrder>();
					freegiftGoodsList 	= new ArrayList<ExtmallOrder>();

					for (ExtmallOrder freegiftGoodsApplyVal : freegiftGoodsApplyValList) {

						// 제휴몰 사은품 전체 제공
						//if (freegiftGoodsApplyVal.getFreegiftSq() != tempFreegiftSq) {
							freegiftList.add(freegiftGoodsApplyVal);
							tempFreegiftSq = freegiftGoodsApplyVal.getFreegiftSq();
						//}

						freegiftGoodsList.add(freegiftGoodsApplyVal);
					}
				}
			}
		}

		resultMap.set("freegiftApplyAmtList"		, freegiftApplyAmtList);
		resultMap.set("freegiftGoodsList"			, freegiftGoodsList);
		resultMap.set("freegiftList"				, freegiftList);

		return resultMap;
	}



	/**
	 * 제휴몰주문등록 엑셀 업로드 대기건 수(본인)
	 *
	 * @param userNo
	 * @return int
	 * @author jmh
	 * @since 2021. 09. 23
	 */
	public int getExtmallOrderExceluploadWateCnt(int userNo) {
		return orderOcmDao.getExtmallOrderExceluploadWateCnt(userNo);
	}

	/**
	 * 제휴몰주문등록 엑셀 저장
	 *
	 * @param excelExtmallOrderList - 외부몰주문등록리스트
	 * @param excelFilename - 엑셀파일명
	 * @return void
	 * @author jmh
	 * @since 2021. 06. 15
	 */
	@Transactional("shopTxnManager")
	public void createExtmallOrderExcelupload(Collection<GagaMap> excelExtmallOrderList, String excelFilename, int userNo) {
		String targetPath = env.getProperty("upload.excel.target.path");

		if ((excelExtmallOrderList == null || excelExtmallOrderList.isEmpty())) {
			try {
				GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, excelFilename));
			} catch (IOException e) {
				// Nothing Do
			}
			throw new IllegalStateException(message.getMessage("FAIL_0001"));
		}
		orderOcmDao.deleteExtmallOrderUploadTmp(userNo);

		// 샵링커 주문번호 중복여부 체크(중복인경우 등록불가)
		ArrayList<String> arrayList = new ArrayList<>();
		ArrayList<String> overlapList = new ArrayList<>();
        for (GagaMap item : excelExtmallOrderList) {
        	if(!arrayList.contains(item.getString("agentOrderId"))) {
            	arrayList.add(item.getString("agentOrderId"));
            }else {
            	overlapList.add(item.getString("agentOrderId"));
            }
        }

        if( 0 < overlapList.size()) {
        	throw new IllegalStateException(message.getMessage("FAIL_0001")+" \n중복된 물품주문번호가 존재합니다 : "+overlapList);
        }

		int dataIndex = 2;
		int index = 0;
		String vendorId = "";
		for (GagaMap gagaMap : excelExtmallOrderList) {
			gagaMap.setString("currPrice", gagaMap.getString("currPrice").replaceAll(",", ""));
			gagaMap.setString("ordQty", gagaMap.getString("ordQty").replaceAll(",", ""));
			gagaMap.setString("delvFee", gagaMap.getString("delvFee").replaceAll(",", ""));

			ExtmallOrder extmallOrder = mapper.convertValue(gagaMap, ExtmallOrder.class);
			String[] params = extmallOrder.getParams();
			String[] columns = extmallOrder.getColumns();

			for (int validation = 0; validation < params.length; validation++) {
				if( validation != 0 && validation != 13 && validation != 20 ) {	// 첫번재열, 이메일 미체크, 배송MEMO
					if ("".equals(params[validation]) || params[validation] == null || "null".equals(params[validation])) {
						throw new IllegalStateException(dataIndex + "행에 " + columns[validation] + "(을)를 입력해 주세요.");
					}
				}
			}

			//extmallOrder.setOrdDt(extmallOrder.getOrdDt().replace("-", ""));
			//extmallOrder.setPayDt(extmallOrder.getPayDt().replace("-", ""));
			extmallOrder.setVendorId(TscConstants.VendorId.SHOPLINKER.value());
			extmallOrder.setOrdAmt(extmallOrder.getCurrPrice() * extmallOrder.getOrdQty());
			extmallOrder.setUploadStat(TscConstants.ExtmallUploadStat.WAIT.value());
			extmallOrder.setRegNo(userNo);
			extmallOrder.setUploadGb("E");
			orderOcmDao.createExtmallOrderUploadTmp(extmallOrder);
			dataIndex++;
			index++;
		}

		// 결과조회시, 실패목록이 여러건 뜨지 않도록 하기위함. => 실패 history가 단건만 생성되도록
		orderOcmDao.deleteExtmallOrderUploadFail(userNo);
	}

	/**
	 * 제휴몰주문등록 업로드 후 목록
	 *
	 * @param ExtmallOrder - 외부몰 주문등록 정보
	 * @return Collection<ExtmallOrder>
	 * @author jmh
	 * @since 2021. 06. 15
	 */
	public Collection<ExtmallOrder> getExtmallOrderUploadTmpList(int userNo) {
		ExtmallOrder extmallOrder = new ExtmallOrder();
		extmallOrder.setRegNo(userNo);
		return orderOcmDao.getExtmallOrderUploadTmpList(extmallOrder);
	}

	/**
	 * 제휴몰주문등록 업로드 후 저장 처리
	 *
	 * @param extmallOrderUpload - 외부몰주문업로드 정보
	 * @return String - 결과값
	 * @author jmh
	 * @since 2020. 06. 15
	 */
	public String saveExtmallorder(ExtmallOrder extmallOrder) {

		int collectCnt = orderOcmDao.createExtmallOrderUploadSecond(extmallOrder);
		//log.info("STEP2 2.1.외부몰주문업로드 데이터 생성: 성공({} 건)", collectCnt);

		if( 0 < collectCnt ) {
			this.createShoplinkerOrder("E", extmallOrder.getRegNo());
		}

		ExtmallOrder resultInfo = orderOcmDao.getExtmallOrderUploadResultInfo(extmallOrder);

		return message.getMessage("SABANGNET_0004", new Object[] {collectCnt, resultInfo.getSuccCnt(), resultInfo.getFailCnt()});
	}

	/**
	 * 제휴몰주문등록 업로드 후 목록
	 *
	 * @return Collection<ExtmallOrder>
	 * @author jmh
	 * @since 2020. 06. 15
	 */
	public Collection<ExtmallOrder> getExtmallOrderUploadSecondList(ExtmallOrder extmallOrder) {
		return orderOcmDao.getExtmallOrderUploadSecondList(extmallOrder);
	}


}
