package com.style24.core.biz.service;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.style24.core.biz.dao.TscCouponDao;
import com.style24.core.support.env.TscConstants;
import com.style24.core.support.message.TscMessageByLocale;
import com.style24.persistence.domain.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Random;

/**
 * 쿠폰 Service
 *
 * @author bin2107
 * @since 2021. 02. 09
 */
@Service
@Slf4j
public class TscCouponService {
    @Autowired
    private TscMessageByLocale message;

    @Autowired
    private TscCouponDao couponDao;

    /**
     * 쿠폰 리스트 조회
     * @param  param
     * @return ArrayList<Coupon>
     * @author xyzp1539
     * @since 2020-12-22
     */
    public ArrayList<Coupon> getCouponList(Coupon param) {
        return couponDao.getCouponList(param);
    }

    /**
     * 쿠폰리스트 카운트 조회
     * @param  param
     * @return int
     * @author xyzp1539
     * @since 2020-12-22
     */
    public int getCouponListCnt(Coupon param) {
        return couponDao.getCouponListCnt(param);
    }

    /**
     * 쿠폰 발급 개수 조회
     * @param  cpnId
     * @return  cnt
     * @author xyzp1539
     * @since 2021-01-15
     */
    public int getCouponIssueCnt(Integer cpnId) {
        return couponDao.getCouponIssueCnt(cpnId);
    }

    /**
     * 쿠폰 상세 조회
     * @param  cpnId
     * @return Coupon
     * @author xyzp1539
     * @since 2021-01-15
     */
    public Coupon getCouponDetail(Integer cpnId) { return couponDao.getCouponDetail(cpnId);}

    /**
     * 쿠폰 적용 대상 - 공급처
     * @param cpnId
     * @return Coupon
     * @author xyzp1539
     * @since 2021-01-18
     */
    public ArrayList<CouponRefval> getCouponRefvalSupplyCompList(Integer cpnId) {
        CouponRefval cpnRefval = new CouponRefval();
        cpnRefval.setCpnId(cpnId);
        cpnRefval.setCpnTarget("G260_13");
        return couponDao.getCouponRefvalSupplyCompList(cpnRefval);
    }

    /**
     * 쿠폰 적용 대상 - 적용상품
     * @param  cpnId
     * @return Coupon
     * @author xyzp1539
     * @since 2021-01-18
     */
    public ArrayList<CouponRefval> getCouponRefvalGoodsList(Integer cpnId , String cpnTarget) {
        CouponRefval cpnRefval = new CouponRefval();
        cpnRefval.setCpnId(cpnId);
        cpnRefval.setCpnTarget(cpnTarget);
        return couponDao.getCouponRefvalGoodsList(cpnRefval);
    }

    /**
     * 쿠폰 적용 대상 - 카테고리
     * @param cpnId
     * @return Coupon
     * @author xyzp1539
     * @since 2021-01-18
     */
    public ArrayList<CouponRefval> getCouponRefvalCategoryList(Integer cpnId) {
        CouponRefval cpnRefval = new CouponRefval();
        cpnRefval.setCpnId(cpnId);
        cpnRefval.setCpnTarget("G260_11");
        return couponDao.getCouponRefvalCategoryList(cpnRefval);
    }

    /**
     * 쿠폰 적용 대상 - 브랜드
     * @param cpnId
     * @return Coupon
     * @author xyzp1539
     * @since 2021-01-18
     */
    public ArrayList<CouponRefval> getCouponRefvalBrandList(Integer cpnId ) {
        CouponRefval cpnRefval = new CouponRefval();
        cpnRefval.setCpnId(cpnId);
        cpnRefval.setCpnTarget("G260_12");
        return couponDao.getCouponRefvalBrandList(cpnRefval);
    }

    /**
     * 쿠폰 적용 대상 - 제외상품
     * @param  cpnId
     * @return Coupon
     * @author xyzp1539
     * @since 2021-01-18
     */
    public ArrayList<CouponRefval> getCouponRefvalExceptGoodsList(Integer cpnId ) {
        CouponRefval cpnRefval = new CouponRefval();
        cpnRefval.setCpnId(cpnId);
        cpnRefval.setCpnTarget("G260_14");
        return couponDao.getCouponRefvalExceptGoodsList(cpnRefval);
    }

