package com.style24.scm.biz.service;

import java.io.IOException;
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 org.springframework.util.StringUtils;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.style24.core.support.message.TscMessageByLocale;
import com.style24.persistence.domain.Brand;
import com.style24.persistence.domain.Goods;
import com.style24.persistence.domain.GoodsDesc;
import com.style24.persistence.domain.GoodsHst;
import com.style24.persistence.domain.GoodsImg;
import com.style24.persistence.domain.GoodsNotiInfo;
import com.style24.persistence.domain.GoodsPriceRes;
import com.style24.persistence.domain.GoodsSearch;
import com.style24.persistence.domain.NotiInfo;
import com.style24.persistence.domain.Notice;
import com.style24.persistence.domain.NoticeGoods;
import com.style24.persistence.domain.Option;
import com.style24.persistence.domain.SearchData;
import com.style24.scm.biz.dao.TssGoodsDao;
import com.style24.scm.support.env.TssConstants;
import com.style24.scm.support.security.session.TssSession;

import lombok.extern.slf4j.Slf4j;

import com.gagaframework.excel.GagaExcelUtil;
import com.gagaframework.excel.env.GagaExcelConstants;
import com.gagaframework.web.parameter.GagaMap;
import com.gagaframework.web.util.GagaDateUtil;
import com.gagaframework.web.util.GagaFileUtil;
import com.gagaframework.web.util.GagaStringUtil;

/**
 *상품 Service
 *
 * @author gagamel
 * @since 2020. 10. 19
 */
@Service
@Slf4j
public class TssGoodsService {

	@Autowired
	private TscMessageByLocale message;

	@Autowired
	private Environment env;

	@Autowired
	private TssGoodsDao goodsDao;

	@Autowired
	private TssCommonService commonService;

	@Autowired
	private TssBusinessService businessService;

	@Autowired
	private TssNoticeService noticeService;

	@Autowired
	private ObjectMapper mapper;

	/**
	 * 상품 목록 건수
	 *
	 * @param goodsSearch
	 * @return
	 * @author eskim
	 * @since 2020. 10. 20
	 */
	public int getGoodsListCount(GoodsSearch goodsSearch) {
		return goodsDao.getGoodsListCount(goodsSearch);
	}

	/**
	 * 상품 목록
	 *
	 * @param goodsSearch
	 * @return
	 * @author eskim
	 * @since 2020. 10. 20
	 */
	public Collection<Goods> getGoodsList(GoodsSearch goodsSearch) {
		return goodsDao.getGoodsList(goodsSearch);
	}

	/**
	 * 상품목록 - 기본정보 엑셀다운로드
	 *
	 * @param goodsSearch
	 * @param excelFilenameWithPath - 경로를 포함한 엑셀파일명
	 * @return
	 * @author eskim
	 * @since 2020. 10. 21
	 */
	public void getGoodsInfoExcelList(GoodsSearch goodsSearch, String excelFilenameWithPath) {

		if ("Y".equals(goodsSearch.getImageViewYn())) {
			// 헤더 title 설정
			String[] listTitles = {"이미지", "상품코드", "업체명", "브랜드명", "상품명", "품목", "재고", "상품상태", "스타일년도", "시즌",
				"정상가", "판매가", "할인율", "가격변경일", "ERP재고연동여부", "정상이월구분", "반품가능 여부", "승인일시"};

			// DB 처리 시 사용되는 파라미터명(셀명) 설정
			String[] cellNames = {"SYS_IMG_NM", "GOODS_CD", "SUPPLY_COMP_CD", "BRAND_GRP_NM", "GOODS_NM", "ITEMKIND_NM",
				"STOCK_QTY_SUM", "GOODS_STAT", "STYLE_YEAR", "SEASON_CD", "LIST_PRICE", "CURR_PRICE",
				"DC_RATE", "PRICE_UPD_DT", "ERP_STOCK_LINK_YN", "FORMAL_GB", "RETURNABLE_YN", "FRST_CFRM_DT"};

			String[] cellTypes = {GagaExcelConstants.CellType.IMAGE.name(),
				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_RIGHT.name(),
				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_RIGHT.name(),
				GagaExcelConstants.CellType.CHAR_RIGHT.name(), GagaExcelConstants.CellType.CHAR_RIGHT.name(),
				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
				GagaExcelConstants.CellType.CHAR_CENTER.name(),
				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name()};

			String targetPath = env.getProperty("upload.goods.view");
			Collection<GagaMap> dataList = goodsDao.getGoodsInfoExcelList(goodsSearch); // map형식으로 조회
			if (dataList != null && !dataList.isEmpty()) {
				for (GagaMap gagaMap : dataList) {
					if (!StringUtils.isEmpty(gagaMap.get("SYS_IMG_NM").toString()) ) {
						gagaMap.set("SYS_IMG_NM", targetPath + '/' +  gagaMap.get("SYS_IMG_NM").toString());
					}
				}
			}

			try {
				GagaExcelUtil.createExcel(excelFilenameWithPath, dataList, "상품 정보", listTitles, cellNames, cellTypes, TssConstants.EXCEL_FOOTER_TITLE);
			} catch (Exception e) {
				throw new IllegalStateException(e);
			}

		} else {
			// 헤더 title 설정
			String[] listTitles = {"상품코드", "업체명", "브랜드명", "상품명", "품목", "재고", "상품상태", "스타일년도",
				"시즌", "정상가", "판매가", "할인율", "가격변경일", "ERP재고연동여부", "정상이월구분", "반품가능 여부", "승인일시"};

			// DB 처리 시 사용되는 파라미터명(셀명) 설정
			String[] cellNames = {"GOODS_CD", "SUPPLY_COMP_CD", "BRAND_GRP_NM", "GOODS_NM", "ITEMKIND_NM", "STOCK_QTY_SUM", "GOODS_STAT", "STYLE_YEAR",
				"SEASON_CD", "LIST_PRICE", "CURR_PRICE", "DC_RATE", "PRICE_UPD_DT", "ERP_STOCK_LINK_YN", "FORMAL_GB", "RETURNABLE_YN", "FRST_CFRM_DT"};

			String[] cellTypes = {
				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_RIGHT.name(),
				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_RIGHT.name(),
				GagaExcelConstants.CellType.CHAR_RIGHT.name(), GagaExcelConstants.CellType.CHAR_RIGHT.name(),
				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name(),
				GagaExcelConstants.CellType.CHAR_CENTER.name(), GagaExcelConstants.CellType.CHAR_CENTER.name()};

			Collection<GagaMap> dataList = goodsDao.getGoodsInfoExcelList(goodsSearch);

			try {
				GagaExcelUtil.createExcel(excelFilenameWithPath, dataList, "상품 정보", listTitles, cellNames, cellTypes, TssConstants.EXCEL_FOOTER_TITLE);
			} catch (Exception e) {
				throw new IllegalStateException(e);
			}
		}
	}

