package com.style24.scm.biz.web;

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.style24.core.biz.checkout.base.ChangedProductOrderInfo;
import com.style24.core.biz.checkout.base.ProductOrderChangeType;
import com.style24.core.biz.service.TscNaverPayService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.gagaframework.excel.GagaExcelUtil;
import com.gagaframework.web.parameter.GagaMap;
import com.gagaframework.web.rest.server.GagaResponse;
import com.gagaframework.web.util.GagaDateUtil;
import com.gagaframework.web.util.GagaFileUtil;
import com.style24.core.biz.service.TscOrderService;
import com.style24.core.support.env.TscConstants;
import com.style24.core.support.message.TscMessageByLocale;
import com.style24.persistence.TscPageRequest;
import com.style24.persistence.domain.Order;
import com.style24.scm.biz.service.TssOrderService;
import com.style24.scm.biz.service.TssRendererService;
import com.style24.scm.support.controller.TssBaseController;
import com.style24.scm.support.security.session.TssSession;

import lombok.extern.slf4j.Slf4j;


/**
 * 주문 Controller
 *
 * @author gagamel
 * @since 2020. 10. 19
 */
@Controller
@RequestMapping("/order")
@Slf4j
public class TssOrderController extends TssBaseController {

	@Autowired
	private TscMessageByLocale message;

	@Autowired
	private TssRendererService rendererService;
	
	@Autowired
	private TssOrderService orderService;

	@Autowired
	private TscOrderService coreOrderService;
	
	@Autowired
	private Environment env;

	@Autowired
	private TscNaverPayService coreNaverPayService;

	/**
	 * 입점업체미발주목록화면
	 *
	 * @return ModelAndView
	 * @author jsh77b
	 * @since 2020. 11. 30
	 */
	@GetMapping("/seller/unorder/list/form")
	public ModelAndView orderSellerUnorderListForm() {
		ModelAndView mav = new ModelAndView();
		
		// 공급업체
		String supplyCompCd 	= "";
		String selfYn 			= "Y";
		
		// 입점업체담당자
		if ("G001_B000".equals(TssSession.getInfo().getRoleCd())) {	
			supplyCompCd = TssSession.getInfo().getSupplyCompCd();
			selfYn = "N";
		}
		// 촬영업체
		else if ("G001_E000".equals(TssSession.getInfo().getRoleCd())) {	
			supplyCompCd = TssSession.getInfo().getSupplyCompCd();
			selfYn = "Y";
		}
		
		mav.addObject("supplyCompList"	, rendererService.getSupplyCompanyList(supplyCompCd, selfYn)); 	// 공급업제목록
		mav.addObject("ordDtlStatList"	, rendererService.getAvailCommonCodeList("G013"));				// 주문상세상태코드
		mav.addObject("shipCompanyList"	, rendererService.getShipCompanyList());						// 택배사 목록

		mav.setViewName("order/OrderSellerListForm");

		return mav;
	}
	
	/**
	 * 입점업체미발주 주문목록 조회
	 *
	 * @param order - 주문정보
	 * @return Collection<Order>
	 * @author jsh77b
	 * @since 2020. 11. 16
	 */
	@PostMapping("/seller/unorder/list")
	@ResponseBody
	public GagaMap getOrderSellerUnorderList(@RequestBody Order order) {
		GagaMap result = new GagaMap();

		order.setPageable(new TscPageRequest(0, 10000));

		// 주문전체건수 조회
		int totalCount = coreOrderService.getOrderSellerUnorderListCount(order);
		order.getPageable().setTotalCount(totalCount);

		Collection<Order> orderList = coreOrderService.getOrderSellerUnorderList(order);

		result.set("pageing"	, order);
		result.set("orderList"	, orderList);

		return result;
	}
	
	/**
	 * 입점업체미발주목록 - 엑셀다운로드시 주문상태값 변경(상품준비중)
	 *
	 * @param orderList - 미발주목록
	 * @return GagaResponse
	 * @author jsh77b
	 * @since 2020. 12. 01
	 */
	@PostMapping("/seller/unorder/status/save")
	@ResponseBody
	public GagaResponse saveUnorderStatus(@RequestBody Collection<Order> orderList) {
		int userNo = TssSession.getInfo().getUserNo();
		coreOrderService.saveUnorderStatus(orderList, userNo);
		return super.ok("");
	}
	
