package com.style24.front.biz.service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

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

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
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.security.GagaPasswordEncoder;
import com.style24.core.biz.service.TscCustomerService;
import com.style24.core.biz.service.TscKakaotalkService;
import com.style24.core.biz.service.TscMailService;
import com.style24.core.support.env.TscConstants;
import com.style24.core.support.session.TscSession;
import com.style24.core.support.util.MaskingUtils;
import com.style24.front.biz.dao.TsfCustomerDao;
import com.style24.front.support.security.TsfLoginDetails;
import com.style24.front.support.security.session.TsfSession;
import com.style24.persistence.domain.Coupon;
import com.style24.persistence.domain.CustAccount;
import com.style24.persistence.domain.CustContactHst;
import com.style24.persistence.domain.CustDeliveryAddr;
import com.style24.persistence.domain.CustGrade;
import com.style24.persistence.domain.CustSnsInfo;
import com.style24.persistence.domain.Customer;
import com.style24.persistence.domain.Login;
import com.style24.persistence.domain.WishList;

import lombok.extern.slf4j.Slf4j;

/**
 * 고객(회원) Service
 *
 * @author gagamel
 * @since 2020. 12. 29
 */
@Service
@Slf4j
public class TsfCustomerService {

	@Autowired
	private TsfCustomerDao customerDao;

	@Autowired
	private TscCustomerService coreCustomerService;

	@Autowired
	private GagaPasswordEncoder passwordEncoder;

	@Autowired
	private TsfLoginService loginService;

	@Autowired
	private TsfCouponService couponService;

	@Autowired
	private TscKakaotalkService kakaotalkService;

	@Autowired
	private TscMailService mailService;

	@Autowired
	private ObjectMapper objectMapper;

	/**
	 * 고객아이디 찾기
	 *
	 * @param customer - 고객정보
	 * @return Customer
	 * @author jsshin
	 * @since 2021. 02. 08
	 */
	public Customer getCustomerFindId(Customer customer) {
		TsfSession.setAttribute("maskingYn", "Y");
		customer.setSiteCd(TscConstants.Site.STYLE24.value());
		customer.encryptData(); // 데이터 암호하
		return customerDao.getCustomerActiveAndDormant(customer);
	}

	/**
	 * 고객정보찾기
	 *
	 * @param custNo - 고객번호
	 * @return Customer 고객정보
	 * @author jsshin
	 * @since 2021. 02. 24
	 */
	public Customer getCustomerFindByCustNo(Integer custNo) {
		Customer customer = new Customer();
		customer.setCustNo(custNo);
		customer.setCustStat(TscConstants.CustStat.ACTIVE.value());
		customer.setSiteCd(TscConstants.Site.STYLE24.value());
		customer.encryptData();
		return coreCustomerService.getCustomerInfo(customer);
	}

	/**
	 * 휴면고객 정보 찾기
	 *
	 * @param custNo - 고객번호
	 * @return Customer 고객정보
	 * @author jsshin
	 * @since 2021. 03. 10
	 */
	public Customer getDormantCustomerFindByCustNo(Integer custNo) {
		Customer customer = new Customer();
		customer.setCustNo(custNo);
		customer.setCustStat(TscConstants.CustStat.DORMANT.value());
		customer.setSiteCd(TscConstants.Site.STYLE24.value());
		customer.encryptData();
		return coreCustomerService.getCustomerInfo(customer);
	}

	/**
	 * 임시비밀번호 조회
	 * @param length - 비밀번호 자릿수
	 * @return 임시비밀번호
	 * @author jsshin
	 * @since 2021. 02. 15
	 */
	public String getTemporaryPassword(int length) {
		return coreCustomerService.getTemporaryPassword(length);
	}

	/**
	 * 고객 비밀번호 수정
	 * @param customer - 고객정보
	 * @author jsshin
	 * @since 2021. 02. 15
	 */
	@Transactional("shopTxnManager")
	public void saveCustomerPassword(Customer customer) {
		customer.setEncodedPasswd(passwordEncoder.encodeSha256(customer.getPasswd()));
		coreCustomerService.saveCustomerPassword(customer);
	}

	/**
	 * 해당 아이디로 가입된 이력이 있는지 확인
	 * @param custId - 아이디
	 * @return boolean - 있으면 TRUE/ 없으면 FALSE
	 * @author jsshin
	 * @since 2021. 02. 15
	 */
	public boolean getCustomerFindByCustIdCount(String custId) {
		Customer customer = new Customer();
		customer.setCustId(custId);
		customer.setSiteCd(TscConstants.Site.STYLE24.value());
		customer.encryptData();

		int result = customerDao.getCustomerInfoCount(customer);

		return result > 0;
	}

	/**
	 * 해당 이메일로 가입된 이력이 있는지 확인
	 * @param email - 이메일
	 * @return boolean - 있으면 TRUE/ 없으면 FALSE
	 * @author jsshin
	 * @since 2021. 02. 15
	 */
	public boolean getCustomerFindByEmailCount(String email) {
		Customer customer = new Customer();
		customer.setEmail(email);
		customer.setSiteCd(TscConstants.Site.STYLE24.value());
		customer.encryptData();

		int result = customerDao.getCustomerInfoCount(customer);

		return result > 0;
	}