	/**
	 * 상품 수정 항목 일괄변경
	 *
	 * @param goods
	 * @author eskim
	 * @since 2020. 01. 17
	 */
	@Transactional("shopTxnManager")
	public void updateGoodsState(Goods goods) {
		if (goods == null || (goods.getArrGoodsCd() == null && goods.getArrGoodsCd().length <= 0)) {
			throw new IllegalStateException(message.getMessage("FAIL_1001"));
		}

		goods.setRegNo(TssSession.getInfo().getUserNo());
		goods.setUpdNo(TssSession.getInfo().getUserNo());

		if (goods.getArrGoodsCd().length > 0) {
			for (String goodsCd : goods.getArrGoodsCd()) {

				goods.setGoodsCd(goodsCd);
				// 이력생성
				goodsDao.createGoodsHst(goods);

				if ("formalGb".equals(goods.getProcJob())) {
					// 상품브랜드 조회
					Goods originGoods = goodsDao.getGoods(goods);
					// 브랜드 확인
					goods.setPntPrate(originGoods.getPntPrate()); // 포인트적립율(PC)
					goods.setPntMrate(originGoods.getPntMrate()); // 포인트적립율(MOBILE)
					Brand brand = new Brand();
					brand.setBrandCd(originGoods.getBrandCd());
					Collection<Brand> brandList = businessService.getBrandList(brand);
					if (brandList != null && !brandList.isEmpty()) {
						float pntPrate = 0;
						float pntMrate = 0;
						for (Brand tmpBrand : brandList) {
							if ("G009_10".equals(goods.getFormalGb())) {
								pntPrate = tmpBrand.getPntPrate10();
								pntMrate = tmpBrand.getPntMrate10();
							} else {
								pntPrate = tmpBrand.getPntPrate20();
								pntMrate = tmpBrand.getPntMrate20();
							}
						}
						goods.setPntPrate(pntPrate); // 포인트적립율(PC)
						goods.setPntMrate(pntMrate); // 포인트적립율(MOBILE)
					}
				} else if ("goodsStat".equals(goods.getProcJob())) {
					// 상품브랜드 조회
					Goods originGoods = goodsDao.getGoods(goods);

					// 승인일
					if (!goods.getGoodsStat().equals(originGoods.getGoodsStat()) && "G008_90".equals(goods.getGoodsStat())) {
						goods.setChGoodsStatYn("Y");
					}
				}
				// 상품정보 변경
				goodsDao.updateGoodsState(goods);
			}

		} else {

			// 이력생성
			goodsDao.createGoodsHst(goods);
			if ("formalGb".equals(goods.getProcJob())) {
				// 상품브랜드 조회
				Goods originGoods = goodsDao.getGoods(goods);
				// 브랜드 확인
				goods.setPntPrate(originGoods.getPntPrate()); // 포인트적립율(PC)
				goods.setPntMrate(originGoods.getPntMrate()); // 포인트적립율(MOBILE)
				Brand brand = new Brand();
				brand.setBrandCd(originGoods.getBrandCd());
				Collection<Brand> brandList = businessService.getBrandList(brand);
				if (brandList != null && !brandList.isEmpty()) {
					float pntPrate = 0;
					float pntMrate = 0;
					for (Brand tmpBrand : brandList) {
						if ("G009_10".equals(goods.getFormalGb())) {
							pntPrate = tmpBrand.getPntPrate10();
							pntMrate = tmpBrand.getPntMrate10();
						} else {
							pntPrate = tmpBrand.getPntPrate20();
							pntMrate = tmpBrand.getPntMrate20();
						}
					}
					goods.setPntPrate(pntPrate); // 포인트적립율(PC)
					goods.setPntMrate(pntMrate); // 포인트적립율(MOBILE)
				}
			}
			// 상품정보 변경
			goodsDao.updateGoodsState(goods);
		}
	}

