package com.style24.front.biz.web;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import com.style24.core.biz.service.TscMailService;
import com.style24.front.biz.service.TsfCommonService;
import com.style24.persistence.TscPageRequest;
import com.style24.persistence.domain.Clause;
import com.style24.persistence.domain.Login;
import com.style24.persistence.domain.SupplyCompany;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.style24.core.biz.service.TscClauseService;
import com.style24.core.support.env.TscConstants;
import com.style24.core.support.message.TscMessageByLocale;
import com.style24.front.biz.service.TsfCustomerService;
import com.style24.front.biz.thirdparty.NiceCertify;
import com.style24.front.biz.thirdparty.Yes24Login;
import com.style24.front.support.controller.TsfBaseController;
import com.style24.front.support.security.session.TsfSession;
import com.style24.persistence.domain.CustSnsInfo;
import com.style24.persistence.domain.Customer;

import lombok.extern.slf4j.Slf4j;

import com.gagaframework.web.parameter.GagaMap;
import com.gagaframework.web.rest.server.GagaResponse;

/**
 * 고객(회원) Controller
 * 
 * @author gagamel
 * @since 2020. 12. 28
 */
@Controller
@RequestMapping("/customer")
@Slf4j
public class TsfCustomerController extends TsfBaseController {

	@Autowired
	private TscMessageByLocale message;

	@Autowired
	private TsfCustomerService customerService;

	@Autowired
	private TscClauseService clauseService;

	@Autowired
	private TscMailService mailService;

	@Autowired
	private NiceCertify niceCertify;

	@Autowired
	private Yes24Login yes24Login;

	@Autowired
	private TsfCommonService commonService;

	/**
	 * 아이디 비밀번호 찾기 화면
	 *
	 * @return ModelAndView
	 * @author jsshin
	 * @since 2021. 07. 19
	 */
	@RequestMapping("/id/pwd/find/form")
	public ModelAndView idPwdFindForm(@RequestParam(value = "sEncData", required = false) String sEncData
			, @RequestParam(value = "authMethod", required = false) String authMethod
			, @RequestParam(value = "custParams", required = false) String custParams
			, @RequestParam(value = "pageGb") String pageGb) {

		ModelAndView mav = new ModelAndView();
		String tmpPageGb = StringUtils.isNotBlank(custParams) ? custParams : pageGb;
		mav.addObject("sEncData", sEncData);
		mav.addObject("authMethod", authMethod);
		mav.addObject("custParams", custParams);
		mav.addObject("pageGb", tmpPageGb);

		mav.setViewName(super.getDeviceViewName("customer/IdAndPwdFindForm"));
		return mav;
	}

	/**
	 * 아이디 찾기 - 고객정보
	 *
	 * @return ModelAndView
	 * @author jsshin
	 * @since 2021. 02. 08
	 */
	@PostMapping("/id/find")
	@ResponseBody
	public GagaMap getIdFindCustInfo(@RequestBody Customer customer) {
		GagaMap result = new GagaMap();
		boolean isFind = false;

		if (StringUtils.isBlank(customer.getAuthMethod())) {
			throw new IllegalStateException(message.getMessage("CUST_0005"));
		}

		Customer params = new Customer();
		// 인증방법
		GagaMap authInfo;
		if (TscConstants.AuthMethod.CUSTINFO.value().equals(customer.getAuthMethod())) {
			// 기본정보
			params.setCustNm(customer.getCustNm());
			params.setEmail(customer.getEmail());
			params.setBirthYmd(customer.getBirthYmd());
		} else if (TscConstants.AuthMethod.MOBILE.value().equals(customer.getAuthMethod())) {
			// 핸드폰 인증
			authInfo = niceCertify.getCertifyCellPhoneResultInfo(customer);
			params.setCi(authInfo.getString("sCi"));
		} else if (TscConstants.AuthMethod.IPIN.value().equals(customer.getAuthMethod())) {
			// 아이핀
			authInfo = niceCertify.getCertifyIpinResultInfo(customer);
			params.setCi(authInfo.getString("sConnInfo"));
		}

		// 고객정보 찾기
		Customer custInfo = customerService.getCustomerFindId(params);
		if (custInfo != null) {
			isFind = true;
			result.setString("maskingCustId", custInfo.getMaskingCustId());
			result.setString("joinDt", custInfo.getJoinDt());
			result.setString("ysJoinDt", custInfo.getYsJoinDt());
			result.setString("nvJoinDt", custInfo.getNvJoinDt());
			result.setString("kkJoinDt", custInfo.getKkJoinDt());
		}
		result.setString("authMethod", customer.getAuthMethod()); // 인증방법
		result.setBoolean("isFind", isFind);
		return result;
	}