	/**
	 * 해당 휴대전화로 가입된 이력이 있는지 확인
	 * @param cellPhnno - 휴대전화
	 * @return boolean - 있으면 TRUE/ 없으면 FALSE
	 * @author jsshin
	 * @since 2021. 02. 15
	 */
	public boolean getCustomerFindByCellPhnnoCount(String cellPhnno) {
		Customer customer = new Customer();
		customer.setCellPhnno(cellPhnno);
		customer.setHypenCellPhone(); // 010-0000-0000
		customer.setSiteCd(TscConstants.Site.STYLE24.value());
		customer.encryptData();

		int result = customerDao.getCustomerInfoCount(customer);

		return result > 0;
	}

	/**
	 * 해당 CI로 가입된 이력이 있는지 확인
	 * @param ci - 연계정보
	 * @return boolean - 있으면 TRUE/ 없으면 FALSE
	 * @author jsshin
	 * @since 2021. 02. 15
	 */
	public boolean getCustomerFindByCiCount(String ci) {
		Customer customer = new Customer();
		customer.setCi(ci);
		customer.setSiteCd(TscConstants.Site.STYLE24.value());
		customer.encryptData();

		int result = customerDao.getCustomerInfoCount(customer);

		return result > 0;
	}

	/**
	 * 해당 CI로 가입된 이력이 있는지 확인
	 * @param ci - 연계정보
	 * @return boolean - 있으면 TRUE/ 없으면 FALSE
	 * @author jsshin
	 * @since 2021. 02. 15
	 */
	public Customer getCustomerFindByCi(String ci) {
		TscSession.setAttribute("maskingYn", "Y");
		Customer customer = new Customer();
		customer.setCi(ci);
		customer.setSiteCd(TscConstants.Site.STYLE24.value());
		customer.encryptData();

		return customerDao.getCustomerInfo(customer);
	}

	/**
	 * 해당 휴대폰 번호로 가입된 이력이 있는지 확인
	 * @param cellPhnno - 휴대전화번호
	 * @return Customer - 고객정보
	 * @author jsshin
	 * @since 2021. 02. 15
	 */
	public Customer getCustomerFindByCellPhnno(String cellPhnno) {
		TscSession.setAttribute("maskingYn", "Y");
		Customer customer = new Customer();
		customer.setCellPhnno(cellPhnno);
		customer.setHypenCellPhone(); // 010-0000-0000
		customer.setSiteCd(TscConstants.Site.STYLE24.value());
		customer.encryptData();

		return customerDao.getCustomerInfo(customer);
	}

	/**
	 * 회원가입 처리 - 일반가입
	 * @param customer - 일반가입
	 * @return boolean - 가입 성공 true / 실패 false
	 * @author jsshin
	 * @since 2021. 02. 19
	 */
	@Transactional("shopTxnManager")
	public boolean saveJoinCustomer(Customer customer) {
		boolean isJoin = true;
		customer.initBirthMm();
		customer.setHypenCellPhone();
		customer.encryptData();
		customer.setEncodedPasswd(passwordEncoder.encodeSha256(customer.getPasswd()));

		customer.setCustStat(TscConstants.CustStat.ACTIVE.value());
		customer.setCustGb(TscConstants.CustGb.NORMAL.value());
		customer.setCustGrade(TscConstants.CustGrade.WELCOME.value());
		
		int custCnt = customerDao.createCustomer(customer);

		if (custCnt > 0) {
			saveJoinPostProcessing(customer);
		} else {
			isJoin = false;
		}

		if(isJoin) {
			Coupon coupon = couponService.getJoinCouponInfo();
			// 알림톡 발송
			try {
				if (StringUtils.isNotBlank(customer.getCellPhnno())) {
					kakaotalkService.sendJoinCongrat(customer, coupon, customer.getCustNo());
				}
			} catch (Exception e) {
				log.error("error", e);
			}

			// 이메일 발송
			try {
				if (StringUtils.isNotBlank(customer.getEmail())) {
					mailService.sendJoinCongrat(customer, coupon, customer.getCustNo());
				}
			} catch (Exception e) {
				log.error("error", e);
			}
		}
		return isJoin;
	}

	/**
	 * 회원가입 처리 - SNS 간편가입
	 * @param customer - SNS 정보
	 * @return boolean - 가입 성공 true / 실패 false
	 * @author jsshin
	 * @since 2021. 02. 19
	 */
	@Transactional("shopTxnManager")
	public boolean saveJoinCustomerSns(Customer customer) {
		boolean isJoin = true;
		String snsId = customer.getSnsType().equals(TscConstants.SnsType.YES24.value()) ? customer.getMemNo() : customer.getSnsId();
		customer.initBirthMm();
		customer.setEncodedPasswd(" ");
		customer.setCustId(customer.getSnsType() + "_" + snsId);
		customer.setHypenCellPhone();
		customer.encryptData();

		customer.setSiteCd(TscConstants.Site.STYLE24.value());
		customer.setFrontGb(TsfSession.getFrontGb());
		customer.setAfLinkCd(TsfSession.getAttribute("afLinkCd"));
		customer.setCustStat(TscConstants.CustStat.ACTIVE.value());
		customer.setCustGb(TscConstants.CustGb.NORMAL.value());
		customer.setCustGrade(TscConstants.CustGrade.WELCOME.value());

		int custCnt = customerDao.createCustomer(customer);
		customerDao.createCustomerSns(customer);

		if (custCnt > 0) {
			saveJoinPostProcessing(customer);
			TsfSession.setAttribute("custNo", String.valueOf(customer.getCustNo()));
		} else {
			isJoin = false;
		}

		if (isJoin) {
			Coupon coupon = couponService.getJoinCouponInfo();
			// 알림톡 발송
			try {
				if (StringUtils.isNotBlank(customer.getCellPhnno())) {
					kakaotalkService.sendJoinCongrat(customer, coupon, customer.getCustNo());
				}
			} catch (Exception e) {
				log.error("error", e);
			}

			// 이메일 발송
			try {
				if (StringUtils.isNotBlank(customer.getEmail())) {
					mailService.sendJoinCongrat(customer, coupon, customer.getCustNo());
				}
			} catch (Exception e) {
				log.error("error", e);
			}
		}

		return isJoin;

	}