	/**
	 * 상품 이미지 등록여부 조회
	 *
	 * @param goods
	 * @return
	 * @author eskim
	 * @since 2020. 10. 21
	 */
	public Collection<Goods> getGoodsImgsYn(Goods goods) {
		return goodsDao.getGoodsImgsYn(goods);
	}

	/**
	 * 상품 상세
	 *
	 * @param goods
	 * @return
	 * @author eskim
	 * @since 2020. 10. 22
	 */
	public Goods getGoods(Goods goods) {
		// 상품기본정보
		Goods resultGoods = goodsDao.getGoods(goods);

		// 상품 상세
		this.getGoodsDesc(resultGoods);
		return resultGoods;
	}

	/**
	 * 상품 상세 조회
	 *
	 * @param resultGoods
	 * @return
	 * @author eskim
	 * @since 2020. 10. 22
	 */
	private Goods getGoodsDesc(Goods resultGoods) {

		GoodsDesc goods = new GoodsDesc();
		goods.setGoodsCd(resultGoods.getGoodsCd());

		//		goods.setDescGb("10");
		//		String goodsDesc = this.getGoodsDescList(goods);
		//		resultGoods.setGoodsDesc(goodsDesc);

		// 상품 상세 pc 상단
		goods.setDescGb("20");
		String goodsPcTopDesc = this.getGoodsDescList(goods);
		resultGoods.setGoodsPcTopDesc(goodsPcTopDesc);

		// 상품 상세  pc 하단
		goods.setDescGb("30");
		String goodsPcDownDesc = this.getGoodsDescList(goods);
		resultGoods.setGoodsPcDownDesc(goodsPcDownDesc);

		// 상품 상세 mobile 상단
		goods.setDescGb("40");
		String goodsMobileTopDesc = this.getGoodsDescList(goods);
		resultGoods.setGoodsMobileTopDesc(goodsMobileTopDesc);

		// 상품 상세 mpbile 하단
		goods.setDescGb("50");
		String goodsMobileDownDesc = this.getGoodsDescList(goods);
		resultGoods.setGoodsMobileDownDesc(goodsMobileDownDesc);

		return resultGoods;
	}

	/**
	 * 상품 상세구분별 컨텐츠 조회
	 *
	 * @param goods
	 * @return
	 * @author eskim
	 * @since 2020. 10. 22
	 */
	private String getGoodsDescList(GoodsDesc goodsDesc) {
		Collection<GoodsDesc> goodsDescList = goodsDao.getGoodsDescList(goodsDesc);
		StringBuilder goodsDescSb = new StringBuilder();
		if (goodsDescList != null && !goodsDescList.isEmpty()) {
			for (GoodsDesc tmpGoodsDesc : goodsDescList) {
				goodsDescSb.append(tmpGoodsDesc.getGoodsDesc());
			}
		}
		return goodsDescSb.toString();
	}

	/**
	 * 상품 정보 이력 조회
	 *
	 * @param goods
	 * @return
	 * @author eskim
	 * @since 2019. 12. 12
	 */
	public Collection<GoodsHst> getGoodsHstList(Goods goods) {
		return goodsDao.getGoodsHstList(goods);
	}

	/**
	 * 상품 옵션 조회
	 *
	 * @param goods
	 * @return
	 * @author eskim
	 * @since 2020. 10. 26
	 */
	public Collection<Option> getGoodsSizeList(Goods goods) {
		return goodsDao.getGoodsSizeList(goods);
	}

	/**
	 * 상품 색상목록 조회
	 *
	 * @param goods
	 * @return
	 * @author eskim
	 * @since 2020. 11. 18
	 */
	public Collection<GoodsImg> getGoodsColorList(Goods goods) {
		return goodsDao.getGoodsColorList(goods);
	}

