package com.style24.batch.biz.service;

import java.util.Collection;

import com.style24.core.biz.service.TscKakaotalkService;
import com.style24.core.biz.service.TscMailService;
import com.style24.persistence.domain.CustAccount;
import com.style24.persistence.domain.CustCoupon;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.style24.batch.biz.dao.TsbCustomerDao;
import com.style24.batch.support.env.TsbConstants;
import com.style24.core.biz.service.TscCustomerService;

import com.style24.core.support.util.CryptoUtils;

import com.style24.persistence.domain.CustGrade;
import com.style24.persistence.domain.Customer;
import com.style24.persistence.domain.CustomerSearch;

import lombok.extern.slf4j.Slf4j;

import com.gagaframework.web.parameter.GagaMap;

/**
 * 회원(고객) Service
 *
 * @author jsshin
 * @since 2021. 03. 05
 */
@Service
@Slf4j
public class TsbCustomerService {

	@Autowired
	private TsbCustomerDao customerDao;

	@Autowired
	private TscCustomerService coreCustomerService;

	@Autowired
	private TscKakaotalkService kakaotalkService;

	@Autowired
	private TscMailService mailService;

	/**
	 * 휴면전환예정 메일 발송 대상
	 *
	 * @param customerSearch - 전환예정기간
	 * @return Collection<Customer>
	 * @author jsshin
	 * @since 2021. 03. 05
	 */
	public Collection<Customer> getDormantCustomerScheduleList(CustomerSearch customerSearch) {
		return customerDao.getDormantCustomerScheduleList(customerSearch);
	}

	/**
	 * 휴면전환예정 안내 메일 발송 대상
	 *
	 * @param customerCollection - 대상
	 * @return int - 성공여부
	 * @author jsshin
	 * @since 2021. 03. 08
	 */
	@Transactional("shopTxnManager")
	public GagaMap sendDormantCustomerSchedule(Collection<Customer> customerCollection) {
		GagaMap result = new GagaMap();
		int succCnt = 0;
		int failCnt = 0;
		Integer senderNo = TsbConstants.REG_NO;
		for (Customer customer : customerCollection) {
			try {
				// 이메일 발송
				if (StringUtils.isNotBlank(customer.getEmail())) {
					mailService.sendExpectedDormentCustomer(customer, senderNo);
				}
				// 카카오톡 알림톡
				if (StringUtils.isNotBlank(customer.getCellPhnno())) {
					kakaotalkService.sendExpectedDormentCustomer(customer, senderNo);
				}

				succCnt++;

			} catch (Exception e) {
				failCnt++;
			}
		}

		result.setInt("succCnt", succCnt);
		result.setInt("failCnt", failCnt);

		return result;
	}

	/**
	 * 휴면회원 전환대상
	 *
	 * @param customerSearch - 전환기간
	 * @return Collection<Customer>
	 * @author jsshin
	 * @since 2021. 03. 05
	 */
	public Collection<Customer> getDormentCustomerList(CustomerSearch customerSearch) {
		return customerDao.getDormentCustomerList(customerSearch);
	}

	/**
	 * 휴면회원 전환 처리
	 *
	 * @param customerSearch - 전환기간
	 * @return GagaMap - 결과
	 * @author jsshin
	 * @since 2021. 03. 05
	 */
	@Transactional("shopTxnManager")
	public GagaMap saveDormantCustomer(CustomerSearch customerSearch) {
		GagaMap result = new GagaMap();
		customerSearch.setEncodedCustNm(CryptoUtils.encryptAES("휴면"));

		int createCustCnt = customerDao.createDormantCustomer(customerSearch);
		int updateCustCnt = customerDao.updateDormantCustomer(customerSearch);
		int createOrdCnt = customerDao.createDormantOrder(customerSearch);
		int updateOrdCnt = customerDao.updateDormantOrder(customerSearch);

		result.setInt("createCustCnt", createCustCnt);
		result.setInt("updateCustCnt", updateCustCnt);
		result.setInt("createOrdCnt", createOrdCnt);
		result.setInt("updateOrdCnt", updateOrdCnt);

		return result;
	}

	/**
	 * 탈퇴회원 삭제대상 목록
	 *
	 * @param customerSearch - 전환기간
	 * @return Collection<Customer>
	 * @author jsshin
	 * @since 2021. 03. 08
	 */
	public Collection<Customer> getExpireSecedeCustomerList(CustomerSearch customerSearch) {

		return customerDao.getExpireSecedeCustomerList(customerSearch);
	}