	/**
	 * 가입 후 처리 혜택(쿠폰)
	 * @param customer - 일반가입, SNS 가입
	 * @author jsshin
	 * @since 2021. 02. 19
	 */
	@Transactional("shopTxnManager")
	public void saveJoinPostProcessing(Customer customer) {
		// 1. 쿠폰지급 : 운영관리 > 회원등급정책관리 > WELCOME 등급
		Coupon coupon = new Coupon();
		coupon.setCustNo(customer.getCustNo());
		coupon.setFrontGb(customer.getFrontGb());
		coupon.setCustGrade(customer.getCustGrade());
		coupon.setCustNo(customer.getCustNo());
		coupon.setSiteCd(TscConstants.Site.STYLE24.value());
		couponService.saveJoinCoupon(coupon);
	}

	/**
	 * Sns 정보에대한 상태 처리
	 *
	 * @param custSnsInfo - SNS 고객 정보
	 * @author jsshin
	 * @since 2021. 02. 19
	 */
	@Transactional("shopTxnManager")
	public GagaMap customerSnsProcessing(CustSnsInfo custSnsInfo) {
		GagaMap resultMap = new GagaMap();
		Customer custInfo;

		// 1. snsId, snsType 값으로 연동되어져 있는지 확인
		custInfo = customerDao.getCusomterSnsFind(custSnsInfo);
		if (custInfo != null) {
			resultMap.setString("custStat", "SUCC_CUST");
			return resultMap;
		}

		if (StringUtils.isBlank(custSnsInfo.getCi())) {
			resultMap.setString("custStat","EMPTY_CI_CUST");
			return resultMap;
		}

		// 2. CI(연계정보)로 가입 되어져 있는 고객이 확인
		custInfo = getCustomerFindByCi(custSnsInfo.getCi());

		if (custInfo != null) { // 2-1. 고객정보 있는경우

			if (TscConstants.CustStat.SECEDE.value().equals(custInfo.getCustStat())) {
				resultMap.setString("custStat", "SECEDE_CUST"); // 탈퇴 회원
				return resultMap;
			}

			if (TscConstants.CustStat.DORMANT.value().equals(custInfo.getCustStat())) {
				resultMap.setString("custStat", "DORMANT_CUST"); // 휴면 회원
				return resultMap;
			}

			if (TscConstants.CustStat.ACTIVE.value().equals(custInfo.getCustStat())) {

				custInfo.setSnsId(custSnsInfo.getSnsId());
				custInfo.setSnsType(custSnsInfo.getSnsType());
				customerDao.createCustomerSns(custInfo);

				resultMap.setString("custStat", "SUCC_CUST");
				resultMap.setString("snsId", custSnsInfo.getSnsId());
				resultMap.setString("snsType", custSnsInfo.getSnsType());
				return resultMap;
			}

		} else { // 2-2. 고객정보 없는 경우

			if (StringUtils.isBlank(custSnsInfo.getCellPhnno())) { // 휴대전화번호가 없는 경우
				resultMap.setString("custStat", "EMPTY_PHONE_CUST");
				return resultMap;
			}
			boolean isFindByPhone = getCustomerFindByCellPhnnoCount(custSnsInfo.getCellPhnno().replace("-", ""));
			if (isFindByPhone) {
				resultMap.setString("custStat", "DUP_PHONE_CUST"); // 휴대폰 중복
				return resultMap;
			}
			boolean isFindByEmail = getCustomerFindByEmailCount(custSnsInfo.getEmail());
			if (isFindByEmail) {
				resultMap.setString("custStat", "DUP_EMAIL_CUST"); // 이메일 중복
				return resultMap;
			}
			Customer customer = objectMapper.convertValue(custSnsInfo, Customer.class);
			boolean isJoin = saveJoinCustomerSns(customer);
			if (!isJoin) {
				resultMap.setString("custStat", "FAIL_CUST");
				return resultMap;
			}
			resultMap.setString("custNo", String.valueOf(customer.getCustNo()));
			resultMap.setString("custStat", "NEW_CUST");
		}

		return resultMap;
	}