	/**
	 * 상품 정보고시 조회
	 *
	 * @param goods
	 * @return
	 * @author eskim
	 * @since 2020. 10. 22
	 */
	public Collection<GoodsNotiInfo> getGoodsNotiInfoList(GoodsNotiInfo goodsNotiInfo) {
		return goodsDao.getGoodsNotiInfoList(goodsNotiInfo);
	}

	/**
	 * 상품 구매등급 조회
	 *
	 * @param goods
	 * @return
	 * @author eskim
	 * @since 2020. 11. 18
	 */
	public Collection<Goods> getGoodsDetailOrderGradeList(Goods goods) {
		return goodsDao.getGoodsDetailOrderGradeList(goods);
	}

	/**
	 * 상품의 정보고시 항목 목록
	 *
	 * @param notiInfo
	 * @return
	 * @author eskim
	 * @since 2020. 11. 18
	 */
	public Collection<NotiInfo> getNotiGoodsInfoList(NotiInfo notiInfo) {
		return goodsDao.getNotiGoodsInfoList(notiInfo);
	}

	/**
	 * 엑셀조회용 상품 저장
	 *
	 * @param procJob : goodsExcelUpload
	 * @param goodsList
	 * @return
	 * @author eskim
	 * @since 2020. 10. 22
	 */
	@Transactional("shopTxnManager")
	public void saveExceluploadGoods(Collection<Goods> goodsList, String excelFilename) {

		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.excel.target.path"), "excel");
		if (goodsList == null || goodsList.isEmpty()) {
			this.deleteExceluploadFile(targetPath, excelFilename);
			throw new IllegalStateException(message.getMessage("FAIL_1001"));
		}

		int index = 0;
		String goodsCdFlag = "";
		String goodsNumFlag = "";
		for (Goods goods : goodsList) {

			if (!StringUtils.isEmpty(goodsCdFlag) && !StringUtils.isEmpty(goodsNumFlag)) {
				throw new IllegalStateException("상품코드와 원코드 중 한 개의 셀에만 값을 입력해서 조회하세요.");
			}

			if (!StringUtils.isEmpty(goods.getSupplyCompCd())) {
				goods.setGoodsCd(goods.getSupplyCompCd());
			}

			SearchData searchData = new SearchData();
			searchData.setRegNo(goods.getRegNo());
			searchData.setSearchCd(goods.getGoodsCd());
			if (index == 0) {
				commonService.deleteExceluploadSearCh(searchData);
			}

			commonService.createExceluploadSearch(searchData);
			index++;
		}
	}