	/**
	 * 비밀번호 찾기 - 고객정보 찾기
	 * @param customer - 고객정보
	 * @return GagaMap
	 * @author jsshin
	 * @since 2021. 02. 15
	 */
	@PostMapping("/password/find/custinfo")
	@ResponseBody
	public GagaMap getPwdFind(@RequestBody Customer customer) {
		GagaMap result = new GagaMap();
		boolean isFind = false;

		if (StringUtils.isBlank(customer.getAuthMethod())) {
			throw new IllegalStateException(message.getMessage("CUST_0005"));
		}

		// 고객정보 찾기 - 아이디, 이름, 이메일
		Customer custInfo = customerService.getCustomerFindId(customer);

		if (custInfo != null) {
			isFind = true;
			result.setString("maskingEmail", custInfo.getMaskingEmail());
		}

		if (isFind) {
			String tempPasswd = customerService.getTemporaryPassword(10);
			log.info("tempPasswd  ====> {}", tempPasswd);
			customer.setTempPasswdYn("Y"); // 임시비밀번호여부
			customer.setPasswd(tempPasswd);
			customer.setRegNo(custInfo.getCustNo());
			customer.setUpdNo(custInfo.getCustNo());
			customer.setCustNo(custInfo.getCustNo());
			customer.setCellPhnno(custInfo.getCellPhnno());
			// 비밀번호 수정
			customerService.saveCustomerPassword(customer);

			if (StringUtils.isNotBlank(customer.getEmail())) {
				try {
					mailService.sendCustomerTempPassword(customer, customer.getCustNo());
				} catch (Exception e) {
					log.error(e.getMessage());
				}

			}
		}

		result.setString("authMethod", customer.getAuthMethod()); // 인증방법
		result.setBoolean("isFind", isFind);
		return result;
	}

	/**
	 * 비밀번호 찾기 - 인증(휴대폰,아이핀)
	 * @param customer - 고객정보
	 * @return GagaMap
	 * @author jsshin
	 * @since 2021. 02. 15
	 */
	@PostMapping("/password/find/certify")
	@ResponseBody
	public GagaMap getPwdFindCertify(@RequestBody Customer customer) {
		GagaMap result = new GagaMap();
		boolean isFind = false;

		if (StringUtils.isBlank(customer.getAuthMethod())) {
			throw new IllegalStateException(message.getMessage("CUST_0005"));
		}

		Customer params = new Customer();
		// 인증방법
		GagaMap authInfo;
		if (TscConstants.AuthMethod.MOBILE.value().equals(customer.getAuthMethod())) {
			// 핸드폰 인증
			authInfo = niceCertify.getCertifyCellPhoneResultInfo(customer);
			params.setCi(authInfo.getString("sCi"));
		} else if (TscConstants.AuthMethod.IPIN.value().equals(customer.getAuthMethod())) {
			// 아이핀
			authInfo = niceCertify.getCertifyIpinResultInfo(customer);
			params.setCi(authInfo.getString("sConnInfo"));
		}

		// 고객정보 찾기
		Customer custInfo = customerService.getCustomerFindId(params);
		if (custInfo != null) {
			isFind = true;
			TsfSession.setAttribute("custNo", String.valueOf(custInfo.getCustNo()));
		}

		result.setString("authMethod", customer.getAuthMethod()); // 인증방법
		result.setBoolean("isFind", isFind);
		return result;
	}

	/**
	 * 비밀번호 변경 화면
	 *
	 * @return ModelAndView
	 * @author jsshin
	 * @since 2021. 02. 17
	 */
	@GetMapping("/password/change/form")
	public ModelAndView passwrodChangeForm(@RequestParam(value = "pageGb") String pageGb) {
		ModelAndView mav = new ModelAndView();
		String custNo = "";

		if ("find".equals(pageGb)) { //비밀번호 찾기 사용
			custNo = TsfSession.getAttribute("custNo");
		}

		if ("temp".equals(pageGb)) { // 비밀번호 변경 캠페인, 임시비밀번호로 로그인시 사용, 마이페이지 내정보 관리-비밀번호 수정
			custNo = String.valueOf(TsfSession.getInfo().getCustNo());
		}

		// 고객번호 없으면 인증화면으로 돌아감
		if (StringUtils.isBlank(custNo)) {
			String redirect = "redirect:/customer/password/find/form";
			mav.setViewName(redirect);
			return mav;
		}

		// 고객정보 찾기
		Customer custInfo = customerService.getCustomerFindByCustNo(Integer.valueOf(custNo));

		if (custInfo != null) {
			mav.addObject("custId", custInfo.getCustId());
		}
		mav.addObject("pageGb", pageGb);
		mav.setViewName(super.getDeviceViewName("customer/PasswordChangeForm"));
		return mav;
	}

	/**
	 * 비밀번호 변경
	 *
	 * @param customer - 비밀번호 정보
	 * @return ModelAndView
	 * @author jsshin
	 * @since 2021. 02. 16
	 */
	@PostMapping("/password/reset")
	@ResponseBody
	public GagaMap resetPassword(@RequestBody Customer customer) {
		GagaMap result = new GagaMap();
		boolean isSuccess = false;
		String custNo = "";
		if (TsfSession.isLogin()) {
			custNo = String.valueOf(TsfSession.getInfo().getCustNo());
		} else {
			custNo = TsfSession.getAttribute("custNo");
		}

		if (StringUtils.isBlank(custNo)) {
			throw new IllegalStateException("고객 정보가 없습니다. 다시 확인 해주세요.");
		}

		// 고객정보 찾기
		Customer custInfo = customerService.getCustomerFindByCustNo(Integer.valueOf(custNo));

		if (custInfo != null) {
			customer.setTempPasswdYn("N"); // 임시비밀번호여부
			customer.setRegNo(custInfo.getCustNo());
			customer.setUpdNo(custInfo.getCustNo());
			customer.setCustNo(custInfo.getCustNo());
			// 비밀번호 수정
			customerService.saveCustomerPassword(customer);
			isSuccess = true;
		}

		result.setBoolean("isSuccess", isSuccess);
		return result;
	}