	/**
	 * 로그인 처리
	 * @param custNo- 고객번호
	 * @param request - 요청
	 * @author jsshin
	 * @since 2021. 02. 18
	 */
	public void getLogin(Integer custNo, HttpServletRequest request) {
		if (custNo == null) {
			throw new IllegalStateException("고객번호가 없습니다.");
		}
		Login loginParam = new Login();
		loginParam.setCustNo(custNo);
		Login loginInfo = loginService.getLoginCheckInfo(loginParam);

		// 권한 설정
		List<SimpleGrantedAuthority> authorities = new ArrayList<>();
		authorities.add(new SimpleGrantedAuthority(loginInfo.getCustGb()));

		TsfLoginDetails loginDetails = new TsfLoginDetails(loginInfo, authorities);

		// 최종로그인일시 Update
		loginService.updateLastLoginDate(loginInfo.getCustNo());

		// 로그인이력 생성
		loginService.createLoginHistory(loginInfo.getCustNo());

		// 세션 생성
		this.createSession(request, loginDetails);
	}

	/**
	 * Session 생성
	 *
	 * @param request - HttpServletRequest
	 * @param loginDetails - 로그인 상세 정보
	 * @author jsshin
	 * @since 2021. 02. 18
	 */
	private void createSession(HttpServletRequest request, TsfLoginDetails loginDetails) {
		HttpSession session = request.getSession(true);
		session.setMaxInactiveInterval(1800);
		session.setAttribute("session", loginDetails);
	}

	/**
	 * 일반고객 정보 유효성
	 *
	 * @param customer - 고객정보
	 * @return GagaMap - 유효성 결과 값
	 * @author jsshin
	 * @since 2021. 02. 18
	 */
	public GagaMap generalCustomerValidation(Customer customer) {
		GagaMap resultMap = new GagaMap();
		String maskingCustId;
		String custId;

		if (StringUtils.isNotBlank(customer.getSnsType()) && StringUtils.isNotBlank(customer.getSnsId())) {
			String snsId = customer.getSnsType().equals(TscConstants.SnsType.YES24.value()) ? customer.getMemNo() : customer.getSnsId();
			custId = customer.getSnsType() + "_" + snsId;
		} else {
			custId = customer.getCustId();
		}

		// 1. 아이디 확인
		boolean boolCustId = getCustomerFindByCustIdCount(custId);
		if (boolCustId) {
			maskingCustId = getMaxCustIdById(customer.getCustId());
			resultMap.setBoolean("isPossibe", false);
			resultMap.setString("maskingCustId", maskingCustId);
			return resultMap;
		}

		// 2. 이메일 확인
		boolean boolEmail = getCustomerFindByEmailCount(customer.getEmail());
		if (boolEmail) {
			maskingCustId = getMaxCustIdByEmail(customer.getEmail());
			resultMap.setBoolean("isPossibe", false);
			resultMap.setString("maskingCustId", maskingCustId);
			return resultMap;
		}

		// 3. 휴대전화
		boolean boolPhone = getCustomerFindByCellPhnnoCount(customer.getCellPhnno());
		if (boolPhone) {
			maskingCustId = getMaxCustIdByCellPhnno(customer.getCellPhnno());
			resultMap.setBoolean("isPossibe", false);
			resultMap.setString("maskingCustId", maskingCustId);
			return resultMap;
		}

		// 4. CI(연계정보)
		boolean boolCi = getCustomerFindByCiCount(customer.getCi());
		if (boolCi) {
			maskingCustId = getMaxCustIdByCi(customer.getCi());
			resultMap.setBoolean("isPossibe", false);
			resultMap.setString("maskingCustId", maskingCustId);
			return resultMap;
		}

		resultMap.setBoolean("isPossibe", true);

		return resultMap;
	}

	/**
	 * SNS 정보로 고객 테이블 조회
	 * @param custSnsInfo - 고객정보
	 * @return 고객정보
	 * @author jsshin
	 * @since 2021. 02. 26
	 */
	public Customer getCusomterSnsFind(CustSnsInfo custSnsInfo) {
		return customerDao.getCusomterSnsFind(custSnsInfo);
	}

	/**
	 * 가입된 아이디 가져오기
	 * @param custId - 고객아이디
	 * @return String - 가입된 고객 아이디
	 * @author jsshin
	 * @since 2021. 03. 02
	 */
	public String getMaxCustIdById(String custId) {
		Customer customer = new Customer();
		customer.setSiteCd(TscConstants.Site.STYLE24.value());
		customer.setCustId(custId);
		String maskingCustId = customerDao.getCustomerMaxCustId(customer);
		return MaskingUtils.id(maskingCustId);
	}

	/**
	 * 가입된 아이디 가져오기
	 * @param email - 이메일
	 * @return String - 가입된 고객 아이디
	 * @author jsshin
	 * @since 2021. 03. 02
	 */
	public String getMaxCustIdByEmail(String email) {
		Customer customer = new Customer();
		customer.setSiteCd(TscConstants.Site.STYLE24.value());
		customer.setEmail(email);
		customer.encryptData();
		String maskingCustId = customerDao.getCustomerMaxCustId(customer);
		return MaskingUtils.id(maskingCustId);
	}