    /**
     * 쿠폰 입점업체 분담율 조회
     * @param
     * @return
     * @author xyzp1539
     * @since 2021-01-18
     */
    public ArrayList<Coupon> getCouponBurdenList(Integer cpnId) {
        return couponDao.getCouponBurdenList(cpnId);
    }

    /**
     * 랜덤쿠폰 생성 리스트 조회
     * @param
     * @return
     * @author xodud1202
     * @since 2021-01-26
     */
    public ArrayList<CustCoupon> getRandomCouponInfo(Integer cpnId) {
        return couponDao.getRandomCouponInfo(cpnId);
    }

    /**
     * 쿠폰사용가능고객구분 조회
     * @param
     * @return
     * @author bin2107
     * @since 2021-02-02
     */
    public ArrayList<Coupon> getCouponCustGbList(Integer cpnId) {
        return couponDao.getCouponCustGbList(cpnId);
    }

    /**
     * 쿠폰사용가능고객등급 조회
     * @param
     * @return
     * @author bin2107
     * @since 2021-02-02
     */
    public ArrayList<Coupon> getCouponCustGradeList(Integer cpnId) {
        return couponDao.getCouponCustGradeList(cpnId);
    }

    /**
     * 쿠폰사용가능결제수단 조회
     * @param
     * @return
     * @author bin2107
     * @since 2021-02-02
     */
    public ArrayList<Coupon> getCouponPayTypeList(int cpnId) {
        return couponDao.getCouponPayTypeList(cpnId);
    }

    /**
     * 선착순쿠폰 조회
     * @param
     * @return
     * @author bin2107
     * @since 2021-02-05
     */
    public ArrayList<Coupon> getLimitedTimeCouponList(int cpnId) {
        return couponDao.getLimitedTimeCouponList(cpnId);
    }

    /**
     * 쿠폰 제휴채널 조회
     * @param
     * @return
     * @author bin2107
     * @since 2021-04-22
     */
    public ArrayList<Coupon> getCouponAfChannelList(int cpnId) {
        return couponDao.getCouponAfChannelList(cpnId);
    }
    
    /**
     * 공급업체목록으로 브랜정보목록 조회
     * @param
     * @return
     * @author jsh77b
     * @since 2021-08-23
     */
    public ArrayList<Coupon> getSupplyCompCdAndBrandCdList(Coupon coupon) {
        return couponDao.getSupplyCompCdAndBrandCdList(coupon);
    }
    
    /**
     * 브랜드목록으로 공급업체정보목록 조회
     * @param
     * @return
     * @author jsh77b
     * @since 2021-08-23
     */
    public ArrayList<Coupon> getBrandCdAndSupplyCompList(Coupon coupon) {
        return couponDao.getBrandCdAndSupplyCompList(coupon);
    }