	/**
	 * 회원가입 유형 화면
	 *
	 * @return ModelAndView
	 * @author jsshin
	 * @since 2021. 03. 02
	 */
	@GetMapping("/join/type/form")
	public ModelAndView getJoinTypeForm() {
		ModelAndView mav = new ModelAndView();

		mav.setViewName(super.getDeviceViewName("customer/JoinTypeForm"));

		return mav;
	}

	/**
	 * 회원정보 입력 화면
	 *
	 * @return ModelAndView
	 * @author jsshin
	 * @since 2021. 02. 05
	 */
	@RequestMapping("/join/form")
	public ModelAndView getJoinForm(@RequestParam(value = "sEncData", required = false) String sEncData
			, @RequestParam(value = "authMethod", required = false) String authMethod
			, @RequestParam(value = "custParams", required = false) String custParams) {

		ModelAndView mav = new ModelAndView();

		mav.addObject("sEncData", sEncData);
		mav.addObject("authMethod", authMethod);
		mav.addObject("custParams", custParams);

		mav.setViewName(super.getDeviceViewName("customer/JoinForm"));

		return mav;
	}

	/**
	 * SNS 가입 시도시 휴대폰 정보 없을시 호출
	 *
	 * @return ModelAndView
	 * @author jsshin
	 * @since 2021. 06. 08
	 */
	@RequestMapping("/sns/join/form")
	public ModelAndView getSnsJoinForm(@RequestParam(value = "sEncData", required = false) String sEncData
			, @RequestParam(value = "authMethod", required = false) String authMethod
			, @RequestParam(value = "custParams", required = false) String custParams, HttpSession session) {
		ModelAndView mav = new ModelAndView();
		CustSnsInfo custSnsInfo = (CustSnsInfo)session.getAttribute("custSnsInfo");
		session.removeAttribute("custSnsInfo"); //세션 지움
		if (StringUtils.isBlank(custParams)) {
			if (custSnsInfo == null) {
				mav.setViewName("redirect:/customer/join/type/form");
				return mav;
			}
		}

		mav.addObject("sEncData", sEncData);
		mav.addObject("authMethod", authMethod);
		mav.addObject("custParams", custParams);
		mav.addObject("custSnsInfo", custSnsInfo);

		mav.setViewName(super.getDeviceViewName("customer/SnsJoinForm"));

		return mav;
	}

	/**
	 * 휴대폰 인증 화면
	 * @param redirectUrl - 모바일사용
	 * @param custParams - 회원정보 수정시 사용
	 * @return ModelAndView
	 * @author jsshin
	 * @since 2021. 02. 09
	 */
	@GetMapping("/nice/cellphone/form")
	public ModelAndView niceCellphoneForm(@RequestParam(value = "redirectUrl", required = false) String redirectUrl, @RequestParam(value = "custParams", required = false) String custParams) {
		ModelAndView mav = new ModelAndView();
		GagaMap result = niceCertify.certifyCellPhone();

		if (!TscConstants.FrontGb.PC.value().equals(TsfSession.getFrontGb())) {
			mav.addObject("redirectUrl", redirectUrl); // 모바일만 사용
			mav.addObject("custParams", custParams); // 모바일만 사용
		}

		mav.addObject("sEncData", result.getString("sEncData"));
		mav.setViewName(super.getDeviceViewName("customer/NiceCellPhoneForm"));

		return mav;
	}

	/**
	 * 아이핀 인증 화면
	 * @param redirectUrl - 모바일사용
	 * @return ModelAndView
	 * @author jsshin
	 * @since 2021. 02. 09
	 */
	@GetMapping("/nice/ipin/form")
	public ModelAndView getCertifyNiceIpin(@RequestParam(value = "redirectUrl", required = false) String redirectUrl, @RequestParam(value = "custParams", required = false) String custParams) {
		ModelAndView mav = new ModelAndView();
		GagaMap result = niceCertify.certifyIpin();

		if (!TscConstants.FrontGb.PC.value().equals(TsfSession.getFrontGb())) {
			mav.addObject("redirectUrl", redirectUrl); // 모바일만 사용
			mav.addObject("custParams", custParams); // 모바일만 사용
		}

		mav.addObject("sEncData", result.getString("sEncData"));
		mav.setViewName(super.getDeviceViewName("customer/NiceIpinForm"));
		return mav;
	}