	/**
	 * 가입된 아이디 가져오기
	 * @param cellPhnno - 전화번호
	 * @return String - 가입된 고객 아이디
	 * @author jsshin
	 * @since 2021. 03. 02
	 */
	public String getMaxCustIdByCellPhnno(String cellPhnno) {
		Customer customer = new Customer();
		customer.setSiteCd(TscConstants.Site.STYLE24.value());
		customer.setCellPhnno(cellPhnno);
		customer.encryptData();
		String maskingCustId = customerDao.getCustomerMaxCustId(customer);
		return MaskingUtils.id(maskingCustId);
	}

	/**
	 * 가입된 아이디 가져오기
	 * @param ci - 연계정보
	 * @return String - 가입된 고객 아이디
	 * @author jsshin
	 * @since 2021. 03. 02
	 */
	public String getMaxCustIdByCi(String ci) {
		Customer customer = new Customer();
		customer.setSiteCd(TscConstants.Site.STYLE24.value());
		customer.setCi(ci);
		customer.encryptData();
		String maskingCustId = customerDao.getCustomerMaxCustId(customer);
		return MaskingUtils.id(maskingCustId);
	}

	/**
	 * 위시리스트 등록
	 *
	 * @return void
	 * @author eskim
	 * @since 2021. 03. 08
	 */
	@Transactional("shopTxnManager")
	public void createWishList(Collection<WishList> wishlist) {

		for (WishList wishInfo : wishlist) {
			wishInfo.setCustNo(TsfSession.getInfo().getCustNo());
			wishInfo.setAfLinkCd(TsfSession.getAttribute("afLinkCd"));
			//wishInfo.setIthrCd(GagaCookieUtil.getCookie(TsfSession.getHttpServletRequest(), TsfConstants.CK_PREFIX + "_ithrCd"));
			//wishInfo.setContentsLoc(GagaCookieUtil.getCookie(TsfSession.getHttpServletRequest(), TsfConstants.CK_PREFIX + "_contentsLoc"));
			wishInfo.setRegNo(TsfSession.getInfo().getCustNo());
			customerDao.createWishList(wishInfo);
		}

		// 위시상품목록 50개만 남게 처리
		String goodsCd = customerDao.getDeleteGoodsWish(TsfSession.getInfo().getCustNo());
		WishList delWishInfo = new WishList();
		delWishInfo.setCustNo(TsfSession.getInfo().getCustNo());
		if (!StringUtils.isBlank(goodsCd)) {
			delWishInfo.setArrGoodsCd(goodsCd.split("\\,"));
			customerDao.deleteWishList(delWishInfo);
		}

	}

	/**
	 * 위시리스트 삭제처리
	 *
	 * @param wishlist - 고객 일련번호
	 * @return void
	 * @author eskim
	 * @since 2021. 03. 08
	 */
	@Transactional("shopTxnManager")
	public void deleteWishList(Collection<WishList> wishlist) {

		for (WishList wishInfo : wishlist) {
			wishInfo.setCustNo(TsfSession.getInfo().getCustNo());
			customerDao.deleteWishList(wishInfo);
		}
	}

	/**
	 * 휴면해제
	 *
	 * @param customer - 고객정보
	 * @return GagaMap - 결과
	 * @author jsshin
	 * @since 2021. 03. 08
	 */
	@Transactional("shopTxnManager")
	public GagaMap releaseDormantCustomer(Customer customer) {
		GagaMap result = new GagaMap();

		Customer custInfo = getDormantCustomerFindByCustNo(customer.getCustNo());

		if (!customer.getCi().equals(custInfo.getCi())) {
			result.setBoolean("isRelase", false);
			result.setString("errorType", "DIFFERENT_CI"); // 계정이 등록된 CI랑 인증한 CI가 다를떄
			return result;
		}

		customer.setRegNo(customer.getCustNo());
		customer.setUpdNo(customer.getCustNo());
		boolean isRelase = coreCustomerService.saveDormantCustomerRelease(customer);
		result.setBoolean("isRelase", isRelase);
		return result;
	}

	/**
	 * 본인인증 처리
	 *
	 * @param customer - 본인인증키
	 * @return GagaMap - 결과
	 * @author jsshin
	 * @since 2021. 03. 11
	 */
	@Transactional("shopTxnManager")
	public GagaMap saveCertification(Customer customer) {
		GagaMap resultMap = new GagaMap();
		customer.initBirthMm();
		customer.setRegNo(customer.getCustNo());
		customer.setUpdNo(customer.getCustNo());
		customer.setHypenCellPhone();
		customer.encryptData();
		boolean isSuccess = false;

		// CI 유효성 체크
		Customer custInfo = getCustomerFindByCi(customer.getCi());
		if (custInfo != null) {
			TsfSession.setAttribute("maskingCustId", custInfo.getMaskingCustId());
			resultMap.setBoolean("isSuccess", isSuccess);
			return resultMap;
		}

		// 1.이력 쌓고
		coreCustomerService.createCustomerHistory(customer);
		// 2.CI 업데이트
		int resultCnt = customerDao.updateCustomerCi(customer);

		if (resultCnt > 0) {
			isSuccess = true;
		}
		resultMap.setBoolean("isSuccess", isSuccess);

		return resultMap;
	}