	/**
	 * 탈퇴처리
	 *
	 * @param customerCollection - 삭제대상 목록
	 * @return GagaMap - 결과정보
	 * @author jsshin
	 * @since 2021. 03. 08
	 */
	@Transactional("shopTxnManager")
	public GagaMap saveSecedeCustomer(Collection<Customer> customerCollection) {
		GagaMap result = new GagaMap();
		int succCnt = 0;
		int failCnt = 0;
		for (Customer customer : customerCollection) {
			Integer custNo = customer.getCustNo();
			try {
				coreCustomerService.deleteSecedeCustomer(custNo);
				succCnt++;
			} catch (Exception e) {
				failCnt++;
			}
		}
		result.setInt("succCnt", succCnt);
		result.setInt("failCnt", failCnt);
		return result;
	}

	/**
	 * 개인정보 이용내역 안내 대상목록
	 *
	 * @return Collection<Customer>
	 * @author jsshin
	 * @since 2021. 05. 06
	 */
	public Collection<Customer> getPrivacyPolicyNoticeTargetList(CustomerSearch customerSearch) {
		return customerDao.getPrivacyPolicyNoticeTargetList(customerSearch);
	}

	/**
	 * 개인정보 이용내역 안내 발송
	 *
	 * @param customerCollection - 대상
	 * @return GagaMap - 성공/실패 카운트
	 * @author jsshin
	 * @since 2021. 05. 06
	 */
	@Transactional("shopTxnManager")
	public GagaMap sendPrivacyPolicyNotice(Collection<Customer> customerCollection) {
		GagaMap result = new GagaMap();
		int succCnt = 0;
		int failCnt = 0;
		for (Customer customer : customerCollection) {
			try {
				Integer senderNo = TsbConstants.REG_NO;

				if (StringUtils.isNotBlank(customer.getEmail())) {
					mailService.sendPrivacyPolicyNotice(customer, senderNo);
				}

				if (StringUtils.isNotBlank(customer.getCellPhnno())) {
					kakaotalkService.sendPrivacyPolicyNotice(customer, senderNo);
				}

				succCnt++;

			} catch (Exception e) {
				log.error(e.getMessage());
				failCnt++;
			}
		}
		result.setInt("succCnt", succCnt);
		result.setInt("failCnt", failCnt);
		return result;
	}

	/**
	 * 마케팅 정보 수신동의 내역 안내 대상목록
	 *
	 * @return Collection<Customer>
	 * @author jsshin
	 * @since 2021. 05. 06
	 */
	public Collection<Customer> getMarketingAgreeNoticeTargetList(CustomerSearch customerSearch) {
		return customerDao.getMarketingAgreeNoticeTargetList(customerSearch);
	}

	/**
	 * 마케팅 정보 수신동의 내역 안내 발송
	 *
	 * @param customerCollection - 대상
	 * @return GagaMap - 성공/실패 카운트
	 * @author jsshin
	 * @since 2021. 05. 06
	 */
	@Transactional("shopTxnManager")
	public GagaMap sendMarketingAgreeNotice(Collection<Customer> customerCollection) {
		GagaMap result = new GagaMap();
		int succCnt = 0;
		int failCnt = 0;
		for (Customer customer : customerCollection) {
			try {
				Integer senderNo = TsbConstants.REG_NO;

				// 이메일 발송
				if (StringUtils.isNotBlank(customer.getEmail())) {
					mailService.sendMarketingAgreeNotice(customer, senderNo);
				}

				if (StringUtils.isNotBlank(customer.getCellPhnno())) {
					kakaotalkService.sendMarketingAgreeNotice(customer, senderNo);
				}

				succCnt++;

			} catch (Exception e) {
				log.error(e.getMessage());
				failCnt++;
			}
		}
		result.setInt("succCnt", succCnt);
		result.setInt("failCnt", failCnt);
		return result;
	}

	/**
	 * 회원등급 변경
	 *
	 * @param custGrade - 정보
	 * @return GagaMap - 성공/실패 카운트
	 * @author jsshin
	 * @since 2021. 05. 06
	 */
	@Transactional("shopTxnManager")
	public GagaMap saveCustomerGrade(CustGrade custGrade) {
		GagaMap result = new GagaMap();
		Collection<CustGrade> custGradeCollection = customerDao.getCustGradePolicyList(custGrade);
		int custGradeHstCnt = 0;

		// 1. 등급산정
		for (CustGrade grade : custGradeCollection) {
			grade.setSiteCd(custGrade.getSiteCd());
			grade.setRegNo(custGrade.getRegNo());
			custGradeHstCnt += customerDao.createChangeCustGradeHst(grade);
		}

		// 2. 회원이력 생성
		int custHstCnt = customerDao.createChangeCustomerHst(custGrade);

		// 3. 회원등급 변경
		int custGradeCnt = customerDao.updateCustomerGrade(custGrade);

		result.setInt("custGradeHstCnt", custGradeHstCnt);
		result.setInt("custHstCnt", custHstCnt);
		result.setInt("custGradeCnt", custGradeCnt);

		return result;
	}