	/**
	 * 나이스 인증 콜백
	 * @param encodeData - 휴대폰인증에서 전달받은 인증결과 암호화 데이터 취득
	 * @param encData - 아이핀에서 전달받은 인증결과 암호화 데이터 취득
	 * @param redirectUrl - 모바일은 호출한 URL 암호화 데이터 전달
	 * @param custParams - 회원가입시 입력 받았던 내용 다시 받음
	 * @return ModelAndView
	 * @author jsshin
	 * @since 2021. 02. 09
	 */
	@RequestMapping("/nice/certify/callback")
	public ModelAndView niceCertifyCallback(@RequestParam(value = "EncodeData", required = false) String encodeData
			, @RequestParam(value = "enc_data", required = false) String encData
			, @RequestParam(value = "param_r1", required = false) String redirectUrl
			, @RequestParam(value = "param_r2", required = false) String custParams) {

		ModelAndView mav = new ModelAndView();
		String sEncData = "";
		String authMethod = "";
		if (StringUtils.isNotBlank(encodeData)) {
			sEncData = encodeData;
			authMethod = TscConstants.AuthMethod.MOBILE.value();
		}
		if (StringUtils.isNotBlank(encData)) {
			sEncData = encData;
			authMethod = TscConstants.AuthMethod.IPIN.value();
		}

		if (!TscConstants.FrontGb.PC.value().equals(TsfSession.getFrontGb())) {
			mav.addObject("redirectUrl", redirectUrl);
			mav.addObject("custParams", custParams);
		}

		mav.addObject("sEncData", sEncData);
		mav.addObject("authMethod", authMethod);
		mav.setViewName(super.getDeviceViewName("customer/NiceCallbackForm"));
		return mav;
	}

	/**
	 * 가입화면 - 아이디 확인
	 *
	 * @param customer - email
	 * @return GagaMap - 결과정보
	 * @author jsshin
	 * @since 2021. 02. 18
	 */
	@PostMapping("/join/id/check")
	@ResponseBody
	public GagaMap getJoinIdCheck(@RequestBody Customer customer) {
		GagaMap result = new GagaMap();

		if (StringUtils.isBlank(customer.getCustId())) {
			throw new IllegalStateException("확인 할 아이디가 없습니다.");
		}

		boolean isFind = customerService.getCustomerFindByCustIdCount(customer.getCustId());

		result.setBoolean("isFind", isFind);
		return result;
	}

	/**
	 * 가입화면 - 이메일 확인
	 *
	 * @param customer - email
	 * @return GagaMap - 결과정보
	 * @author jsshin
	 * @since 2021. 02. 18
	 */
	@PostMapping("/email/check")
	@ResponseBody
	public GagaMap getEmailCheck(@RequestBody Customer customer) {
		GagaMap result = new GagaMap();

		if (StringUtils.isBlank(customer.getEmail())) {
			throw new IllegalStateException("확인 할 이메일이 없습니다.");
		}

		boolean isFind = customerService.getCustomerFindByEmailCount(customer.getEmail());

		result.setBoolean("isFind", isFind);

		return result;
	}

	/**
	 * 가입화면 - 휴대폰 확인(임시)
	 *
	 * @param customer - cellphnno
	 * @return GagaMap - 결과정보
	 * @author jsshin
	 * @since 2021. 02. 18
	 */
	@PostMapping("/cellphnno/check")
	@ResponseBody
	public GagaMap getCellphnnoCheck(@RequestBody Customer customer) {
		GagaMap result = new GagaMap();

		if (StringUtils.isBlank(customer.getCellPhnno())) {
			throw new IllegalStateException("확인 할 휴대폰번호가 없습니다.");
		}

		Customer custInfo = customerService.getCustomerFindByCellPhnno(customer.getCellPhnno());

		if (custInfo != null) {
			result.setString("maskingCustId", custInfo.getMaskingCustId());
			result.setBoolean("isFind", true);
		} else {
			result.setBoolean("isFind", false);
		}

		return result;
	}

	/**
	 * 가입화면 - 나이스 휴대폰인증
	 *
	 * @param customer - 인증정보
	 * @return GagaMap - 결과정보
	 * @author jsshin
	 * @since 2021. 02. 18
	 */
	@PostMapping("/authentication/check")
	@ResponseBody
	public GagaMap getAuthenticationCheck(@RequestBody Customer customer) {
		GagaMap result = new GagaMap();

		GagaMap authInfo = niceCertify.getCertifyCellPhoneResultInfo(customer);
		if (StringUtils.isNotBlank(customer.getCi())) {
			//log.info("ci ====> {}, sCi ======> {}", customer.getCi(), authInfo.getString("sCi"));
			if (!customer.getCi().equals(authInfo.getString("sCi"))) {
				throw new IllegalStateException("SNS 연계정보와 본인인증 연계정보가 다릅니다.");
			}
		}
		customer.setCi(authInfo.getString("sCi"));
		customer.setCellPhnno(authInfo.getString("sMobileNo"));

		if ("N".equals(authInfo.getString("adult"))) {
			throw new IllegalStateException("만14세 이상만 회원가입이 가능합니다.");
		}

		Customer custInfo;
		custInfo = customerService.getCustomerFindByCi(customer.getCi());	// CI 중복체크
		if (custInfo != null) {
			result.setString("maskingCustId", custInfo.getMaskingCustId());
			result.setString("custStat", custInfo.getCustStat());
			result.setString("cellPhnno", customer.getCellPhnno());
			result.setBoolean("isFind", true);
			return result;
		}

		custInfo = customerService.getCustomerFindByCellPhnno(customer.getCellPhnno());	// 휴대전화 중복체크
		if (custInfo != null) {
			result.setString("maskingCustId", custInfo.getMaskingCustId());
			result.setString("custStat", custInfo.getCustStat());
			result.setString("cellPhnno", customer.getCellPhnno());
			result.setBoolean("isFind", true);
			return result;
		}

		result.setBoolean("isFind", false);
		result.setString("cellPhnno", customer.getCellPhnno());

		TsfSession.setAttribute("encData", customer.getEncData());

		return result;
	}