	/**
	 * 비밀번호 변경 날짜 업데이트
	 *
	 * @param customer - 고객번호
	 * @return GagaMap - 결과
	 * @author jsshin
	 * @since 2021. 03. 11
	 */
	@Transactional("shopTxnManager")
	public GagaMap updatePasswordDate(Customer customer) {
		GagaMap resultMap = new GagaMap();
		boolean isSuccess = false;
		customer.setRegNo(customer.getCustNo());
		customer.setUpdNo(customer.getCustNo());
		customer.setPwdChangeDay(60); //30일간 안보여야 하기때문에 (오늘날짜 - 60) 처리

		// 1.이력 쌓고
		coreCustomerService.createCustomerHistory(customer);

		// 2.비밀번호 변경일자 업데이트
		int resultCnt = customerDao.updatePasswordDate(customer);
		if (resultCnt > 0) {
			isSuccess = true;
		}

		resultMap.setBoolean("isSuccess", isSuccess);

		return resultMap;
	}

	/**
	 * 비밀번호 맞는지 확인
	 *
	 * @param customer - 고객정보
	 * @return boolean
	 * @author jsshin
	 * @since 2021. 03. 15
	 */
	public boolean customerPasswordConfirm(Customer customer) {
		boolean isMatch = false;
		Login login = new Login();
		login.setCustNo(TsfSession.getInfo().getCustNo());
		Login loginCheckInfo = loginService.getLoginCheckInfo(login);

		if (loginCheckInfo != null) {
			isMatch = passwordEncoder.matchesSha256(customer.getPasswd(), loginCheckInfo.getPasswd());
		}

		return isMatch;
	}

	/**
	 * 본인인증을 통한 이름, 휴대전화번호 수정
	 *
	 * @param customer - 고객정보
	 * @return GagaMap
	 * @author jsshin
	 * @since 2021. 03. 15
	 */
	@Transactional("shopTxnManager")
	public GagaMap updateCustomerAuth(Customer customer) {
		GagaMap result = new GagaMap();
		customer.initBirthMm();
		customer.setRegNo(customer.getCustNo());
		customer.setUpdNo(customer.getCustNo());
		customer.setHypenCellPhone();
		customer.encryptData();
		// 1. 이력쌓고
		coreCustomerService.createCustomerHistory(customer);

		// 2. 이름, 휴대전화 번호, 생년월일 저장
		int updateCnt = customerDao.updateCustomerAuth(customer);

		boolean isSuccess = updateCnt > 0; // 변경 성공시 true

		result.setBoolean("isSuccess", isSuccess);

		return result;
	}

	/**
	 * 고객계좌 정보
	 *
	 * @param  custNo - 고객번호
	 * @return CustAccount - 고객계과 정보
	 * @author jsshin
	 * @since 2021. 03. 18
	 */
	public CustAccount getCustomerAccuontInfo(Integer custNo) {
		return coreCustomerService.getCustomerAccuontInfo(custNo);
	}