	/**
	 * 회원등급 변경
	 *
	 * @param customerSearch - 정보
	 * @return Collection<Customer>
	 * @author jsshin
	 * @since 2021. 05. 06
	 */
	public Collection<Customer> getCustGradeChangeTargetList(CustomerSearch customerSearch) {
		return customerDao.getCustGradeChangeTargetList(customerSearch);
	}

	/**
	 * 넷퍼시메일솔루션으로 회원정보 생성
	 * @author gagamel
	 * @since 2021. 5. 10
	 */
	@Transactional("shopTxnManager")
	public void createNetpathyMailCustomer() {
		// 회원정보 Truncate
		customerDao.truncateNetpathyMailCustomer();

		// 회원정보 생성
		int result = customerDao.createNetpathyMailCustomer();

		log.info("1.넷퍼시메일솔루션으로 회원정보 생성 ({}건) : OK", result);
	}

	/**
	 * 넷퍼시메일솔루션으로 탈퇴/휴면회원정보 생성
	 * @author gagamel
	 * @since 2021. 5. 10
	 */
	@Transactional("shopTxnManager")
	public void createNetpathyMailWithdrawalCustomer() {
		// 회원정보 Truncate
		customerDao.truncateNetpathyMailWithdrawalCustomer();

		// 회원정보 생성
		int result = customerDao.createNetpathyMailWithdrawalCustomer();

		log.info("2.넷퍼시메일솔루션으로 탈퇴/휴면회원정보 생성 ({}건) : OK", result);
	}

	/**
	 * 넷퍼시메일솔루션으로 회원포인트정보 생성
	 * 		전일자 변경된 포인트가 있는 회원에 대해서만
	 * @author gagamel
	 * @since 2021. 5. 10
	 */
	@Transactional("shopTxnManager")
	public void createNetpathyMailCustomerPoint() {
		// 회원정보 Truncate
		customerDao.truncateNetpathyMailCustomerPoint();

		// 회원정보 생성
		int result = customerDao.createNetpathyMailCustomerPoint();

		log.info("3.넷퍼시메일솔루션으로 회원포인트정보 생성 ({}건) : OK", result);
	}

	/**
	 * 생일쿠폰안내대상 목록
	 *
	 * @param customerSearch - 사이트 코드
	 * @return Collection<Customer> - 목록
	 * @author jsshin
	 * @since  2021. 05. 10
	 */
	public Collection<CustCoupon> getBirthDayTargetList(CustomerSearch customerSearch) {
		return customerDao.getBirthDayTargetList(customerSearch);
	}


	/**
	 * 생일쿠폰 안내
	 *
	 * @param custCoupon - 쿠폰정보, 고객정보
	 * @author jsshin
	 * @since  2021. 05. 10
	 */
	@Transactional("shopTxnManager")
	public void sendBirthDayCouponNotice(CustCoupon custCoupon) {
		Integer senderNo = TsbConstants.REG_NO;
		// 이메일 발송
		if (StringUtils.isNotBlank(custCoupon.getEmail()) && "Y".equals(custCoupon.getEmailAgreeYn())) {
			mailService.sendBirthDayCouponNotice(custCoupon, senderNo);
		}
		// 카카오 알림톡
		if (StringUtils.isNotBlank(custCoupon.getCellPhnno()) && "Y".equals(custCoupon.getSmsAgreeYn())) {
			kakaotalkService.sendBirthDayCouponNotice(custCoupon, senderNo);
		}

	}

	/**
	 * 휴면/미접속자 대상 목록
	 *
	 * @param customerSearch - 사이트 코드
	 * @return Collection<Customer> - 목록
	 * @author jsshin
	 * @since  2021. 05. 10
	 */
	public Collection<Customer> getComBackNotiTarketList(CustomerSearch customerSearch) {
		return customerDao.getComBackNotiTarketList(customerSearch);
	}