    /**
     * 쿠폰 저장
     * @param params
     * @author xyzp1539
     * @since  2021-01-11
     */
    @Transactional("shopTxnManager")
    public String saveCoupon(Coupon params){
//        int cpnId = params.getCpnId();		// 쿠폰ID (신규생성인지 수정인지 구분하기 위해 params의 cpnId를 먼저 가져옴 > 쿠폰 생성시 cpnId를 저장하기때문임)

        if("U".equals(params.getMode())) {    //수정모드일때
            couponDao.updateCouponMstInfo(params);	// 쿠폰 마스터 수정
            couponDao.deleteCouponCustGubun(params);	// 쿠폰 회원 구분 수정
            couponDao.deleteCouponCustGrade(params);	// 쿠폰 회원 등급 수정
            couponDao.deleteCouponPayType(params);	// 쿠폰 결제 수단 수정
            couponDao.deleteCouponRefVal(params);	// 공급업체,브랜드,카테고리,상품 삭제
            couponDao.deleteCouponBurden(params);	// 입점업체 분담율 삭제
            couponDao.deleteLimitedTimeCoupon(params);	// 선착순 쿠폰 삭제
            couponDao.deleteCouponAfChannel(params);	// 제휴링크 삭제
        }else{	//등록모드일때
            params.setCpnStat("G232_10");
            couponDao.couponInsert(params);
        }

        for(int i=0; i<params.getUsableCustGbArr().length; i++){
            params.setUsableCustGb(params.getUsableCustGbArr()[i]);
            couponDao.createCouponCustGubun(params);
        }

        for(int i=0; i<params.getUsableCustGradeArr().length; i++){
            params.setUsableCustGrade(params.getUsableCustGradeArr()[i]);
            couponDao.createCouponCustGrade(params);
        }

        for(int i=0; i<params.getPayTypeArr().length; i++){
            params.setPayType(params.getPayTypeArr()[i]);
            couponDao.createCouponPayType(params);
        }

        // 공급업체 등록
        for(CouponRefval compRefval : params.getSupplyCompList()){
            compRefval.setCpnId(params.getCpnId());
            compRefval.setCpnTarget("G260_13");
            compRefval.setRefVal(compRefval.getSupplyCompCd());
            compRefval.setCpnType(params.getCpnType());
            compRefval.setRegNo(params.getRegNo());
            compRefval.setUpdNo(params.getUpdNo());
            couponDao.saveCouponRefVal(compRefval);
        }

        // 브랜드 등록
        for(CouponRefval brandRefval : params.getBrandList()){
            brandRefval.setCpnId(params.getCpnId());
            brandRefval.setCpnTarget("G260_12");
            brandRefval.setRefVal(brandRefval.getBrandCd());
            brandRefval.setCpnType(params.getCpnType());
            brandRefval.setRegNo(params.getRegNo());
            brandRefval.setUpdNo(params.getUpdNo());
            couponDao.saveCouponRefVal(brandRefval);
        }

        // 적용상품
        for(CouponRefval applyGoodsRefval : params.getApplyGoodsList()){
            applyGoodsRefval.setCpnId(params.getCpnId());
            applyGoodsRefval.setCpnTarget("G260_10");
            applyGoodsRefval.setRefVal(applyGoodsRefval.getGoodsCd());
            applyGoodsRefval.setCpnType(params.getCpnType());
            applyGoodsRefval.setRegNo(params.getRegNo());
            applyGoodsRefval.setUpdNo(params.getUpdNo());
            couponDao.saveCouponRefVal(applyGoodsRefval);
        }

        // 카테고리
        for(CouponRefval cateRefval : params.getCateList()){
            cateRefval.setCpnId(params.getCpnId());
            cateRefval.setCpnTarget("G260_11");
            cateRefval.setRefVal(cateRefval.getCateNo());
            cateRefval.setFormalGb(cateRefval.getFormalGb());
            cateRefval.setBrandCd(cateRefval.getBrandCd());
            cateRefval.setCpnType(params.getCpnType());
            cateRefval.setRegNo(params.getRegNo());
            cateRefval.setUpdNo(params.getUpdNo());
            couponDao.saveCouponRefVal(cateRefval);
        }

        // 제외상품
        for(CouponRefval exceptGoodsRefval : params.getExceptGoodsList()){
            exceptGoodsRefval.setCpnId(params.getCpnId());
            exceptGoodsRefval.setCpnTarget("G260_14");
            exceptGoodsRefval.setRefVal(exceptGoodsRefval.getGoodsCd());
            exceptGoodsRefval.setCpnType(params.getCpnType());
            exceptGoodsRefval.setRegNo(params.getRegNo());
            exceptGoodsRefval.setUpdNo(params.getUpdNo());
            couponDao.saveCouponRefVal(exceptGoodsRefval);
        }

        // 입점업체분담율
        log.info("CouponAfChannel params getBurdenList{}",params.getBurdenList());
        for(CouponBurden couponBurden : params.getBurdenList()){
            couponBurden.setCpnId(params.getCpnId());
            couponBurden.setRegNo(params.getRegNo());
            couponBurden.setUpdNo(params.getUpdNo());
            couponDao.saveCouponBurden(couponBurden);
        }
        
        if (!params.getScmYn().equals("Y")) {
            // 선착순쿠폰
        	if (params.getLimitedTimeCpnList() != null && params.getLimitedTimeCpnList().size() > 0) {
	            for(CouponLimitedTime couponLimitedTime : params.getLimitedTimeCpnList()){
	                couponLimitedTime.setCpnId(params.getCpnId());
	                couponLimitedTime.setRegNo(params.getRegNo());
	                couponLimitedTime.setUpdNo(params.getUpdNo());
	                couponLimitedTime.setDownStdt(couponLimitedTime.getDownStDate().replaceAll("-", "")+couponLimitedTime.getDownStTime().replaceAll(":",""));
	                couponLimitedTime.setDownEddt(couponLimitedTime.getDownEdDate().replaceAll("-", "")+couponLimitedTime.getDownEdTime().replaceAll(":",""));
	                couponDao.createLimitedTimeCoupon(couponLimitedTime);
	            }
        	}
            
            // 쿠폰제휴링크
        	if (params.getAfChannelList() != null && params.getAfChannelList().size() > 0) {
	            for(CouponAfChannel couponAfChannel : params.getAfChannelList()){
	                couponAfChannel.setCpnId(params.getCpnId());
	                couponAfChannel.setRegNo(params.getRegNo());
	                log.info("CouponAfChannel  couponAfChannel{}",couponAfChannel);
	                couponDao.createCouponAfChannel(couponAfChannel);
	            }
        	}
        }

        // 수정모드이고 변경된 쿠폰상태가 대기 , 중지 인경우 고객이 발급받은 내용도 변경
        if(params.getMode().equals("U") &&
                (params.getCpnStat().equals("G232_10") || params.getCpnStat().equals("G232_12")) ) {

            CustCoupon custCoupon = new CustCoupon();
            custCoupon.setCpnId(params.getCpnId());
            custCoupon.setUseYn("Y");
            ArrayList<CustCoupon> custList = couponDao.getCouponIssueCustList(custCoupon);

            if(custList != null && custList.size() > 0 ) {
                for(CustCoupon issueCust : custList) {
                    issueCust.setAvailEddt(params.getAvailEddt());
                    issueCust.setUpdNo(params.getUpdNo());

                    couponDao.updateCustCouponAvailEddt(issueCust);
                }
            }
        }

        // 시리얼 쿠폰 생성(최초 쿠폰 생성일 경우에만)
        if(params.getMode().equals("N") && params.getCpnType().equals(TscConstants.CpnType.PAY_CPN.value()) && params.getDcCdGb().equals(TscConstants.DcCdGb.SERIAL.value())) {
            // 시리얼 쿠폰명이 동일한 쿠폰이 일정 겹치는 부분이 있는지 확인
            int overlapCheck = couponDao.getSerialOverlapCheck(params);
            if(overlapCheck < 1) {
                for(int i = 0 ; i < params.getTotPubLimitQty() ; i++) {
                    couponDao.createRandomCouponInfo(params);
                }
            } else {
                throw new IllegalStateException("같은 시리얼명이 사용되는 쿠폰이 중복됩니다. 기간을 확인해주세요.");
            }
        } else if(params.getMode().equals("N") && params.getCpnType().equals(TscConstants.CpnType.PAY_CPN.value()) && params.getDcCdGb().equals(TscConstants.DcCdGb.RANDOM.value())) {
            Random random = new Random();
            String prefixRandomCpn = "" + params.getCpnId();		// 랜덤 번호는 쿠폰번호 + 랜덤문자 = 12로 처리함
            // 랜덤 문자 발급 수 만큼 진행
            for(int j = 0 ; j < params.getTotPubLimitQty() ; j++) {
                boolean chk = true;
                while (chk) {
                    // 대문자+소문자+숫자 조합 10자리 인증번호 생성
                    StringBuilder sb = new StringBuilder();
                    // 쿠폰번호 + 랜덤글자 = 12 글자만큼 생성
                    for (int i = 0; i < 12 - prefixRandomCpn.length(); i++) {
                        int index = random.nextInt(2);
                        switch (index) {
                            case 0:
                                sb.append((char) (random.nextInt(26) + 65));
                                break;
                            case 1:
                                sb.append(random.nextInt(10));
                                break;
                        }
                    }

                    // 인증번호 중복 체크
                    int cnt = couponDao.getRandomCouponNmCnt(sb.toString());

                    if (cnt == 0) {
                        // 인증번호 설정
                        params.setRdCpnNm(sb.substring(0, 4) + params.getCpnId() + sb.substring(4));
                        couponDao.createRandomCouponInfo(params);
                        chk = false;
                    }
                }
            }
        }

        return "SUCCESS";
    }