	/**
	 * 고객정보 수정
	 *
	 * @param  customer - 고객정보
	 * @return GagaMap - 결과
	 * @author jsshin
	 * @since 2021. 03. 19
	 */
	@Transactional("shopTxnManager")
	public GagaMap saveCustomerInfo(Customer customer) {
		GagaMap result = new GagaMap();
		Integer custNo = TsfSession.getInfo().getCustNo();
		customer.setCustNo(custNo);
		customer.setRegNo(custNo);
		customer.setUpdNo(custNo);
		customer.setSiteCd(TscConstants.Site.STYLE24.value());

		// 1. 이메일 변경여부 체크 및 변경시 유효성 체크
		if ("Y".equals(customer.getEmailModifyYn())) {
			customer.encryptData();
			boolean isFind = getCustomerByEmail(customer);
			if (isFind) {
				result.setBoolean("isSuccess", false);
				result.setString("resultType", "DUP_EMAIL");
				return result;
			}
		}

		// 2. 계좌정보 수정여부 체크
		if ("Y".equals(customer.getAccountModifyYn())) {
			CustAccount custAccount = new CustAccount();
			custAccount.setCustNo(custNo);
			custAccount.setRegNo(custNo);
			custAccount.setUpdNo(custNo);
			custAccount.setAccountNo(customer.getAccountNo());
			custAccount.setAccountNm(customer.getAccountNm());
			custAccount.setBankCd(customer.getBankCd());
			coreCustomerService.saveCustomerAccountInfo(custAccount);
		}

		// 3. 마케팅 수정 여부 체크
		if ("Y".equals(customer.getMarketingModifyYn())) {
			coreCustomerService.createCustomerMarketHst(customer);
		}

		// 4. 고객이력 생성
		coreCustomerService.createCustomerHistory(customer);
		// 5. 고객정보 수정
		customerDao.updateCustomerInfo(customer);

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

	/**
	 * 이메일 유효성 체크 -
	 * 본인이 사용하고 있는 이메일 제외 하고 다른 사람이
	 * 변경하려는 이메일 사용하느지 체크
	 *
	 * @param  customer - 이메일, 고객번호
	 * @return GagaMap - 결과
	 * @author jsshin
	 * @since 2021. 03. 19
	 */
	public boolean getCustomerByEmail(Customer customer) {
		customer.encryptData();
		int resultCnt = coreCustomerService.getCustomerByEmail(customer);
		return resultCnt > 0;
	}

	/**
	 * 회원탈퇴 처리
	 *
	 * @param  customer - 고객번호
	 * @return GagaMap - 결과
	 * @author jsshin
	 * @since 2021. 03. 24
	 */
	@Transactional("shopTxnManager")
	public GagaMap saveCustomerSecede(Customer customer) {
		return coreCustomerService.saveCustomerSecede(customer);
	}

	/**
	 * 마이페이지 - 비밀번호 변경
	 *
	 * @param  customer - 고객번호
	 * @return GagaMap - 결과
	 * @author jsshin
	 * @since 2021. 04. 01
	 */
	@Transactional("shopTxnManager")
	public GagaMap changePassword(Customer customer) {
		GagaMap resultMap = new GagaMap();
		boolean isSuccess = false;
		Login login = new Login();
		login.setCustNo(customer.getCustNo());
		Login loginCheckInfo = loginService.getLoginCheckInfo(login);

		if (loginCheckInfo != null) {
			isSuccess = passwordEncoder.matchesSha256(customer.getOrgPasswd(), loginCheckInfo.getPasswd());
		}
		if (!isSuccess) {
			resultMap.setBoolean("isSuccess", isSuccess);
			resultMap.setString("resultType", "WRONG_PWD");
			return resultMap;
		} else {
			customer.setTempPasswdYn("N"); // 임시비밀번호여부
			saveCustomerPassword(customer); // 비밀번호 수정
		}
		resultMap.setBoolean("isSuccess", isSuccess);
		return resultMap;
	}

	/**
	 * 마이페이지 - 배송지 목록
	 *
	 * @param  custDeliveryAddr - 고객번호
	 * @return Collection<CustDeliveryAddr> - 배송목록
	 * @author jsshin
	 * @since 2021. 04. 01
	 */
	public Collection<CustDeliveryAddr> getCustomerDeliveryAddrList(CustDeliveryAddr custDeliveryAddr) {
		return coreCustomerService.getCustomerDeliveryAddrList(custDeliveryAddr);
	}

	/**
	 * 마이페이지 - 배송지 삭제
	 *
	 * @param  custDeliveryAddr - 고객번호
	 * @return Collection<CustDeliveryAddr> - 배송목록
	 * @author jsshin
	 * @since 2021. 04. 01
	 */
	@Transactional("shopTxnManager")
	public GagaMap deleteCustDeliveryAddr(CustDeliveryAddr custDeliveryAddr) {
		GagaMap resultMap = new GagaMap();
		Integer custNo = TsfSession.getInfo().getCustNo();
		custDeliveryAddr.setCustNo(custNo);
		custDeliveryAddr.setRegNo(custNo);
		custDeliveryAddr.setUpdNo(custNo);
		int resultCnt = coreCustomerService.deleteCustDeliveryAddr(custDeliveryAddr);
		boolean isSuccess = resultCnt > 0;
		resultMap.setBoolean("isSuccess", isSuccess);
		return resultMap;
	}

	/**
	 * 고객 예상등급
	 *
	 * @param  customer - 고객번호
	 * @return GagaMap - 예상등급
	 * @author jsshin
	 * @since 2021. 04. 06
	 */
	public GagaMap getExpectedCustGrde(Customer customer) {
		GagaMap result = new GagaMap();
		CustGrade params = new CustGrade();
		params.setCustNo(customer.getCustNo());
		params.setSiteCd(customer.getSiteCd());
		Collection<CustGrade> custGradePolicy = customerDao.getCustGradePolicy(params);

		CustGrade expctCustGrade;
		for (CustGrade grade : custGradePolicy) {
			grade.setCustNo(customer.getCustNo());
			expctCustGrade = customerDao.getExpectedCustGrde(grade);
			if (expctCustGrade != null) {
				result.set("expctCustGrade", expctCustGrade);
				return result;
			}
		}
		return result;
	}

	/**
	 * 고객 정책정보
	 *
	 * @param  custGrade - 고객번호
	 * @return Collection<CustGrade>
	 * @author jsshin
	 * @since 2021. 04. 12
	 */
	public Collection<CustGrade> getCustGradePolicy(CustGrade custGrade) {
		return customerDao.getCustGradePolicy(custGrade);
	}

	/**
	 * SMS수신거부 처리
	 * @param custNo - 고객번호
	 * @author gagamel
	 * @since 2021. 5. 11
	 */
	@Transactional("shopTxnManager")
	public void updateSmsReceptionRefuse(Integer custNo) {
		// 수신거부 처리
		int result = customerDao.updateSmsReceptionRefuse(custNo);

		if (result > 0) {
			Customer customer = new Customer();
			customer.setCustNo(custNo);
			customer.setSmsAgreeYn("N");
			customer.setRegNo(custNo);

			// 마케팅수신동의이력 생성
			coreCustomerService.createCustomerMarketHst(customer);

			// 고객이력 생성
			coreCustomerService.createCustomerHistory(customer);
		}
	}

	/**
	 * 메일수신거부 처리
	 * @param custNo - 고객번호
	 * @author gagamel
	 * @since 2021. 5. 11
	 */
	@Transactional("shopTxnManager")
	public void updateEmailReceptionRefuse(Integer custNo) {
		// 수신거부 처리
		int result = customerDao.updateEmailReceptionRefuse(custNo);

		if (result > 0) {
			Customer customer = new Customer();
			customer.setCustNo(custNo);
			customer.setEmailAgreeYn("N");
			customer.setRegNo(custNo);

			// 마케팅수신동의이력 생성
			coreCustomerService.createCustomerMarketHst(customer);

			// 고객이력 생성
			coreCustomerService.createCustomerHistory(customer);
		}
	}



	/**
	 * 고객 예상등급 이후 정보
	 *
	 * @param  custGrade - 고객번호
	 * @return GagaMap
	 * @author jsshin
	 * @since 2021. 05. 11
	 */
	public GagaMap getNextCustGradeInfo(CustGrade custGrade) {
		GagaMap result = new GagaMap();
		// 1.고객 예상등급 이후 정보
		List<CustGrade> custGradePolicy = (List<CustGrade>) customerDao.getCustGradePolicy(custGrade);
		CustGrade nextCustGradePolicy = custGradePolicy.get(0);
		nextCustGradePolicy.setCustNo(custGrade.getCustNo());
		// 2.고객 예상등급 이후 정보로 주문금액 확인
		CustGrade nextCustGrade = customerDao.getCustGradeOrderInfo(nextCustGradePolicy);
		if (nextCustGrade != null) {
			nextCustGradePolicy.setOrdCnt(nextCustGrade.getOrdCnt());
			nextCustGradePolicy.setSumRealOrdAmt(nextCustGrade.getSumRealOrdAmt());
		} else {
			nextCustGradePolicy.setOrdCnt(0);
			nextCustGradePolicy.setSumRealOrdAmt(0);
		}
		result.set("nextCustGradePolicy", nextCustGradePolicy);
		return result;
	}

	/**
	 * 앱푸시수신여부
	 *
	 * @return String - 앱수신여부
	 * @author jsshin
	 * @since 2021. 05. 20
	 */
	public String getAppAgreeYn() {
		if (!TsfSession.isLogin()) {
			return  "N";
		}

		Customer customer = getCustomerFindByCustNo(TsfSession.getInfo().getCustNo());
		if (customer != null) {
			return  customer.getAppAgreeYn();
		}

		return "N";
	}

	/**
	 * 앱마케팅수신여부
	 *
	 * @return String - 앱수신여부
	 * @author jsshin
	 * @since 2021. 05. 20
	 */
	public String getAppMkAgreeYn() {
		if (!TsfSession.isLogin()) {
			return  "N";
		}
		Customer customer = getCustomerFindByCustNo(TsfSession.getInfo().getCustNo());
		if (customer != null) {
			return customer.getMkAgreeYn();
		}
		return "N";
	}

	/**
	 * 앱푸시수신동의여부 변경
	 *
	 * @param appAppAgreeYn - 앱푸시수신여부
	 * @return int - 결과
	 * @author jsshin
	 * @since 2021. 05. 20
	 */
	@Transactional("shopTxnManager")
	public int updateAppAgreeYn(String appAppAgreeYn) {
		if (!TsfSession.isLogin()) {
			throw new IllegalStateException("로그인 후 다시 시도하시기 바랍니다.");
		}

		Integer custNo = TsfSession.getInfo().getCustNo();
		Customer customer = getCustomerFindByCustNo(custNo);
		int resultCnt = 0;
		if (customer != null) {
			if (!customer.getAppAgreeYn().equals(appAppAgreeYn)) {
				Customer custInfo = new Customer();
				custInfo.setCustNo(custNo);
				custInfo.setAppAgreeYn(appAppAgreeYn);
				custInfo.setRegNo(custNo);
				custInfo.setUpdNo(custNo);
				coreCustomerService.createCustomerMarketHst(custInfo);

				coreCustomerService.createCustomerHistory(custInfo);

				resultCnt = customerDao.updateAppAgreeYn(custInfo);
			}
		}
		return resultCnt;
	}

	/**
	 * 앱마케팅수신여부 변경
	 *
	 * @param mkAgreeYn - 마케팅 수신여부
	 * @return int - 결과
	 * @author jsshin
	 * @since 2021. 05. 20
	 */
	@Transactional("shopTxnManager")
	public int updateMkAgreeYn(String mkAgreeYn) {
		if (!TsfSession.isLogin()) {
			throw new IllegalStateException("로그인 후 다시 시도하시기 바랍니다.");
		}

		Integer custNo = TsfSession.getInfo().getCustNo();
		Customer customer = getCustomerFindByCustNo(custNo);
		int resultCnt = 0;
		if (customer != null) {
			if (!customer.getMkAgreeYn().equals(mkAgreeYn)) {
				Customer custInfo = new Customer();
				custInfo.setCustNo(custNo);
				custInfo.setMkAgreeYn(mkAgreeYn);
				custInfo.setRegNo(custNo);
				custInfo.setUpdNo(custNo);
				coreCustomerService.createCustomerMarketHst(custInfo);

				coreCustomerService.createCustomerHistory(custInfo);

				resultCnt = customerDao.updateMkAgreeYn(custInfo);
			}
		}
		return resultCnt;
	}

	/**
	 * 선물하기 알림톡 발송 정보 조회
	 *
	 * @param CustContactHst
	 * @return int
	 * @author card007
	 * @since 2021. 06. 04
	 */
	public int getGiftKakaoSendInfo(CustContactHst custContactHst) {
		return customerDao.getGiftKakaoSendInfo(custContactHst);
	}

}