	@Transactional("shopTxnManager")
	public void changeEncodingCustomerInfo() {
		Collection <Customer>  customerCollection = customerDao.getEncodingCustomer();
		for (Customer custInfo: customerCollection) {
				try {
					Customer params = new Customer();
					params.setCustNo(custInfo.getCustNo());
					params.setEncodedCustNm(CryptoUtils.newEncryptAES(custInfo.getCustNm()));
					params.setEncodedSexGb(CryptoUtils.newEncryptAES(custInfo.getSexGb()));
					params.setEncodedEmail(CryptoUtils.newEncryptAES(custInfo.getEmail()));
					params.setCellPhnno(CryptoUtils.newEncryptAES(custInfo.getCellPhnno()));
					params.setBirthYmd(CryptoUtils.newEncryptAES(custInfo.getBirthYmd()));
					params.setHomeZipcode(CryptoUtils.newEncryptAES(custInfo.getHomeZipcode()));
					params.setEncodedHomeBaseAddr(CryptoUtils.newEncryptAES(custInfo.getHomeBaseAddr()));
					params.setEncodedHomeDtlAddr(CryptoUtils.newEncryptAES(custInfo.getHomeDtlAddr()));
					customerDao.updateEncodingCustomer(params);
				} catch (Exception e) {
					log.error(e.getMessage());
					log.info("ERROR CUST_NO ====> {}", custInfo.getCustNo());

				}
		}
	}

	@Transactional("shopTxnManager")
	public void changeEncodingDormantCustomerInfo() {
		Collection <Customer> customerCollection = customerDao.getEncodingDormantCustomer();
		for (Customer custInfo: customerCollection) {
				try {
					Customer params = new Customer();
					params.setCustNo(custInfo.getCustNo());
					params.setEncodedCustNm(CryptoUtils.newEncryptAES(custInfo.getCustNm()));
					params.setEncodedSexGb(CryptoUtils.newEncryptAES(custInfo.getSexGb()));
					params.setEncodedEmail(CryptoUtils.newEncryptAES(custInfo.getEmail()));
					params.setCellPhnno(CryptoUtils.newEncryptAES(custInfo.getCellPhnno()));
					params.setBirthYmd(CryptoUtils.newEncryptAES(custInfo.getBirthYmd()));
					params.setHomeZipcode(CryptoUtils.newEncryptAES(custInfo.getHomeZipcode()));
					params.setEncodedHomeBaseAddr(CryptoUtils.newEncryptAES(custInfo.getHomeBaseAddr()));
					params.setEncodedHomeDtlAddr(CryptoUtils.newEncryptAES(custInfo.getHomeDtlAddr()));
					customerDao.updateEncodingDormantCustomer(params);
				} catch (Exception e) {
					log.error(e.getMessage());
					log.info("ERROR CUST_NO ====> {}", custInfo.getCustNo());

				}
		}
	}

	@Transactional("shopTxnManager")
	public void changeEncodingSecedeCustomerInfo() {
		Collection <Customer> customerCollection = customerDao.getEncodingSecedeCustomer();
		for (Customer custInfo: customerCollection) {
				try {
					Customer params = new Customer();
					params.setCustNo(custInfo.getCustNo());
					params.setEncodedCustNm(CryptoUtils.newEncryptAES(custInfo.getCustNm()));
					params.setEncodedSexGb(CryptoUtils.newEncryptAES(custInfo.getSexGb()));
					params.setEncodedEmail(CryptoUtils.newEncryptAES(custInfo.getEmail()));
					params.setCellPhnno(CryptoUtils.newEncryptAES(custInfo.getCellPhnno()));
					params.setBirthYmd(CryptoUtils.newEncryptAES(custInfo.getBirthYmd()));
					params.setHomeZipcode(CryptoUtils.newEncryptAES(custInfo.getHomeZipcode()));
					params.setEncodedHomeBaseAddr(CryptoUtils.newEncryptAES(custInfo.getHomeBaseAddr()));
					params.setEncodedHomeDtlAddr(CryptoUtils.newEncryptAES(custInfo.getHomeDtlAddr()));
					customerDao.updateEncodingSecedeCustomer(params);
				} catch (Exception e) {
					log.error(e.getMessage());
					log.info("ERROR CUST_NO ====> {}", custInfo.getCustNo());
				}
		}
	}

	@Transactional("shopTxnManager")
	public void changeEncodingCustAccount() {
		Collection <CustAccount> custAccountCollection = customerDao.getEncodingCustAccount();
		for (CustAccount custAccountInfo: custAccountCollection) {
				try {
					CustAccount params = new CustAccount();
					params.setCustNo(custAccountInfo.getCustNo());
					params.setEncodedAccountNo(CryptoUtils.newEncryptAES(custAccountInfo.getAccountNo()));
				} catch (Exception e) {
					log.error(e.getMessage());
					log.info("ERROR CUST_NO ====> {}", custAccountInfo.getCustNo());
				}
		}
	}


}