    /**
     * 쿠폰 적용대상 삭제
     * @param   couponRefval
     * @return
     * @author xyzp1539
     * @since 2021-01-19
     */
    @Transactional("shopTxnManager")
    public void updateCouponRefval(CouponRefval couponRefval) {
        couponDao.updateCouponRefval(couponRefval);
    }

    /**
     * 고객 쿠폰
     * @param
     * @return
     * @author xyzp1539
     * @since 2021-01-21
     */
    @Transactional("shopTxnManager")
    public void saveCouponCustPub(CustCoupon custCoupon) {
        Gson gson = new Gson();

        Collection<CustCoupon> custPubList = gson.fromJson(custCoupon.getCustList() , new TypeToken<Collection<CustCoupon>>(){}.getType());
        for(CustCoupon custPub : custPubList ) {
            custPub.setCpnId(custCoupon.getCpnId());
            custPub.setAvailStdt(custCoupon.getAvailStdt());
            custPub.setAvailEddt(custCoupon.getAvailEddt());
            custPub.setPubReason(custCoupon.getPubReason());
            custPub.setPubReasonDtl(custCoupon.getPubReasonDtl());
            custPub.setEndAlimSendYn(custCoupon.getEndAlimSendYn());
            custPub.setRegNo(custCoupon.getRegNo());
            custPub.setUpdNo(custCoupon.getUpdNo());

            couponDao.saveCouponCustPub(custPub);
        }
    }