	/**
	 * 일반 가입처리
	 *
	 * @param customer - 고객정보
	 * @param request - 자동로그인
	 * @param session - 세션 저장된 내용삭제
	 * @return GagaMap - 결과정보
	 * @author jsshin
	 * @since 2021. 02. 18
	 */
	@PostMapping("/join/save")
	@ResponseBody
	public GagaMap saveJoinCustomer(@RequestBody Customer customer, HttpServletRequest request, HttpSession session) {
		GagaMap result = new GagaMap();

		// 1.세션에 인코딩된 데이터를 가져온다.
		String encData = TsfSession.getAttribute("encData");
		customer.setEncData(encData);
		session.removeAttribute("encData");

		GagaMap authInfo = niceCertify.getCertifyCellPhoneResultInfo(customer);

		// 2.인증통해 받은 데이터 매핑
		customer.setSexGb(authInfo.getString("sGender"));
		customer.setCustNm(authInfo.getString("sName"));
		customer.setBirthYmd(authInfo.getString("sBirthDate"));
		customer.setForeignerYn(authInfo.getString("sforeignerYn"));
		customer.setCi(authInfo.getString("sCi"));

		customer.setSiteCd(TscConstants.Site.STYLE24.value());
		customer.setFrontGb(TsfSession.getFrontGb());
		customer.setAfLinkCd(TsfSession.getAttribute("afLinkCd"));

		// 3. 가입 가능여부
		GagaMap resultMap = customerService.generalCustomerValidation(customer);
		boolean isPossible = resultMap.getBoolean("isPossibe");

		// 가능하지 않으면 바로 리턴
		if (!isPossible) {
			TsfSession.setAttribute("maskingCustId", resultMap.getString("maskingCustId"));
			result.setBoolean("isJoin", false);
			return resultMap;
		}

		// 4.고객정보 생성 및 혜택 처리
		boolean isJoin = customerService.saveJoinCustomer(customer);

		if (isJoin) {
			customerService.getLogin(customer.getCustNo(), request);
			TsfSession.setAttribute("custNo", String.valueOf(customer.getCustNo()));
		}

		result.setBoolean("isJoin", isJoin);

		return result;
	}

	/**
	 * SNS 회원 가입처리
	 * 고객 소셜 로그인 후 휴대전화정보가 없을때 해당 로직 사용됨
	 *
	 * @param customer - 고객정보
	 * @param request - 자동로그인
	 * @param session - 세션 저장된 내용삭제
	 * @return GagaMap - 결과정보
	 * @author jsshin
	 * @since 2021. 02. 18
	 */
	@PostMapping("/sns/join/save")
	@ResponseBody
	public GagaMap saveSnsJoinCustomer(@RequestBody Customer customer, HttpServletRequest request, HttpSession session) {
		GagaMap result = new GagaMap();

		// 1.세션에 인코딩된 데이터를 가져온다.
		String encData = TsfSession.getAttribute("encData");
		customer.setEncData(encData);
		session.removeAttribute("encData");

		GagaMap authInfo = niceCertify.getCertifyCellPhoneResultInfo(customer);

		// 2.인증통해 받은 데이터 매핑
		customer.setSexGb(authInfo.getString("sGender"));
		customer.setCustNm(authInfo.getString("sName"));
		customer.setBirthYmd(authInfo.getString("sBirthDate"));
		customer.setForeignerYn(authInfo.getString("sforeignerYn"));
		customer.setCi(authInfo.getString("sCi"));

		customer.setSiteCd(TscConstants.Site.STYLE24.value());
		customer.setFrontGb(TsfSession.getFrontGb());
		customer.setAfLinkCd(TsfSession.getAttribute("afLinkCd"));

		// 3. 가입 가능여부
		GagaMap resultMap = customerService.generalCustomerValidation(customer);
		boolean isPossible = resultMap.getBoolean("isPossibe");

		// 가능하지 않으면 바로 리턴
		if (!isPossible) {
			TsfSession.setAttribute("maskingCustId", resultMap.getString("maskingCustId"));
			result.setBoolean("isJoin", false);
			return resultMap;
		}

		// 4.고객정보 생성, SNS 정보 생성 및 혜택 처리
		boolean isJoin = customerService.saveJoinCustomerSns(customer);

		if (isJoin) {
			customerService.getLogin(customer.getCustNo(), request);
			TsfSession.setAttribute("custNo", String.valueOf(customer.getCustNo()));
		}

		result.setBoolean("isJoin", isJoin);

		return result;
	}