	/**
	 * 입점업체미발주목록 - 엑셀다운로드
	 *
	 * @param request - request
	 * @return ResponseEntity<InputStreamResource>
	 * @throws Exception - exception
	 * @author jsh77b
	 * @since 2020. 12. 01
	 */
	@GetMapping("/seller/unorder/excel/list")
	public ResponseEntity<InputStreamResource> downloadPickingGoodsExcelList(HttpServletRequest request, Order param) throws Exception {
		String excelfileName 	= "입점출고목록_" + GagaDateUtil.getTodayDateTime() + ".xlsx";
		String excelFilePath 	= GagaFileUtil.getConcatenationPath(env.getProperty("download.path"), "excel", excelfileName);
		
		param.setRegNo(TssSession.getInfo().getUserNo());
		param.setSearch("EXCEL");

		coreOrderService.geSellerUnorderExcelList(param, excelFilePath);

		return GagaFileUtil.writeFile(request, excelFilePath);
	}
	
	/**
	 * 입점 송장 엑셀 업로드
	 *
	 * @param order - 주문정보
	 * @return GagaMap
	 * @throws Exception - exception
	 * @author jsh77b
	 * @since 2020. 12. 01
	 */
	@PostMapping("/seller/unorder/invoice/excelupload/save")
	@ResponseBody
	public GagaMap saveSellerUnorderInvoiceExcelupload(@RequestBody Order order) throws Exception {

		ObjectMapper mapper = new ObjectMapper();
		
		// 1. UPLOAD 경로 조회
		String targetPath = GagaFileUtil.getConcatenationPath(env.getProperty("upload.excel.target.path"), "excel");
		
		// 2. DB 처리 시 사용되는 파라미터명(셀명) 설정
		String[] cellName = {
			  "ordNo"
			, "ordDtlNo"
			, "goodsCd"
			, "optCd2"
			, "ordQty"
			, "shipCompCd"
			, "invoiceNo"
		};
		
		Collection<GagaMap> ecxelList = GagaExcelUtil.getList(GagaFileUtil.getConcatenationPath(targetPath, order.getExcelFileNm()), 0, cellName, 0);
		
		// 3. 주문목록 매퍼 등록
		Collection<Order> orderList = new ArrayList<>();
		for (GagaMap map : ecxelList) {
			Order tmpGoods = mapper.convertValue(map, Order.class);
			orderList.add(tmpGoods);
		}
		
		// 4. 업로드된 임시 엑셀파일 삭제
		if (CollectionUtils.isEmpty(orderList)) {
			try {
				GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, order.getExcelFileNm()));
			} catch (IOException e) {
				// Nothing Do
			}
			//throw new IllegalStateException(message.getMessage("FAIL_1001"));
			throw new IllegalStateException("실패 했습니다.");
		}
		
		// 4. 주문상세번호 기준으로 송장번호 등록
		int userNo = TssSession.getInfo().getUserNo();
		String result = coreOrderService.saveUnorderInvoice(orderList, userNo);
		GagaMap map = new GagaMap();
		map.set("msg", result);

		// 5. 파일 삭제 (중복처리?)
		GagaFileUtil.deleteFile(GagaFileUtil.getConcatenationPath(targetPath, order.getExcelFileNm()));

		return map;
	}
	
	/**
	 * 입점업체미발주목록 - 송장번호 입력(자사 : 배송준비중, 입점 : 배송중)
	 *
	 * @param orderList - 송방번호 입력된 주문리스트
	 * @return GagaMap
	 * @author jsh77b
	 * @since 2020. 12. 01
	 */
	@PostMapping(value = "/seller/unorder/invoice/save")
	@ResponseBody
	public GagaMap saveUnorderInvoice(@RequestBody Collection<Order> orderList) {
		// 1. 송장번호 개별 등록
		int userNo = TssSession.getInfo().getUserNo();
		String result = coreOrderService.saveUnorderInvoice(orderList, userNo);
		GagaMap map = new GagaMap();
		map.set("msg", result);
		return map;
	}

	/**
	 * 입점업체 최종 배송 확인
	 *
	 * @return ModelAndView
	 * @author xodud1202
	 * @since 2021. 04. 20
	 */
	@GetMapping("/seller/final/delv/list/form")
	public ModelAndView sellerFinalDelvListForm() {
		ModelAndView mav = new ModelAndView();
		mav.addObject("shipCompanyList", rendererService.getShipCompanyList());						// 택배사 목록
		mav.addObject("supplyCompCd", TssSession.getInfo().getSupplyCompCd());						// 입점업체 권한
		mav.setViewName("order/OrderSellerDelvListForm");
		return mav;
	}

	/**
	 * 입점업체 배송준비중 목록 조회
	 * @param order - 주문정보
	 * @return Collection<Order>
	 * @author jsh77b
	 * @since 2020. 11. 16
	 */
	@PostMapping("/seller/final/delv/list")
	@ResponseBody
	public Collection<Order> sellerFinalDelvList(@RequestBody Order order) throws Exception {
		Collection<Order> orderList = coreOrderService.getOrderSellerUnorderList(order);
		return orderList;
	}

	/**
	 * 입점 상품 배송중 처리
	 *
	 * @param orderList - 미발주목록
	 * @return GagaResponse
	 * @author xodud1202
	 * @since 2021. ?. ?
	 */
	@PostMapping("/seller/delv/started")
	@ResponseBody
	public GagaResponse sellerDelvStarted(@RequestBody Collection<Order> orderList) {
		int userNo = TssSession.getInfo().getUserNo();
		coreOrderService.updateSellerDelvStartAndPartCancel(orderList, userNo);
		return super.ok("");
	}

	/**
	 * 입점 상품 주문 목록
	 * @param orderList - 주문목록화면
	 * @return ModelAndView
	 * @author xodud1202
	 * @since 2020. 06. 07
	 */
	@GetMapping("/seller/delv/list/form")
	public ModelAndView sellerDelvListForm() {
		ModelAndView mav = new ModelAndView();

		// 공급업체
		String supplyCompCd 	= "";
		String selfYn 			= "Y";

		// 입점업체담당자
		if ("G001_B000".equals(TssSession.getInfo().getRoleCd())) {
			supplyCompCd = TssSession.getInfo().getSupplyCompCd();
			selfYn = "N";
		}
		// 촬영업체
		else if ("G001_E000".equals(TssSession.getInfo().getRoleCd())) {
			supplyCompCd = TssSession.getInfo().getSupplyCompCd();
			selfYn = "Y";
		}

		mav.addObject("supplyCompList"	, rendererService.getSupplyCompanyList(supplyCompCd, selfYn)); 	// 공급업제목록
		mav.addObject("ordDtlStatList"	, rendererService.getAvailCommonCodeList("G013"));		// 주문상세상태코드
		mav.addObject("shipCompanyList"	, rendererService.getShipCompanyList());						// 택배사 목록

		mav.setViewName("order/OrderSellerDelvEndListForm");

		return mav;
	}

	/**
	 * 입점업체 주문 목록 조회
	 *
	 * @param order - 주문정보
	 * @return Collection<Order>
	 * @author xodud1202
	 * @since 2021. 06. 07
	 */
	@PostMapping("/seller/order/list")
	@ResponseBody
	public GagaMap getOrderSellerOrderList(@RequestBody Order order) {
		GagaMap result = new GagaMap();

		order.setPageable(new TscPageRequest(order.getPageNo() - 1, order.getPageSize()));

		// 주문전체건수 조회
		int totalCount = coreOrderService.getOrderSellerUnorderListCount(order);
		order.getPageable().setTotalCount(totalCount);

		order.setIfYn("Y");			// 취소, 반품 신청/대기 건 제외하지 않도록 구분값 지정
		Collection<Order> orderList = coreOrderService.getOrderSellerUnorderList(order);

		result.set("pageing"	, order);
		result.set("orderList"	, orderList);

		return result;
	}
	
	/**
	 * 입점입고대상목록(교환,반품접수)
	 *
	 * @return ModelAndView
	 * @author jsh77b
	 * @since 2021. 05. 17
	 */
	@GetMapping("/seller/claim/list/form")
	public ModelAndView orderSellerClaimListForm() {
		ModelAndView mav = new ModelAndView();
		
		// 공급업체
		String supplyCompCd 	= "";
		String selfYn 			= "Y";
		
		// 입점업체담당자
		if ("G001_B000".equals(TssSession.getInfo().getRoleCd())) {	
			supplyCompCd = TssSession.getInfo().getSupplyCompCd();
			selfYn = "N";
		}
		// 촬영업체
		else if ("G001_E000".equals(TssSession.getInfo().getRoleCd())) {
			supplyCompCd = TssSession.getInfo().getSupplyCompCd();
			selfYn = "Y";
		}
		
		mav.addObject("supplyCompList"	, rendererService.getSupplyCompanyList(supplyCompCd, selfYn)); 	// 공급업제목록
		mav.addObject(" chgStatList"	, rendererService.getAvailCommonCodeList("G685"));				// 클렘임상태코드
		mav.setViewName("order/OrderSellerClaimListForm");

		return mav;
	}
	
	/**
	 * 입점클레임목록조회(교환,반품접수)
	 *
	 * @param order - 주문정보
	 * @return Collection<Order>
	 * @author jsh77b
	 * @since 2021. 05. 17
	 */
	@PostMapping("/seller/claim/list")
	@ResponseBody
	public GagaMap getOrderSellerClaimList(@RequestBody Order order) throws Exception {
		
		GagaMap result = new GagaMap();
		
		order.setPageable(new TscPageRequest(order.getPageNo() - 1, order.getPageSize()));
		
		// 주문전체건수 조회
		int totalCount = (int) coreOrderService.getOrderSellerClaimCount(order);
		order.getPageable().setTotalCount(totalCount);
		
		Collection<Order> orderSellerClaimList = coreOrderService.getOrderSellerClaimList(order);
		
		result.set("pageing"				, order);
		result.set("orderSellerClaimList"	, orderSellerClaimList);
				
		return result;
	}
	
	/**
	 * 입점입고대상목록(교환,반품접수)
	 *
	 * @return ModelAndView
	 * @author jsh77b
	 * @since 2021. 05. 17
	 */
	@GetMapping("/seller/claim/target/list/form")
	public ModelAndView orderSellerClaimTargetListForm() {
		ModelAndView mav = new ModelAndView();
		
		// 공급업체
		String supplyCompCd 	= "";
		String selfYn 			= "Y";
		
		// 입점업체담당자
		if ("G001_B000".equals(TssSession.getInfo().getRoleCd())) {	
			supplyCompCd = TssSession.getInfo().getSupplyCompCd();
			selfYn = "N";
		}
		// 촬영업체
		else if ("G001_E000".equals(TssSession.getInfo().getRoleCd())) {
			supplyCompCd = TssSession.getInfo().getSupplyCompCd();
			selfYn = "Y";
		}
		
		mav.addObject("supplyCompList"	, rendererService.getSupplyCompanyList(supplyCompCd, selfYn)); 	// 공급업제목록
		mav.addObject(" chgStatList"	, rendererService.getAvailCommonCodeList("G685"));				// 클렘임상태코드
		mav.setViewName("order/OrderSellerClaimTargetListForm");

		return mav;
	}
	
	/**
	 * 입점클레임목록조회(교환,반품접수)
	 *
	 * @param order - 주문정보
	 * @return Collection<Order>
	 * @author jsh77b
	 * @since 2021. 05. 17
	 */
	@PostMapping("/seller/claim/target/list")
	@ResponseBody
	public Collection<Order> getOrderSellerClaimTargetList(@RequestBody Order order) throws Exception {
		
		// 값이없으면 반품접수, 교환접수
		String [] multiChgStat = new String[3];
		if (order.getChgStat() == null || "".equals(order.getChgStat())) {
			multiChgStat[0] = TscConstants.OrderChangeStat.EXCHANGE.value();
			multiChgStat[1] = TscConstants.OrderChangeStat.RETURN.value();
			multiChgStat[2] = TscConstants.OrderChangeStat.WITHDRAW.value();
		} else {
			multiChgStat[0] = order.getChgStat();
		}
		
		// 페이징쿼리때문에
		order.setMultiChgStat(multiChgStat);
		order.setPageable(new TscPageRequest(1 - 1, 1000));
		
		Collection<Order> OrderSellerClaimList = coreOrderService.getOrderSellerClaimList(order);
		return OrderSellerClaimList;
	}
	
	/**
	 * 입점클레임목록 - 입고확인
	 *
	 * @param orderList
	 * @return GagaMap
	 * @author jsh77b
	 * @since 2021. 05. 17
	 */
	@PostMapping(value = "/seller/claim/chgStat31/save")
	@ResponseBody
	public GagaMap saveClaimChgStat31(@RequestBody Collection<Order> orderList) {
		
		// 1. 입고확인
		int userNo = TssSession.getInfo().getUserNo();
		String result = coreOrderService.saveClaimChgStat31(orderList, userNo);
		GagaMap map = new GagaMap();
		map.set("msg", result);
		return map;
	}
	
	/**
	 * 입점상품검수중목록(상품검수중)
	 *
	 * @return ModelAndView
	 * @author jsh77b
	 * @since 2021. 05. 17
	 */
	@GetMapping("/seller/withdraw/list/form")
	public ModelAndView orderSellerWidthdrawListForm() {
		ModelAndView mav = new ModelAndView();
		
		// 공급업체
		String supplyCompCd 	= "";
		String selfYn 			= "Y";
		
		// 입점업체담당자
		if ("G001_B000".equals(TssSession.getInfo().getRoleCd())) {	
			supplyCompCd = TssSession.getInfo().getSupplyCompCd();
			selfYn = "N";
		}
		// 촬영업체
		else if ("G001_E000".equals(TssSession.getInfo().getRoleCd())) {	
			supplyCompCd = TssSession.getInfo().getSupplyCompCd();
			selfYn = "Y";
		}
		
		mav.addObject("supplyCompList"	, rendererService.getSupplyCompanyList(supplyCompCd, selfYn)); 	// 공급업제목록
		mav.addObject("chgStatList"		, rendererService.getAvailCommonCodeList("G685"));					// 클렘임상태코드
		mav.setViewName("order/OrderSellerWithdrawListForm");

		return mav;
	}
	
	/**
	 * 입점상품검수중목록조회(상품검수중)
	 *
	 * @param order - 주문정보
	 * @return Collection<Order>
	 * @author jsh77b
	 * @since 2021. 05. 17
	 */
	@PostMapping("/seller/withdraw/list")
	@ResponseBody
	public Collection<Order> getOrderSellerWithdrawList(@RequestBody Order order) throws Exception {
		
		// 값이없으면 반품접수, 교환접수
		String [] multiChgStat = new String[1];
		multiChgStat[0] = TscConstants.OrderChangeStat.WITHDRAW_GOODS_CHECK.value();
		
		order.setMultiChgStat(multiChgStat);
		
		// 페이징쿼리때문에
		order.setMultiChgStat(multiChgStat);
		order.setPageable(new TscPageRequest(1 - 1, 1000));
				
		Collection<Order> OrderSellerClaimList = coreOrderService.getOrderSellerClaimList(order);
		return OrderSellerClaimList;
	}

	@GetMapping("/naverpay/recv/order/complete")
	public ModelAndView naverpayRecvOrderComplete(HttpServletRequest request, HttpServletResponse response) {
		try {
			log.info("<<<< 결제완료 수신 시작 >>>>");

			PrintWriter out = response.getWriter();
			Order time = coreNaverPayService.setInitData();
			ChangedProductOrderInfo[] changedProductOrderList = coreNaverPayService.changedProductOrderList(ProductOrderChangeType.PAYED, time.getFrom(), time.getTo(), TssSession.getInfo().getUserNo()); // 변경 상품주문 조회;

			if(changedProductOrderList != null) {
				log.info("<<<< 수신건수: [{}]건 >>>>", changedProductOrderList.length);
				Order result = coreNaverPayService.createOrderInfo(changedProductOrderList, TssSession.getInfo().getUserNo());
			}

			log.info("<<<< 결제완료 수신 종료 >>>>");

			out.print("<html><body><form><h1>ORDER COMPLETE SUCCESS</h1></body></html>");
			out.flush();
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}

	@GetMapping("/naverpay/send/ready/delivery")
	public ModelAndView naverpaySendReadyDelivery(HttpServletRequest request, HttpServletResponse response) {
		try {
			log.info("<<<< 결제완료 수신 시작 >>>>");

			PrintWriter out = response.getWriter();
			log.info("<<<< 배송준비중 송신 시작 >>>>");
			Order time = coreNaverPayService.setInitData();
			Collection<Order> readyDeliveryList = coreNaverPayService.getReadyDeliveryList(time); // 네이버페이 주문형 배송준비중 테스트

			if (readyDeliveryList != null) {
				// 배송 준비중 데이터 네이버로 송신
				Order result = coreNaverPayService.sendNaverPayReadyDeliveryOrder(readyDeliveryList, TssSession.getInfo().getUserNo());
			}

			log.info("<<<< 배송준비중 송신 종료 >>>>");

			out.print("<html><body><form><h1>DELIVERY READY SUCCESS</h1></body></html>");
			out.flush();
			out.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}
}