    /**
     * 쿠폰발급받은 회원리스트 팝업
     * @param
     * @return
     * @author bin2107
     * @since 2021-02-03
     */
    public Collection<Coupon> getCpnPubCustList(int cpnId) {
        return couponDao.getCpnPubCustList(cpnId);
    }

    /**
     * 선착순쿠폰 삭제
     *
     * @param
     * @return
     * @author bin2107
     * @since 2021. 2. 5
     */
    @Transactional("shopTxnManager")
    public void updateLimitedTimeCouponList(CouponLimitedTime couponLimitedTime) {
        if (couponLimitedTime == null || (couponLimitedTime.getArrLimitCpnId() == null && couponLimitedTime.getArrLimitCpnId().length <= 0)) {
            throw new IllegalStateException(message.getMessage("FAIL_1001"));
        }

        if (couponLimitedTime.getArrLimitCpnId().length > 0) {
            couponDao.updateLimitedTimeCouponList(couponLimitedTime);
        }
    }

    /**
     * 쿠폰 상태 변경
     * @param
     * @author bin2107
     * @since 2021. 2. 5
     */
    @Transactional("shopTxnManager")
    public void updateCouponStat(Coupon coupon) {
        couponDao.updateCouponStat(coupon);
    }

    /**
     * 쿠폰조회 목록
     * @param coupon - 쿠폰 정보
     * @return
     * @author gagamel
     * @since 2021. 1. 8
     */
    public Collection<Coupon> getCouponRetrieveList(Coupon coupon) {
        return couponDao.getCouponRetrieveList(coupon);
    }

    /**
     * 쿠폰발급
     *
     * @param coupon - 쿠폰정보
     * @author jsshin
     * @since 2021. 1. 29
     */
    @Transactional("shopTxnManager")
    public void saveCouponIssue(CustCoupon coupon) {
        couponDao.saveCouponCustPub(coupon);
    }

    /**
     * 쿠폰지급 - pdGb 별 쿠폰 지급
     * @param coupon - 쿠폰정보
     * @author jsshin
     * @since 2021. 04. 15
     */
    @Transactional("shopTxnManager")
    public int createCustCoupon(CustCoupon coupon) {
        return couponDao.createCustCoupon(coupon);
    }

    /**
     * 랜덤 쿠폰 지급
     * @param coupon - 쿠폰정보
     * @author jsshin
     * @since 2021. 1. 29
     */
    public void updateGiveRandomCoupon(CustCoupon coupon) {
        couponDao.updateGiveRandomCoupon(coupon);
    }
}