	/**
	 * 가입완료 페이지
	 *
	 * @return ModelAndView - 가입완료 화면
	 * @author jsshin
	 * @since 2021. 02. 18
	 */
	@GetMapping("/join/complete/form")
	public ModelAndView getJoinCompleteForm() {
		ModelAndView mav = new ModelAndView();
		String maskingCustId = TsfSession.getAttribute("maskingCustId");
		String custNo = TsfSession.getAttribute("custNo");
		//log.info("custNo  ===> {}", custNo);
		mav.addObject("maskingCustId", maskingCustId);
		mav.addObject("custNo", custNo);
		mav.setViewName(super.getDeviceViewName("customer/JoinCompleteForm"));

		return mav;
	}

	/**
	 * 휴면해제 인증화면
	 *
	 * @param sEncData  - 본인인증 후 받는 암호화데이터
	 * @param authMethod - 인증방법(휴대폰, 아이핀)
	 * @param custParams  - 아이핀 인증 후 필요한 값 받는 변수
	 * @return ModelAndView - 가입완료 화면
	 * @author jsshin
	 * @since 2021. 03. 08
	 */
	@RequestMapping("/dormant/certify/form")
	public ModelAndView getDormantCeirtyForm(@RequestParam(value = "sEncData", required = false) String sEncData
			, @RequestParam(value = "authMethod", required = false) String authMethod
			, @RequestParam(value = "custParams", required = false) String custParams) {
		ModelAndView mav = new ModelAndView();

		// http 에서는 Same-Site None 설정이 안되므로 아래와 같이 처리
		if (StringUtils.isNotBlank(custParams)) {
			TsfSession.setAttribute("custNo", custParams);
		}

		if (!TscConstants.FrontGb.PC.value().equals(TsfSession.getFrontGb())) {
			mav.addObject("custNo", TsfSession.getAttribute("custNo"));
		}

		mav.addObject("sEncData", sEncData);
		mav.addObject("authMethod", authMethod);

		mav.setViewName(super.getDeviceViewName("customer/DormantCertifyForm"));

		return mav;
	}

	/**
	 * 휴면해제
	 *
	 * @return GagaMap - 결과
	 * @author jsshin
	 * @since 2021. 03. 08
	 */
	@PostMapping("/dormant/release")
	@ResponseBody
	public GagaMap releaseDormantCustomer(@RequestBody Customer customer, HttpSession session) {
		String custNo = TsfSession.getAttribute("custNo");
		if (StringUtils.isBlank(custNo) || StringUtils.isBlank(customer.getEncData())) {
			throw new IllegalStateException("로그인 다시 시도해주세요.");
		}

		GagaMap resultInfo;
		if (TscConstants.AuthMethod.MOBILE.value().equals(customer.getAuthMethod())) {
			resultInfo = niceCertify.getCertifyCellPhoneResultInfo(customer);
			customer.setCi(resultInfo.getString("sCi"));
		} else {
			resultInfo = niceCertify.getCertifyIpinResultInfo(customer);
			customer.setCi(resultInfo.getString("sConnInfo"));
		}

		customer.setCustNo(Integer.parseInt(custNo));
		session.removeAttribute("custNo"); // 고객번호 세션 삭제
		return customerService.releaseDormantCustomer(customer);
	}

	/**
	 * 휴면해제 완료화면
	 *
	 * @return ModelAndView - 휴면해제 완료화면
	 * @author jsshin
	 * @since 2021. 03. 08
	 */
	@GetMapping("/dormant/certify/complete/form")
	public ModelAndView getDormantCeirtyCompleteForm() {
		ModelAndView mav = new ModelAndView();

		mav.setViewName(super.getDeviceViewName("customer/DormantCertifyCompleteForm"));

		return mav;
	}

	/**
	 * 본인인증 화면
	 *
	 * @return ModelAndView - 가입완료 화면
	 * @author jsshin
	 * @since 2021. 03. 10
	 */
	@RequestMapping("/certification/form")
	public ModelAndView getCertificationForm(@RequestParam(value = "sEncData", required = false) String sEncData
			, @RequestParam(value = "authMethod", required = false) String authMethod
			, @RequestParam(value = "custParams", required = false) String custParams) {
		ModelAndView mav = new ModelAndView();

		// http 에서는 Same-Site None 설정이 안되므로 아래와 같이 처리
		if (StringUtils.isNotBlank(custParams)) {
			TsfSession.setAttribute("custNo", custParams);
		}

		if (!TscConstants.FrontGb.PC.value().equals(TsfSession.getFrontGb())) {
			mav.addObject("custNo", TsfSession.getAttribute("custNo"));
		}

		mav.addObject("sEncData", sEncData);
		mav.addObject("authMethod", authMethod);

		mav.setViewName(super.getDeviceViewName("customer/CertificationForm"));
		return mav;
	}