	/**
	 * 파일 삭제
	 *
	 * @param targetPath
	 * @param excelFilename
	 * @author eskim
	 * @since 2020. 10. 22
	 */
	private void deleteExceluploadFile(String targetPath, String excelFilename) {
		// 파일 삭제
		try {
			GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, excelFilename));
		} catch (IOException e) {
			// Nothing Do
		}
	}

	/**
	 * 상품 저장
	 *
	 * @param goods
	 * @return
	 * @author eskim
	 * @since 2020. 10. 27
	 */
	@Transactional("shopTxnManager")
	public void saveGoodsDetail(Goods goods) {

		// <,> replace 처리
		goods.setRegNo(TssSession.getInfo().getUserNo());
		goods.setUpdNo(TssSession.getInfo().getUserNo());

		goods.setGoodsPcTopDesc(GagaStringUtil.replace(GagaStringUtil.replace(goods.getGoodsPcTopDesc(), "&lt;", "<"), "&gt;", ">"));
		goods.setGoodsMobileTopDesc(GagaStringUtil.replace(GagaStringUtil.replace(goods.getGoodsMobileTopDesc(), "&lt;", "<"), "&gt;", ">"));
		goods.setGoodsPcDownDesc(GagaStringUtil.replace(GagaStringUtil.replace(goods.getGoodsPcDownDesc(), "&lt;", "<"), "&gt;", ">"));
		goods.setGoodsMobileDownDesc(GagaStringUtil.replace(GagaStringUtil.replace(goods.getGoodsMobileDownDesc(), "&lt;", "<"), "&gt;", ">"));

		goods.setGoodsNm(GagaStringUtil.replace(GagaStringUtil.replace(goods.getGoodsNm(), "&lt;", "<"), "&gt;", ">"));
		goods.setGoodsTnm(GagaStringUtil.replace(GagaStringUtil.replace(goods.getGoodsTnm(), "&lt;", "<"), "&gt;", ">"));
		goods.setGoodsSnm1(GagaStringUtil.replace(GagaStringUtil.replace(goods.getGoodsSnm1(), "&lt;", "<"), "&gt;", ">"));

		// 가격, 수수료 승인처리시
//		// 가격변경일
//		if (goods.getCurrPrice() != goods.getCurrPriceOrg()) {
//			goods.setCurrBprice(goods.getCurrPriceOrg());
//		} else {
//			goods.setCurrPrice(goods.getCurrPriceOrg());
//		}
//
//		// 승인일
//		if (!goods.getGoodsStat().equals(goods.getGoodsStatOrg())) {
//			goods.setChGoodsStatYn("Y");
//		}
		if ("Y".equals(goods.getChCfrmYn())) {
			GoodsPriceRes goodsPriceRes = new GoodsPriceRes();
			goodsPriceRes.setGoodsCd(goods.getGoodsCd());
			if (goods.getCurrPrice() != goods.getCurrPriceOrg()) {
				goodsPriceRes.setResGoodsPrice(goods.getCurrPrice());
				goodsPriceRes.setEndGoodsPrice(goods.getCurrPrice());
			}
			if (goods.getSellFeeRate() != goods.getSellFeeRateOrg()) {
				goodsPriceRes.setSellFeeRate(goods.getSellFeeRate());
			}
			goodsPriceRes.setApplyStdt(GagaDateUtil.getTodayDateTime());	//yyyymmddhhmiss
			int toYear = Integer.parseInt(GagaDateUtil.getToday("yyyy")) + 4;
			goodsPriceRes.setApplyEddt(toYear +"1231235959");	//yyyymmddhhmiss
			goodsPriceRes.setCfrmYn("N");
			goodsPriceRes.setApplyYn("N");
			goodsPriceRes.setRegNo(goods.getRegNo());
			goodsPriceRes.setUpdNo(goods.getUpdNo());
			goodsDao.createGoodPriceRes(goodsPriceRes);

			goods.setCurrPrice(goods.getCurrPriceOrg());
			goods.setSellFeeRate(goods.getSellFeeRateOrg());
		}

		// 선물 주문여부 N 설정
		goods.setGiftPackYn("N");
		// 사용자 검색어를 검색어에 적용
		String goodsSnm = goodsDao.getGoodsSnm(goods.getGoodsCd());
		if (!StringUtils.isEmpty(goods.getGoodsSnm1())) {
			goods.setGoodsSnm1(GagaStringUtil.replace(goods.getGoodsSnm1(), " ", "")); // 빈값 삭제
			String[] arrGoodsSnm = goods.getGoodsSnm1().split(";");
			StringBuilder tempGoodsSnm = new StringBuilder();
			for (String loopGoodsSnm : arrGoodsSnm) {
				if (goodsSnm.toUpperCase().indexOf(loopGoodsSnm.toUpperCase()) <= -1) {
					tempGoodsSnm.append(loopGoodsSnm).append(";");
				}
			}
			goods.setGoodsSnm(tempGoodsSnm.toString() + goodsSnm);

		} else if (!goodsSnm.equals(goods.getGoodsSnm())) {
			goods.setGoodsSnm(goodsSnm);
		}

		goods.setFormalGb(goods.getFormalGb());
		// 브랜드 확인
		if (!"G056_N".equals(goods.getGoodsType())) {
			if (!goods.getFormalGb().equals(goods.getFormalGbOrg())) {
				Brand brand = new Brand();
				brand.setBrandCd(goods.getBrandCd());
				Collection<Brand> brandList = businessService.getBrandList(brand);
				if (brandList != null && !brandList.isEmpty()) {
					float pntPrate = 0.0f;
					float pntMrate = 0.0f;
					for (Brand tmpBrand : brandList) {
						if ("G009_10".equals(goods.getFormalGb())) {
							pntPrate = tmpBrand.getPntPrate10();
							pntMrate = tmpBrand.getPntMrate10();
						} else {
							pntPrate = tmpBrand.getPntPrate20();
							pntMrate = tmpBrand.getPntMrate20();
						}
					}
					goods.setPntPrate(pntPrate); // 포인트적립율(PC)
					goods.setPntMrate(pntMrate); // 포인트적립율(MOBILE)
				}
			}
		}

		// 기본정보 변경
		if ("Y".equals(goods.getChDataYn())) {
			goodsDao.createGoodsHst(goods);
			goodsDao.updateGoods(goods);
		}

		// 상품상세정보 변경
		if (!"Y".equals(goods.getChkDescKeep())) {
			this.saveGoodsDetailDesc(goods);
		}

//		int idx = 1;
//		// 구성상품 변경
//		if (!"G056_N".equals(goods.getGoodsType())) {
//
//			Collection<GoodsCompose> goodsExtendList = goods.getGoodsComposeListNew();
//			for (GoodsCompose regGoodsExtend : goodsExtendList) {
//				regGoodsExtend.setDispOrd(idx);
//				regGoodsExtend.setRegNo(TssSession.getInfo().getUserNo());
//				regGoodsExtend.setUpdNo(TssSession.getInfo().getUserNo());
//				goodsDao.saveGoodsCompose(regGoodsExtend); // 구성상품기본 저장
//
//				idx++;
//			}
//		}

		// 옵션/재고 변경
		if (goods.getOptCd() != null && goods.getOptCd().length > 0 && "Y".equals(goods.getChStockDataYn())) {
			this.saveStock(goods);
		}

		// 상품 정보고시 변경
		this.saveGoodsNotiInfo(goods);

		// 상품 구매등급 적용
		if (goods.getGoodsOrderGrade() != null && goods.getGoodsOrderGrade().length > 0) {
			Goods goodsOrderGrade = new Goods();
			goodsOrderGrade.setGoodsCd(goods.getGoodsCd());
			goodsOrderGrade.setRegNo(TssSession.getInfo().getUserNo());
			goodsDao.deleteGoodsCustGrade(goodsOrderGrade);
			for(String custGrade : goods.getGoodsOrderGrade()) {
				goodsOrderGrade.setCustGrade(custGrade);
				goodsDao.createGoodsCustGrade(goodsOrderGrade);
			}
		}else {
			Goods goodsOrderGrade = new Goods();
			goodsOrderGrade.setGoodsCd(goods.getGoodsCd());
			goodsOrderGrade.setRegNo(TssSession.getInfo().getUserNo());
			goodsDao.deleteGoodsCustGrade(goodsOrderGrade);
		}

	}

	/**
	 * 상품상세정보 변경 - 상품상세
	 *
	 * @param goods
	 * @author eskim
	 * @since 2020. 10. 27.
	 */
	private void saveGoodsDetailDesc(Goods goods) {
		// 상품상세 구분(10:상품설명, 20:상위컨텐츠, 30:하위컨텐츠, 40:하위컨텐츠-모바일, 50:상위컨텐츠-모바일)
		GoodsDesc goodsDesc = new GoodsDesc();
		goodsDesc.setGoodsCd(goods.getGoodsCd());
		goodsDesc.setRegNo(goods.getRegNo());
		goodsDesc.setUpdNo(goods.getUpdNo());

		// PC 상단
		goodsDesc.setDescGb("10");
		goodsDesc.setGoodsDesc(goods.getGoodsPcTopDesc());
		this.saveGoodsDesc(goodsDesc);

		// PC 하단
		goodsDesc.setDescGb("20");
		goodsDesc.setGoodsDesc(goods.getGoodsPcTopDesc());
		this.saveGoodsDesc(goodsDesc);

		// 공용 하단
		goodsDesc.setDescGb("30");
		goodsDesc.setGoodsDesc(goods.getGoodsPcDownDesc());
		this.saveGoodsDesc(goodsDesc);

		// MO 상단
		goodsDesc.setDescGb("40");
		goodsDesc.setGoodsDesc(goods.getGoodsMobileTopDesc());
		this.saveGoodsDesc(goodsDesc);

		//		// 상품상세 저장

		//
		//		// 세트상품의 구서상품으로 있을경우 처리
		//		this.saveGoodsSetDesc(goodsDesc);

		// MO 하단
		goodsDesc.setDescGb("50");
		goodsDesc.setGoodsDesc(goods.getGoodsMobileDownDesc());
		this.saveGoodsDesc(goodsDesc);
	}

	/**
	 * 상품 상세 저장
	 *
	 * @param goodsDesc
	 * @return
	 * @author eskim
	 * @since 2020. 10. 27
	 */
	private void saveGoodsDesc(GoodsDesc goodsDesc) {

		goodsDao.deleteGoodsDesc(goodsDesc);

		String[] arrProdHtml = null;
		arrProdHtml = makeArrayToString(goodsDesc.getGoodsDesc(), 3900);
		if (arrProdHtml.length > 0) {
			for (int i = 0; i < arrProdHtml.length; i++) {
				if (!arrProdHtml[i].isEmpty()) {
					goodsDesc.setSeq(i + 1);
					goodsDesc.setGoodsDesc(arrProdHtml[i]);
					goodsDao.createGoodsDesc(goodsDesc);
				}
			}
		}
	}

	/**
	 * String => byte array
	 *
	 * @param raw
	 * @param len
	 * @return
	 * @author eskim
	 * @since 2020. 10. 27
	 */
	public static String[] makeArrayToString(String raw, int len) {

		String[] ary = null;

		if (raw == null) {
			return ary;
		}

		try {

			// raw 의 byte
			byte[] rawBytes = raw.getBytes("UTF-8"); // MS949
			int rawLength = rawBytes.length;

			if (rawLength > len) {
				int aryLength = (rawLength / len) + (rawLength % len != 0 ? 1 : 0);
				ary = new String[aryLength];

				int endCharIndex = 0; // 문자열이 끝나는 위치
				String tmp;
				for (int i = 0; i < aryLength; i++) {

					if (i == (aryLength - 1)) {
						tmp = raw.substring(endCharIndex);
					} else {

						int useByteLength = 0;
						int rSize = 0;
						for (; endCharIndex < raw.length(); endCharIndex++) {

							if (raw.charAt(endCharIndex) > 0x007F) {
								useByteLength += 3;
							} else {
								useByteLength++;
							}
							if (useByteLength > len) {
								break;
							}
							rSize++;
						}
						tmp = raw.substring((endCharIndex - rSize), endCharIndex);
					}

					ary[i] = tmp;
				}

			} else {
				ary = new String[] {raw};
			}

		} catch (java.io.UnsupportedEncodingException e) {
		}

		return ary;
	}

	/**
	 * 옵션/재고 변경 - 상품상세
	 *
	 * @param goods
	 * @param index
	 * @author eskim
	 * @since 2020. 10. 27
	 */
	private void saveStock(Goods goods) {
		int index = 0;
		Option stock = new Option();
		stock.setGoodsCd(goods.getGoodsCd());
		stock.setUpdNo(goods.getUpdNo());
		stock.setRegNo(goods.getRegNo());
		goodsDao.createStockHst(stock);
		log.info("saveStock goods={}", goods);
		for (String optCd : goods.getOptCd()) {
			log.info("saveStock index={}", index);
			log.info("saveStock optCd={}", optCd);
			Option goodsStock = new Option();
			goodsStock.setGoodsCd(goods.getCompsGoodsCd()[index]); // 구성상품 코드
			goodsStock.setOptCd(optCd);
			goodsStock.setOptCd1(goods.getOptCd1()[index]);
			goodsStock.setOptCd2(goods.getOptCd2()[index]);
			goodsStock.setBaseStockQty(Integer.parseInt(goods.getBaseStockQty()[index]));
			goodsStock.setSoldoutYn(goods.getSoldoutYn()[index]);
			goodsStock.setDispOrd(goods.getDispOrd()[index]);
			goodsStock.setDispYn(goods.getDispYn()[index]);
			goodsStock.setRegNo(goods.getRegNo());
			goodsStock.setUpdNo(goods.getUpdNo());

			if ("N".equals(goods.getSelfGoodsYn())) {
				goodsStock.setSelfGoodsYn(goods.getSelfGoodsYn());
				goodsStock.setCurrStockQty(Integer.parseInt(goods.getEditCurrStockQty()[index]));
			}
			goodsDao.saveStock(goodsStock);
			index++;
		}
	}

	/**
	 * 상품 사이즈 옵션정보 이력 생성
	 *
	 * @param goods
	 * @author eskim
	 * @since 2020. 11. 17
	 */
	@Transactional("shopTxnManager")
	public void createStockHst(Option option) {
		goodsDao.createStockHst(option);
	}

	/**
	 * 상품 정보고시 변경 - 상품상세
	 *
	 * @param goods
	 * @author eskim
	 * @since 2020. 10. 27
	 */
	private void saveGoodsNotiInfo(Goods goods) {
		int index;
		if (goods.getNotiListNew() != null && !goods.getNotiListNew().isEmpty()) {
			index = 0;
			for (GoodsNotiInfo goodsNotiInfo : goods.getNotiListNew()) {
				if (index == 0) {
					goodsDao.deleteGoodsNotiInfo(goods);
				}
				goodsNotiInfo.setNiContent(GagaStringUtil.replace(GagaStringUtil.replace(goodsNotiInfo.getNiContent(), "&lt;", "<"), "&gt;", ">"));
				goodsNotiInfo.setRegNo(goods.getRegNo());
				goodsNotiInfo.setUpdNo(goods.getUpdNo());
				goodsDao.saveGoodsNotiInfo(goodsNotiInfo);
				index++;
			}
		}
	}

	/**
	 * 상품 할인율 계산
	 *
	 * @param value
	 * @param len
	 * @param pad
	 * @return
	 */
	private long getDcRate(int listPrice, int currPrice) {
		double rate = (double)(currPrice) / (double)(listPrice);
		return 100 - (long)((Math.round(rate * 100) / 100.0) * 100);
	}

	/**
	 * 상품별 옵션 등록 여부 확인
	 *
	 * @param
	 * @return
	 * @author eskim
	 * @since 2020. 11. 17
	 */
	public int getGoodsOptionCount(Option option) {

		return goodsDao.getGoodsOptionCount(option);
	}

	/**
	 * 상품 가격승인관리 목록 건수
	 *
	 * @param goodsPriceHst
	 * @return
	 * @author eskim
	 * @since 2020. 11. 26
	 */
	public int getGoodsSupplyPriceCount(GoodsPriceRes goodsPriceHst) {

		return goodsDao.getGoodsSupplyPriceCount(goodsPriceHst);
	}

	/**
	 * 상품 가격승인관리 목록 조회
	 *
	 * @param goodsPriceHst
	 * @return
	 * @author eskim
	 * @since 2020. 11. 26
	 */
	public Collection<GoodsPriceRes> getGoodsSupplyPriceList(GoodsPriceRes goodsPriceHst) {

		return goodsDao.getGoodsSupplyPriceList(goodsPriceHst);
	}

	/**
	 * 상품 상세공지 목록
	 *
	 * @param goodsSearch
	 * @return
	 * @author eskim
	 * @since 2020. 11. 27
	 */
	public Collection<Notice> getNoticeList(GoodsSearch goodsSearch) {
		return goodsDao.getNoticeList(goodsSearch);
	}

	/**
	 * 상품 상세공지 상품 목록
	 *
	 * @param notice
	 * @return
	 * @author eskim
	 * @since 2020. 11. 27
	 */
	public Collection<NoticeGoods> getNoticeGoodsList(Notice notice) {
		return goodsDao.getNoticeGoodsList(notice);
	}

	/**
	 * 공지사항 저장
	 * @param notice - 공지사항 정보
	 * @return
	 * @author eskim
	 * @since 2020. 11. 27
	 */
	@Transactional("shopTxnManager")
	public void saveNotice(Notice notice) {
		notice.setRegNo(TssSession.getInfo().getUserNo());
		notice.setUpdNo(TssSession.getInfo().getUserNo());

		// 신규 일때
		if (notice.getNoticeSq() == null) {
			// 공지사항 저장
			noticeService.createNotice(notice);

			// 등록된 사용자번호 값 가져오기
			Integer noticeSq = notice.getNoticeSq();

			notice.setNoticeSq(noticeSq);

		} else {
			// 공지사항 수정
			noticeService.updateNotice(notice);
		}

		if (!StringUtils.isEmpty(notice.getGoodsList())) {
			Collection<NoticeGoods> noticeGoodsList = null;
			try {
				noticeGoodsList = mapper.readValue(notice.getGoodsList(), new TypeReference<Collection<NoticeGoods>>() {
				});
			} catch (Exception e) {
				e.printStackTrace();
				throw new IllegalStateException(message.getMessage("상품상세공지 저장 중 오류로 인해 저장되지 않았습니다."));
			}
			log.info("noticeGoodsList: {}", noticeGoodsList);
			for (NoticeGoods noticeGoods : noticeGoodsList) {
				noticeGoods.setNoticeSq(notice.getNoticeSq());
				noticeGoods.setRegNo(TssSession.getInfo().getUserNo());
				noticeGoods.setUpdNo(TssSession.getInfo().getUserNo());

				goodsDao.saveNoticeGoods(noticeGoods);
			}

		}
	}

	/**
	 * 공지사항 상품 삭제
	 * @param noticeGoods
	 * @return
	 * @author eskim
	 * @since 2020. 11. 27
	 */
	@Transactional("shopTxnManager")
	public void deleteNoticeGoods(NoticeGoods noticeGoods) {

		if (noticeGoods == null || (noticeGoods.getArrGoodsCd() == null && noticeGoods.getArrGoodsCd().length <= 0)) {
			throw new IllegalStateException(message.getMessage("FAIL_1001"));
		}

		if (noticeGoods.getArrGoodsCd().length > 0) {
			for (String goodsCd : noticeGoods.getArrGoodsCd()) {
				noticeGoods.setGoodsCd(goodsCd);
				noticeGoods.setRegNo(TssSession.getInfo().getUserNo());
				noticeGoods.setUpdNo(TssSession.getInfo().getUserNo());

				goodsDao.deleteNoticeGoods(noticeGoods);
			}
		}
	}

	/**
	 * 상품이미지 목록
	 *
	 * @param goodsImg
	 * @return Collection<GoodsImg>
	 * @author eskim
	 * @since 2020. 12. 23
	 */
	public Collection<GoodsImg> getGoodsImgList(GoodsImg goodsImg) {
		return goodsDao.getGoodsImageList(goodsImg);
	}

	/**
	 * 상품이미지 저장 처리
	 * @param goodsImgList - 상품이미지 목록
	 * @throws
	 * @author eskim
	 * @since 2020. 12. 23
	 */
	@Transactional("shopTxnManager")
	public void saveGoodsImageList(Collection<GoodsImg> goodsImgList){
		int index = 0;
		for (GoodsImg goodsImg : goodsImgList) {
			// 상품이미지 전체 삭제
			if (index++ == 0) {
				goodsDao.deleteGoodsImageTotal(goodsImg);
			}

			if (!goodsImg.getMode().equals("D")) {
				// 상품이미지 등록
				goodsImg.setRegNo(TssSession.getInfo().getUserNo());
				goodsDao.createGoodsImage(goodsImg);
			}
		}
	}

}