	/**
	 * 본인인증 처리
	 *
	 * @param customer - 본인인증키
	 * @return GagaMap - 결과
	 * @author jsshin
	 * @since 2021. 03. 11
	 */
	@PostMapping("/certification/save")
	@ResponseBody
	public GagaMap saveCertification(@RequestBody Customer customer, HttpSession session) {
		String custNo = TsfSession.getAttribute("custNo");
		if (StringUtils.isBlank(custNo) || StringUtils.isBlank(customer.getEncData())) {
			throw new IllegalStateException("로그인 다시 시도해 주세요.");
		}
		GagaMap authInfo = niceCertify.getCertifyCellPhoneResultInfo(customer);
		customer.setSexGb(authInfo.getString("sGender"));
		customer.setCustNm(authInfo.getString("sName"));
		customer.setBirthYmd(authInfo.getString("sBirthDate"));
		customer.setForeignerYn(authInfo.getString("sforeignerYn"));
		customer.setCi(authInfo.getString("sCi"));
		customer.setCellPhnno(authInfo.getString("sMobileNo"));
		customer.setCustNo(Integer.parseInt(custNo));

		session.removeAttribute("custNo"); // 고객번호 세션 삭제
		return customerService.saveCertification(customer);
	}

	/**
	 * 비밀번호 변경 캠페인 화면
	 *
	 * @return ModelAndView - 가입완료 화면
	 * @author jsshin
	 * @since 2021. 03. 11
	 */
	@GetMapping("/password/campaign/form")
	public ModelAndView getPasswordCampaignnForm() {
		ModelAndView mav = new ModelAndView();

		mav.setViewName(super.getDeviceViewName("customer/PasswordCampaignForm"));

		return mav;
	}

	/**
	 * 비밀번호 변경 일시 변경
	 *
	 * @return GagaMap - 결과
	 * @param customer - 고객정보
	 * @author jsshin
	 * @since 2021. 03. 11
	 */
	@PostMapping("/password/date/update")
	@ResponseBody
	public GagaMap updatePasswordDate(@RequestBody Customer customer) {
		Integer custNo = TsfSession.getInfo().getCustNo();
		if (custNo == null) {
			throw new IllegalStateException("로그인 다시 시도해 주세요.");
		}
		customer.setCustNo(custNo);
		return customerService.updatePasswordDate(customer);
	}

	/**
	 * 이용약관
	 * @return ModelAndView
	 * @author gagamel
	 * @since 2021. 3. 18
	 */
	@GetMapping("/use/terms/form")
	public ModelAndView useTermsForm() {
		ModelAndView mav = new ModelAndView();
		mav.addObject("clause", clauseService.getClause(TscConstants.Site.STYLE24.value(), "G057_10"));
		mav.setViewName("web/customer/UseTermsFormWeb");
		return mav;
	}

	/**
	 * 개인정보취급방침
	 * @return ModelAndView
	 * @author gagamel
	 * @since 2021. 3. 18
	 */
	@GetMapping("/privacy/policy/form")
	public ModelAndView privacyPolicyForm() {
		ModelAndView mav = new ModelAndView();
		mav.addObject("clause", clauseService.getClause(TscConstants.Site.STYLE24.value(), "G057_11"));
		mav.addObject("clauseList", clauseService.getClauseList(TscConstants.Site.STYLE24.value(), "G057_11"));
		mav.setViewName("web/customer/PrivacyPolicyFormWeb");
		return mav;
	}

	/**
	 * 정보 이용동의 화면 - Yes24 사용
	 *
	 * @return ModelAndView
	 * @author jsshin
	 * @since 2021. 03. 25
	 */
	@PostMapping("/consent/useinfo/form")
	public ModelAndView cnstentUseInfoForm(Customer customer) {
		ModelAndView mav = new ModelAndView();

		mav.addObject("custNm", customer.getCustNm());

		mav.setViewName(super.getDeviceViewName("customer/ConsentUseInfoForm"));

		return mav;
	}

	/**
	 * 정보 이용동의 화면 - 연동 처리
	 *
	 * @return ModelAndView
	 * @author jsshin
	 * @since 2021. 03. 25
	 */
	@PostMapping("/peristalsis/yes24")
	@ResponseBody
	public GagaMap peristalsisYes24(HttpSession session, HttpServletRequest request) {
		CustSnsInfo custSnsInfo = (CustSnsInfo)session.getAttribute("custSnsInfo");
		session.removeAttribute("custSnsInfo"); // YES24 세션 지움

		if (custSnsInfo == null) {
			throw new IllegalStateException("연계정보 값이 없습니다. 고객센터에 문의하시기 바랍니다.");
		}

		// 1. SNS처리
		GagaMap resultMap = customerService.customerSnsProcessing(custSnsInfo);
		String custStat = resultMap.getString("custStat");

		// 2.신규가입 및 연동이면 바로 로그인 처리
		if ("NEW_CUST".equals(custStat)) {
			customerService.getLogin(Integer.parseInt(resultMap.getString("custNo")), request);
		}

		// 3.YES24 연동처리
		if ("NEW_CUST".equals(custStat) || "SUCC_CUST".equals(custStat)) {
			yes24Login.saveLink(custSnsInfo);
		}

		return resultMap;
	}

	/**
	 * 이용약관 화면
	 *
	 * @return ModelAndView
	 * @author jsshin
	 * @since 2021. 04. 01
	 */
	@PostMapping("/use/terms/layer")
	public ModelAndView getUseTermsLayer() {
		ModelAndView mav = new ModelAndView();
		mav.addObject("clause", clauseService.getClause(TscConstants.Site.STYLE24.value(), "G057_10"));
		mav.setViewName(super.getDeviceViewName("customer/UseTermsLayerForm"));
		return mav;
	}

	/**
	 * 개인정보취급방침 화면
	 *
	 * @return ModelAndView
	 * @author jsshin
	 * @since 2021. 04. 01
	 */
	@PostMapping("/privacy/policy/layer")
	public ModelAndView getPrivacyPolicyLayer(HttpServletRequest request) {
		ModelAndView mav = new ModelAndView();
		mav.addObject("clause", clauseService.getClause(TscConstants.Site.STYLE24.value(), "G057_11"));
		mav.addObject("clauseList", clauseService.getClauseList(TscConstants.Site.STYLE24.value(), "G057_11"));
		mav.addObject("mallGb", request.getParameter("mallGb"));
		mav.setViewName(super.getDeviceViewName("customer/PrivacyPolicyLayerForm"));
		return mav;
	}

	/**
	 * 개인정보취급방침 정보
	 *
	 * @return Clause
	 * @author jsshin
	 * @since 2021. 06. 10
	 */
	@GetMapping("/privacy/policy/info/{clauseSq}")
	@ResponseBody
	public Clause getPrivacyPolicyInfo(@PathVariable Integer clauseSq) {
		return clauseService.getPrivacyPolicyInfo(clauseSq);
	}

	/**
	 * 공급업체목록 화면
	 *
	 * @return ModelAndView
	 * @author jsshin
	 * @since 2021. 04. 01
	 */
	@PostMapping("/supply/company/layer")
	public ModelAndView getSupplyCompanyLayer(HttpServletRequest request) {
		ModelAndView mav = new ModelAndView();
		mav.addObject("mallGb", request.getParameter("mallGb"));
		mav.setViewName(super.getDeviceViewName("customer/SupplyCompanyLayerForm"));
		return mav;
	}

	/**
	 * 공급업체목록
	 *
	 * @param supplyCompany
	 * @return GagaMap
	 * @author jsshin
	 * @since 2021. 06. 10
	 */
	@PostMapping("/supply/company/list")
	@ResponseBody
	public GagaMap getSupplyCompanyList(@RequestBody SupplyCompany supplyCompany) {
		GagaMap result = new GagaMap();
		TscPageRequest pageable = new TscPageRequest((supplyCompany.getPageNo() > 0 ? supplyCompany.getPageNo() - 1 : 0), supplyCompany.getPageSize(), supplyCompany.getPageUnit());
		pageable.setTotalCount(commonService.getSupplyCompanyCount());
		supplyCompany.setPageable(pageable);
		result.set("supplyCompanyList",commonService.getSupplyCompanyList(supplyCompany));
		result.set("paging", supplyCompany);
		return result;
	}

	/**
	 * 개인정보위탁 화면
	 *
	 * @return ModelAndView
	 * @author jsshin
	 * @since 2021. 04. 01
	 */
	@PostMapping("/privacy/trust/layer")
	public ModelAndView getMarketingLayerForm() {
		ModelAndView mav = new ModelAndView();
		mav.addObject("clause", clauseService.getClause(TscConstants.Site.STYLE24.value(), "G057_43"));
		mav.setViewName(super.getDeviceViewName("customer/PrivacyTrustLayerForm"));
		return mav;
	}

	/**
	 * 비회원주문확인 화면
	 *
	 * @return ModelAndView
	 * @author jsshin
	 * @since 2021. 04. 20
	 */
	@GetMapping("/noncust/order/confirm/form")
	public ModelAndView getNonCustOrderConfirmForm() {
		ModelAndView mav = new ModelAndView();
		mav.setViewName(super.getDeviceViewName("customer/NonCustOrderConfirmForm"));
		return mav;
	}

	/**
	 * SMS수신거부 처리
	 * @param custNo - 고객번호
	 * @author gagamel
	 * @since 2020. 5. 11
	 */
	@GetMapping("/sms/refuse/{custNo}")
	@ResponseBody
	public GagaResponse updateSmsReceptionRefuse(@PathVariable Integer custNo) {
		customerService.updateSmsReceptionRefuse(custNo);
		return super.ok(message.getMessage("SUCC_0004"));
	}

	/**
	 * 이메일수신거부 처리
	 * @param custNo - 고객번호
	 * @author gagamel
	 * @since 2020. 5. 11
	 */
	@GetMapping("/email/refuse/{custNo}")
	@ResponseBody
	public GagaResponse updateEmailReceptionRefuse(@PathVariable Integer custNo) {
		customerService.updateSmsReceptionRefuse(custNo);
		return super.ok(message.getMessage("SUCC_0004"));
	}

}
