package kr.co.uplus.ez.api.sendNumMgt;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

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

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.spring.SqlSessionTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import kr.co.uplus.ez.api.comm.CommService;
import kr.co.uplus.ez.api.custMgt.CustMgtService;
import kr.co.uplus.ez.api.custMgt.dto.InsertUserResDto;
import kr.co.uplus.ez.api.sendNumMgt.dto.DeleteNumberReqDto;
import kr.co.uplus.ez.api.sendNumMgt.dto.DeleteNumberResDto;
import kr.co.uplus.ez.api.sendNumMgt.dto.DetailNumber;
import kr.co.uplus.ez.api.sendNumMgt.dto.DetailNumberReqDto;
import kr.co.uplus.ez.api.sendNumMgt.dto.DetailNumberResDto;
import kr.co.uplus.ez.api.sendNumMgt.dto.InsertNumber;
import kr.co.uplus.ez.api.sendNumMgt.dto.InsertNumberFile;
import kr.co.uplus.ez.api.sendNumMgt.dto.InsertNumberReqDto;
import kr.co.uplus.ez.api.sendNumMgt.dto.InsertNumberRes;
import kr.co.uplus.ez.api.sendNumMgt.dto.InsertNumberResDto;
import kr.co.uplus.ez.api.sendNumMgt.dto.ProfileInfo;
import kr.co.uplus.ez.api.sendNumMgt.dto.ProfileListReqDto;
import kr.co.uplus.ez.api.sendNumMgt.dto.ProfileListRes;
import kr.co.uplus.ez.api.sendNumMgt.dto.ProfileListResDto;
import kr.co.uplus.ez.api.sendNumMgt.dto.SendAdminInfo;
import kr.co.uplus.ez.api.sendNumMgt.dto.SendAdminListReqDto;
import kr.co.uplus.ez.api.sendNumMgt.dto.SendAdminListRes;
import kr.co.uplus.ez.api.sendNumMgt.dto.SendAdminListResDto;
import kr.co.uplus.ez.api.sendNumMgt.dto.SendNumberApprDetailReqDto;
import kr.co.uplus.ez.api.sendNumMgt.dto.SendNumberApprDetailRes;
import kr.co.uplus.ez.api.sendNumMgt.dto.SendNumberApprDetailResDto;
import kr.co.uplus.ez.api.sendNumMgt.dto.SendNumberApprDoc;
import kr.co.uplus.ez.api.sendNumMgt.dto.SendNumberApprInfo;
import kr.co.uplus.ez.api.sendNumMgt.dto.SendNumberApprListReqDto;
import kr.co.uplus.ez.api.sendNumMgt.dto.SendNumberApprListRes;
import kr.co.uplus.ez.api.sendNumMgt.dto.SendNumberApprListResDto;
import kr.co.uplus.ez.api.sendNumMgt.dto.SendNumberApprNum;
import kr.co.uplus.ez.api.sendNumMgt.dto.SendNumberInfo;
import kr.co.uplus.ez.api.sendNumMgt.dto.SendNumberListReqDto;
import kr.co.uplus.ez.api.sendNumMgt.dto.SendNumberListRes;
import kr.co.uplus.ez.api.sendNumMgt.dto.SendNumberListResDto;
import kr.co.uplus.ez.api.sendNumMgt.dto.UpdateApprReqDto;
import kr.co.uplus.ez.api.sendNumMgt.dto.UpdateApprResDto;
import kr.co.uplus.ez.api.sendNumMgt.dto.UpdateApprSendNumber;
import kr.co.uplus.ez.common.components.HubeasyApiComponents;
import kr.co.uplus.ez.common.data.ApiResponseCode;
import kr.co.uplus.ez.common.data.Const;
import kr.co.uplus.ez.common.data.Paging;
import kr.co.uplus.ez.common.utils.CommonUtils;
import kr.co.uplus.ez.common.utils.DateUtil;
import kr.co.uplus.ez.common.utils.DateUtils;
import kr.co.uplus.ez.common.utils.FileIoUtils;
import kr.co.uplus.ez.common.utils.FileUtil;

@Service
public class SendNumMgtService {
	
	private static final Logger logger = LoggerFactory.getLogger(SendNumMgtService.class);

	@Autowired
	@Qualifier("sqlSessionTemplateDb1")
	private SqlSessionTemplate sqlSessionMaster;

	@Autowired
	@Qualifier("sqlSessionTemplateDb2")
	private SqlSessionTemplate sqlSessionSlave;
	
	@Autowired
    private HubeasyApiComponents hubeasyApi;

	@Value("${file-resource.info.sendNumber.path:/efs/admin/sendNumber/}")
	private String sendNumUploadPath;
	
    @Value("${msghubez.applicationId:EZ_ADMIN}")
    private String apiApplicationId;
    
    @Value("${mail.senrNoRejTempleteCode:E0007}")
    private String senrNoRejTempleteCode;
    
    @Value("${msghubez.homepage-url:https://mhez.uplus.co.kr}")
    private String mailTempleteHomeUrl;
    
    @Value("${mail.from:msghubez@lguplus.co.kr}")
    private String fromEmail;

	private static int BUFFERSIZE = 1024;
	
	@Autowired
    private CommService commService;
	
	
	/**
	 * date : 2022. 4. 25.
	 * auth : ckr
	 * desc : 발신 프로필 목록 조회
	 * @param profileListReqDto
	 * @return
	 */
	public ProfileListResDto profileList(ProfileListReqDto profileListReqDto) {
		SendNumMgtMapper sendNumMgtMapper = sqlSessionSlave.getMapper(SendNumMgtMapper.class);
		String nowPage = String.valueOf(profileListReqDto.getPage());
		int totalCnt = sendNumMgtMapper.selectProfileTotalCnt(profileListReqDto);

		if(totalCnt == 0) {
			ProfileListRes profileListRes = new ProfileListRes();
			profileListRes.setList(new ArrayList<>());

			Paging paging = new Paging();
			paging.setPage(nowPage);
			paging.setTotalCnt(String.valueOf(totalCnt));
			profileListRes.setPaging(paging);

			return new ProfileListResDto(ApiResponseCode.CM_NOT_FOUND, profileListRes);
		}

		int page = profileListReqDto.getPage();
		int pagePerRows = profileListReqDto.getPagePerRows();
		page = (page - 1) * pagePerRows;
		profileListReqDto.setPage(page);

		List<ProfileInfo> profileInfos = sendNumMgtMapper.selectProfileList(profileListReqDto);

		ProfileListRes profileListRes = new ProfileListRes();
		profileListRes.setList(profileInfos);

		Paging paging = new Paging();
		paging.setPage(nowPage);
		paging.setTotalCnt(String.valueOf(totalCnt));
		profileListRes.setPaging(paging);

		return new ProfileListResDto(ApiResponseCode.SUCCESS, profileListRes);


	}

	/**
	 * date : 2022. 4. 25.
	 * auth : ckr
	 * desc : 문자 발신 번호 목록 조회
	 * @param sendNumberListReqDto
	 * @return
	 */
	public SendNumberListResDto numberList(SendNumberListReqDto sendNumberListReqDto) {
		SendNumMgtMapper sendNumMgtMapper = sqlSessionSlave.getMapper(SendNumMgtMapper.class);
		String nowPage = String.valueOf(sendNumberListReqDto.getPage());
		int totalCnt = sendNumMgtMapper.selectSendNumberTotalCnt(sendNumberListReqDto);

		if(totalCnt == 0) {

			SendNumberListRes sendNumberListRes = new SendNumberListRes();
			sendNumberListRes.setList(new ArrayList<>());

			Paging paging = new Paging();
			paging.setPage(nowPage);
			paging.setTotalCnt(String.valueOf(totalCnt));
			sendNumberListRes.setPaging(paging);
			return new SendNumberListResDto(ApiResponseCode.CM_NOT_FOUND, sendNumberListRes);
		}

		int page = sendNumberListReqDto.getPage();
		int pagePerRows = sendNumberListReqDto.getPagePerRows();
		page = (page - 1) * pagePerRows;
		sendNumberListReqDto.setPage(page);

		List<SendNumberInfo> sendNumberInfos = sendNumMgtMapper.selectSendNumberList(sendNumberListReqDto);

		SendNumberListRes sendNumberListRes = new SendNumberListRes();
		sendNumberListRes.setList(sendNumberInfos);

		Paging paging = new Paging();
		paging.setPage(nowPage);
		paging.setTotalCnt(String.valueOf(totalCnt));
		sendNumberListRes.setPaging(paging);

		return new SendNumberListResDto(ApiResponseCode.SUCCESS, sendNumberListRes);
	}

	/**
	 * date : 2022. 4. 25.
	 * auth : ckr
	 * desc : 문자 발신 번호 삭제
	 * @param deleteNumberReqDto
	 * @return
	 */
	public DeleteNumberResDto deleteNumber(DeleteNumberReqDto deleteNumberReqDto) {

		SendNumMgtMapper sendNumMgtMapper = sqlSessionSlave.getMapper(SendNumMgtMapper.class);

		try {
			sendNumMgtMapper.deleteNumber(deleteNumberReqDto);
		} catch (Exception e) {
			return new DeleteNumberResDto(ApiResponseCode.CM_DB_QUERY_ERR);
		}

		return new DeleteNumberResDto(ApiResponseCode.SUCCESS);
	}

	/**
	 * date : 2022. 4. 25.
	 * auth : ckr
	 * desc : 문자 발신 번호 등록
	 * @param insertNumberReqDto
	 * @return
	 */
	@Transactional(value="db1TransactionManager")
	public InsertNumberResDto insertNumber(InsertNumberReqDto insertNumberReqDto, MultipartHttpServletRequest multipartRequest) {

		
		
		Iterator fileNameIter = multipartRequest.getFileNames(); 
		while (fileNameIter.hasNext()) {
	    String key = (String)fileNameIter.next();
	    logger.debug("key={}",key);
		}

		SendNumMgtMapper sendNumMgtMapper = sqlSessionMaster.getMapper(SendNumMgtMapper.class);

		String adminId = insertNumberReqDto.getAdminId();
		Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		UserDetails userDetails = (UserDetails) principal;
		String regId = userDetails.getUsername();

		// 2. 중복 발신번호 체크를 위한 조회.
		List<InsertNumber> dbSendNumbers = null;
		List<InsertNumber> sendNumbers = insertNumberReqDto.getList();
		List<InsertNumber> allSendNumbers = insertNumberReqDto.getList();
		List<InsertNumber> duplicateSendNumList = new ArrayList<>();
		
		String nmineeDivCd = insertNumberReqDto.getNmineeDivCd();
		if(StringUtils.equals(nmineeDivCd, "01")) {
			// 사업자 - 발신 번호 전체 중복 체크
			dbSendNumbers = sendNumMgtMapper.selectSndrnoListAll(insertNumberReqDto);
		}else {
			// 타사업자 - 해당 사업자 발신 번호 한해서만 중복 체크
			dbSendNumbers = sendNumMgtMapper.selectSndrnoList(insertNumberReqDto);
		}
//		List<InsertNumber> dbSendNumbers = sendNumMgtMapper.selectSndrnoList(insertNumberReqDto);
//		List<InsertNumber> sendNumbers = insertNumberReqDto.getList();

//		List<InsertNumber> allSendNumbers = insertNumberReqDto.getList();
//		List<InsertNumber> duplicateSendNumList = new ArrayList<>();
		for (int i=0; i<dbSendNumbers.size(); i++){
			for (int j=0; j<sendNumbers.size(); j++){
				String dbSendNum = dbSendNumbers.get(i).getSendNum();
				String getSendNum = sendNumbers.get(j).getSendNum();
				if(StringUtils.equals(dbSendNum, getSendNum)){
//					sendNumbers.remove(j);
					allSendNumbers.remove(j);
					InsertNumber insertNumber = new InsertNumber();
					insertNumber.setSendNum(getSendNum);
					duplicateSendNumList.add(insertNumber);
				}
			}
		}

		if(allSendNumbers.size() == 0){
			InsertNumberRes insertNumberRes = new InsertNumberRes();
			if(duplicateSendNumList.size() > 0){
				// 발신번호 중복건 응답 처리.
				insertNumberRes.setList(duplicateSendNumList);
			}
			return new InsertNumberResDto(ApiResponseCode.CE_SENDMGT_DUPLICATE_SENDNUM, insertNumberRes);
		}

		// 1. 발신번호 SEQ 채번
		String regReqNo = sendNumMgtMapper.selectRegReqNo();
		String userSeq = sendNumMgtMapper.selectUserSeqByAdminId(adminId);
		try {
			Date now = new Date();
			String nowDate = DateUtils.dateToStr(now, "yyyyMMddHHmmss");
			insertNumberReqDto.setUserSeq(userSeq);
			insertNumberReqDto.setReqCnt(insertNumberReqDto.getList().size());
			insertNumberReqDto.setRegId(regId);
			insertNumberReqDto.setRegReqNo(regReqNo);
			insertNumberReqDto.setApvCnt(insertNumberReqDto.getList().size()); 		// 승인 건수
			insertNumberReqDto.setRejtCnt(0); 										// 반려 건수
			insertNumberReqDto.setReqSttusCd(Const.SNDRNO_REQ_STTUS_CD_COMPLETED);  // 요청 상태 코드(01:승인대기, 02:처리완료)
			insertNumberReqDto.setCmpltDt(nowDate); 								// 완료일시

			//	2. 발신번호등록 테이블 저장. (EZ_SNDRNO_REG)
			sendNumMgtMapper.insertNumber(insertNumberReqDto);
			logger.debug("발신번호 저장 성공");

			String yyyyMMdd = DateUtils.date2strYMD();
			// Path : efs/admin/sendNumDoc/yyyy/mm/
			String path = sendNumUploadPath + yyyyMMdd.substring(0, 4) + File.separator + yyyyMMdd.substring(4, 6);
			File dir = new File(path);
			if(!dir.isDirectory()) {
				dir.mkdirs();
			}

			for (InsertNumber dbInsertNumber : allSendNumbers){
				if(StringUtils.isNotBlank(dbInsertNumber.getSendNum())){
					dbInsertNumber.setCustSeq(insertNumberReqDto.getCustSeq());
					dbInsertNumber.setRegReqNo(regReqNo);
					dbInsertNumber.setNmineeDivCd(insertNumberReqDto.getNmineeDivCd());
					dbInsertNumber.setInchDivCd(Const.INCH_DIV_CD_ADM);
					if(StringUtils.equals(Const.COMM_YES, insertNumberReqDto.getBizrAuthYn())){
						dbInsertNumber.setNmineeDivCd(Const.NMINEE_DIV_CD);
					}else{
						dbInsertNumber.setNmineeDivCd(insertNumberReqDto.getNmineeDivCd());
					}
					dbInsertNumber.setRegId(regId);
					sendNumMgtMapper.insertNumberList(dbInsertNumber);
				}
			}

			// 사업자 인증 여부 Y
			if(allSendNumbers.size() > 0) {
				UpdateApprReqDto updateApprReqDto = new UpdateApprReqDto();
				updateApprReqDto.setAdminId(adminId);
				sendNumMgtMapper.updateSvcUser(updateApprReqDto);
			}

			// 사업자 인증이 안된 경우 파일업로드...

			// 4. 발신번호 등록 서류 테이블 저장. (EZ_SNDRNO_DOC)
			// DOC_NO 채번.

			List<MultipartFile> multipartFiles = new ArrayList<>();
			List<String> docTpCd = new ArrayList<>();
			if(StringUtils.equals(Const.SNDRNO_TP_CD_SELF, insertNumberReqDto.getNmineeDivCd())) {
				// 사업자등록증 '06'
				if(multipartRequest.getFile("businessFile") != null) {
					MultipartFile businessFile = multipartRequest.getFile("businessFile");
					multipartFiles.add(businessFile);
					docTpCd.add(Const.SNDRNO_DOC_TP_CD_06);
				}
				
				// 통신서비스이용 증명원 '01'
				MultipartFile communicationFile = multipartRequest.getFile("communicationFile");
				multipartFiles.add(communicationFile);
				docTpCd.add(Const.SNDRNO_DOC_TP_CD_01);
				
//					// 재직증명서 '02'
//					if(multipartRequest.getFile("tenureFile") != null) {
//						MultipartFile tenureFile = multipartRequest.getFile("tenureFile");
//						multipartFiles.add(tenureFile);
//						docTpCd.add(Const.SNDRNO_DOC_TP_CD_02);
//					}
				
				
//					// 신분증(본인확인) '13'
//					if(multipartRequest.getFile("identificationCardFile") != null) {
//						MultipartFile identificationCardFile  = multipartRequest.getFile("identificationCardFile");
//						multipartFiles.add(identificationCardFile);
//						docTpCd.add(Const.SNDRNO_DOC_TP_CD_13);
//					}
				
				// 재직증명서(본인확인) '14'
				if(multipartRequest.getFile("identificationEvidenceFile") != null) {
					MultipartFile identificationEvidenceFile = multipartRequest.getFile("identificationEvidenceFile");
					multipartFiles.add(identificationEvidenceFile);
					docTpCd.add(Const.SNDRNO_DOC_TP_CD_14);
				}
				
			} else if(StringUtils.equals(Const.SNDRNO_TP_CD_OTHER, insertNumberReqDto.getNmineeDivCd())){
				logger.debug("타사업자로 온거 맞아?");
				// 사업자등록증 '06'
				if(multipartRequest.getFile("businessFile") != null) {
					MultipartFile businessFile = multipartRequest.getFile("businessFile");
					logger.debug("businessFile={}",businessFile.getName());
					multipartFiles.add(businessFile);
					docTpCd.add(Const.SNDRNO_DOC_TP_CD_06);
				}
				
				// 통신서비스이용 증명원 '01'
				MultipartFile communicationFile = multipartRequest.getFile("communicationFile");
				logger.debug("communicationFile={}",communicationFile.getName());
				multipartFiles.add(communicationFile);
				docTpCd.add(Const.SNDRNO_DOC_TP_CD_01);
				
				// 재직증명서(본인확인) '14'
				if(multipartRequest.getFile("identificationEvidenceFile") != null) {
					logger.debug("재직증명서");
					MultipartFile identificationEvidenceFile = multipartRequest.getFile("identificationEvidenceFile");
					multipartFiles.add(identificationEvidenceFile);
					docTpCd.add(Const.SNDRNO_DOC_TP_CD_14);
				}
				
				// 위임장 '04'
				MultipartFile attorneyFile = multipartRequest.getFile("attorneyFile");
				logger.debug("attorneyFile={}",multipartRequest.getFile("attorneyFile"));
				multipartFiles.add(attorneyFile);
				docTpCd.add(Const.SNDRNO_DOC_TP_CD_04);
				
				// 위임-수임업체 관계 확인 문서 '03'
				MultipartFile delegationFile = multipartRequest.getFile("delegationFile");
				logger.debug("delegationFile={}",delegationFile.getName());
				multipartFiles.add(delegationFile);
				docTpCd.add(Const.SNDRNO_DOC_TP_CD_03);

				// 위임업체 사업자등록증 '10'
				MultipartFile delegatedBusinessFile = multipartRequest.getFile("delegatedBusinessFile");
				logger.debug("delegatedBusinessFile={}",delegatedBusinessFile.getName());
				multipartFiles.add(delegatedBusinessFile);
				docTpCd.add(Const.SNDRNO_DOC_TP_CD_10);

				
				// 위임사 신분증(임직원 신청시) '08'
				if(multipartRequest.getFile("delegatedIdentificationFile") != null) {
					logger.debug("위임사 신분증(임직원 신청시)");
					MultipartFile delegatedIdentificationFile = multipartRequest.getFile("delegatedIdentificationFile");
					multipartFiles.add(delegatedIdentificationFile);
					docTpCd.add(Const.SNDRNO_DOC_TP_CD_08);
				}
				
				// 수임사 대리인 재직증명서(임직원 신청시) '15'
				if(multipartRequest.getFile("commDeputyCertificateFile") != null) {
					logger.debug("수임사 대리인 재직증명서(임직원 신청시)");
					MultipartFile commDeputyCertificateFile = multipartRequest.getFile("commDeputyCertificateFile");
					multipartFiles.add(commDeputyCertificateFile);
					docTpCd.add(Const.SNDRNO_DOC_TP_CD_15);
				}

				// 위임사 재직증명서(임직원 신청시) '09'
				if(multipartRequest.getFile("delegateCertificateFile") != null) {
					logger.debug("위임사 재직증명서(임직원 신청시)");
					MultipartFile delegateCertificateFile = multipartRequest.getFile("delegateCertificateFile");
					multipartFiles.add(delegateCertificateFile);
					docTpCd.add(Const.SNDRNO_DOC_TP_CD_09);
				}

				// 수임사 대리인 신분증(임직원 신청시) '16'
				if(multipartRequest.getFile("commDeputyIdFile") != null) {
					logger.debug("수임사 대리인 신분증(임직원 신청시)");
					MultipartFile commDeputyIdFile = multipartRequest.getFile("commDeputyIdFile");
					multipartFiles.add(commDeputyIdFile);
					docTpCd.add(Const.SNDRNO_DOC_TP_CD_16);
				}

				// 사업자등록증(타사) '07'
//					MultipartFile otherBusinessFile = multipartRequest.getFile("otherBusinessFile");
//					multipartFiles.add(otherBusinessFile);
//					docTpCd.add(Const.SNDRNO_DOC_TP_CD_07);

				// 신분증(본인확인) '13'
//					if(multipartRequest.getFile("identificationCardFile") != null) {
//						MultipartFile identificationCardFile  = multipartRequest.getFile("identificationCardFile");
//						multipartFiles.add(identificationCardFile);
//						docTpCd.add(Const.SNDRNO_DOC_TP_CD_13);
//					}
				// 법인인감증명서 '12'
//					MultipartFile corporateCertificateFile = multipartRequest.getFile("corporateCertificateFile");
//					multipartFiles.add(corporateCertificateFile);
//					docTpCd.add(Const.SNDRNO_DOC_TP_CD_12);
				
				
//					// 수임사 사업자등록증 '11'
//					MultipartFile authorizedBusinessFile = multipartRequest.getFile("authorizedBusinessFile");
//					multipartFiles.add(authorizedBusinessFile);
//					docTpCd.add(Const.SNDRNO_DOC_TP_CD_11);
			}


			// 파일 업로드 및 테이블 저장 (등록 서류 관련).
			for(int j=0; j<multipartFiles.size(); j++) {
				logger.debug("********들어왔나 내용확인만 하자.몇번째={},내용={}",j,multipartFiles.get(j).getOriginalFilename());
			}
			
			for(int j=0; j<multipartFiles.size(); j++){
				logger.debug("왜 for문 안돌아?몇번째={},내용={}",j,multipartFiles.get(j).getOriginalFilename());
				// DOC FILE UPLOAD.
				String ext = FileIoUtils.getExtension(multipartFiles.get(j).getOriginalFilename());
				// File Nm : [reg_req_no]_[doc_no]_[doc_tp_cd].확장자
				String fileNm = regReqNo + "_" + ("" + Integer.parseInt(docTpCd.get(j))) + "_" + docTpCd.get(j) + "." + ext;
				String titleNm = multipartFiles.get(j).getOriginalFilename();
				long fileSize = multipartFiles.get(j).getSize();
				
				
				// File Upload.
				FileUtil.upload(multipartFiles.get(j), fileNm, path);

				// 발신번호 등록 서류 테이블 저장 (EZ_SNDRNO_DOC).
				InsertNumberFile insertFile = new InsertNumberFile();
				insertFile.setRegReqNo(regReqNo);
				insertFile.setDocNo("" + Integer.parseInt(docTpCd.get(j)));
				//insertFile.setDocNo(docTpCd.get(j).substring(1,2));
				insertFile.setDocTpCd(docTpCd.get(j));
				insertFile.setDocTitle(titleNm);
				insertFile.setFileNm(fileNm);
				insertFile.setFilePath(path);
				insertFile.setFileSize(fileSize);
				insertFile.setRegId(regId);
				sendNumMgtMapper.insertNumberDoc(insertFile);
			}

		}catch (Exception e){
			return new InsertNumberResDto(ApiResponseCode.CM_DB_QUERY_ERR);
		}

		InsertNumberRes insertNumberRes = new InsertNumberRes();
		if(duplicateSendNumList.size() > 0){
			// 발신번호 중복건 응답 처리.
			insertNumberRes.setList(duplicateSendNumList);
		}

		return new InsertNumberResDto(ApiResponseCode.SUCCESS, insertNumberRes);
	}

	/**
	 * date : 2022. 4. 25.
	 * auth : ckr
	 * desc : 문자 발신 번호 정보 상세 조회
	 * @param detailNumberReqDto
	 * @return
	 */
	public DetailNumberResDto numberDetail(DetailNumberReqDto detailNumberReqDto) {

		SendNumMgtMapper sendNumMgtMapper = sqlSessionSlave.getMapper(SendNumMgtMapper.class);

		DetailNumber detailNumber = new DetailNumber();
		try {
			detailNumber = sendNumMgtMapper.detailNumber(detailNumberReqDto);

			if(detailNumber == null) {
				return new DetailNumberResDto(ApiResponseCode.CM_NOT_FOUND);
			}
			detailNumber.setList(sendNumMgtMapper.selectAuthFileList(detailNumberReqDto));
		} catch (Exception e) {
			return new DetailNumberResDto(ApiResponseCode.CM_DB_QUERY_ERR);
		}

		return new DetailNumberResDto(ApiResponseCode.SUCCESS, detailNumber);
	}

	/**
	 * date : 2022. 4. 25.
	 * auth : ckr
	 * desc : 관리자ID 목록 조회
	 * @param adminListReqDto
	 * @return
	 */
	public SendAdminListResDto adminList(SendAdminListReqDto adminListReqDto) {
		SendNumMgtMapper sendNumMgtMapper = sqlSessionSlave.getMapper(SendNumMgtMapper.class);
		int totalCnt = sendNumMgtMapper.selectAdminTotalCnt(adminListReqDto);

		if(totalCnt == 0) {
			SendAdminListRes adminListRes = new SendAdminListRes();
			adminListRes.setList(new ArrayList<>());
			return new SendAdminListResDto(ApiResponseCode.CM_NOT_FOUND, adminListRes);
		}

		List<SendAdminInfo> adminInfos = sendNumMgtMapper.selectAdminList(adminListReqDto);

		Paging paging = new Paging();
		paging.setTotalCnt(String.valueOf(totalCnt));

		SendAdminListRes adminListRes = new SendAdminListRes();
		adminListRes.setList(adminInfos);

		return new SendAdminListResDto(ApiResponseCode.SUCCESS, adminListRes);
	}

	/**
	 * date : 2022. 4. 25.
	 * auth : ckr
	 * desc : 발신번호 승인 목록 조회
	 * @param sendNumberApprListReqDto
	 * @return
	 */
	public SendNumberApprListResDto apprList(SendNumberApprListReqDto sendNumberApprListReqDto) {

		SendNumMgtMapper sendNumMgtMapper = sqlSessionSlave.getMapper(SendNumMgtMapper.class);

		String nowPage = String.valueOf(sendNumberApprListReqDto.getPage());
		int totalCnt = sendNumMgtMapper.selectSvcSndrnoListTotalCnt(sendNumberApprListReqDto);

		if(totalCnt == 0) {
			SendNumberApprListRes sendNumberApprListRes = new SendNumberApprListRes();
			sendNumberApprListRes.setList(new ArrayList<>());

			Paging paging = new Paging();
			paging.setPage(nowPage);
			paging.setTotalCnt(String.valueOf(totalCnt));
			sendNumberApprListRes.setPaging(paging);

			return new SendNumberApprListResDto(ApiResponseCode.CM_NOT_FOUND, sendNumberApprListRes);
		}

		int page = sendNumberApprListReqDto.getPage();
		int pagePerRows = sendNumberApprListReqDto.getPagePerRows();
		page = (page - 1) * pagePerRows;
		sendNumberApprListReqDto.setPage(page);

		List<SendNumberApprInfo> sendNumberApprInfos = sendNumMgtMapper.selectSvcSndrnoList(sendNumberApprListReqDto);

		SendNumberApprListRes sendNumberApprListRes = new SendNumberApprListRes();
		sendNumberApprListRes.setList(sendNumberApprInfos);

		Paging paging = new Paging();
		paging.setPage(nowPage);
		paging.setTotalCnt(String.valueOf(totalCnt));
		sendNumberApprListRes.setPaging(paging);

		return new SendNumberApprListResDto(ApiResponseCode.SUCCESS, sendNumberApprListRes);
	}

	/**
	 * date : 2022. 4. 25.
	 * auth : ckr
	 * desc : 발신번호 승인 상세 정보 조회
	 * @param sendNumberApprDetailReqDto
	 * @return
	 */
	public SendNumberApprDetailResDto apprDetail(SendNumberApprDetailReqDto sendNumberApprDetailReqDto) {

		SendNumMgtMapper sendNumMgtMapper = sqlSessionSlave.getMapper(SendNumMgtMapper.class);

		// Detail 조회.
		SendNumberApprDetailRes sendNumberApprDetailRes = sendNumMgtMapper.selectSvcSndrnoReqDetail(sendNumberApprDetailReqDto);

		// 발신번호 목록 조회
		List<SendNumberApprNum> sendNumberApprNums = sendNumMgtMapper.selectSvcSndnoList(sendNumberApprDetailReqDto);

		// 발신번호 문서 목록 조회
		List<SendNumberApprDoc> sendNumberApprDocs = sendNumMgtMapper.selectSndnoDocList(sendNumberApprDetailReqDto);


		sendNumberApprDetailRes.setNumList(sendNumberApprNums);
		sendNumberApprDetailRes.setDocList(sendNumberApprDocs);


		return new SendNumberApprDetailResDto(ApiResponseCode.SUCCESS, sendNumberApprDetailRes);
	}

	/**
	 * date : 2022. 4. 25.
	 * auth : ckr
	 * desc : 발신번호 승인내역 수정
	 * @param updateApprReqDto
	 * @return
	 */
	public UpdateApprResDto updateAppr(UpdateApprReqDto updateApprReqDto) {

		SendNumMgtMapper sendNumMgtMapper = sqlSessionMaster.getMapper(SendNumMgtMapper.class);
		
		Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		UserDetails userDetails = (UserDetails) principal;
		String regId = userDetails.getUsername();
		Map<Object, Object> mailReqMap = new HashMap<Object,Object>();
		
		List<String> sndrNoList = new ArrayList<String>();
		
		// 발신번호 메모 업데이트. upddateSndrnoReg
		int totalCnt = updateApprReqDto.getList().size();
		int apvCnt = 0;
		int rejtCnt = 0;
		for(UpdateApprSendNumber updateApprSendNumber: updateApprReqDto.getList()){
			if(StringUtils.equals(Const.SNDRNO_STTUS_CD_COMPLETED, updateApprSendNumber.getSttusCd())){
				apvCnt++;
				logger.debug("발신번호 승인, 건수 ={}",apvCnt);
				updateApprSendNumber.setUseYn(Const.COMM_YES);	// 사용여부 : 승인완료 시 자동으로 Y 값으로 되며 승인대기, 반려, 관리자 변경 값은 N으로 표기
			}else if(StringUtils.equals(Const.SNDRNO_STTUS_CD_REJECT, updateApprSendNumber.getSttusCd())){
				rejtCnt++;
				logger.debug("발신번호 반려, 건수 ={}",rejtCnt);
				updateApprSendNumber.setUseYn(Const.COMM_NO);	// 사용여부 : 승인완료 시 자동으로 Y 값으로 되며 승인대기, 반려, 관리자 변경 값은 N으로 표기
				logger.debug("************************반려 값 오는지 확인 ********************");
				logger.debug("발신번호={}",updateApprSendNumber.getSndrno());
				// ** 발신번호 반려 시에는 사용자에게 반려 메일 전송  **
				//1. for문 안에서는 반려 발신번호 리스트에 셋팅
				sndrNoList.add(updateApprSendNumber.getSndrno());

			}
			updateApprSendNumber.setAdminId(regId);
			sendNumMgtMapper.updateSndrno(updateApprSendNumber);
		}
		
		//2. 반려 발신번호 리스트에 값이 있을 경우 메일을 보냄
		if(sndrNoList.size()>0) {
			// 3. 반려 발신번호 메일 대상 주소
			String adminId = updateApprReqDto.getAdminId();
			String userEmail = sendNumMgtMapper.selectUserEmailByAdminId(adminId);
			
			//3. 발신번호 리스트 치환
			/*
			String SndrNoString = sndrNoList.toString();
			
			String SndrNoRe1 = SndrNoString.replace("[", "<br>");
			String SndrNoRe2 = SndrNoRe1.replace(", ","</br><br>");
			String SndrNoRe3 = SndrNoRe2.replace("]", "</br>");
			*/
			
			String SndrNoString = "";
			for (int i = 0; i < sndrNoList.size(); i++) {
				SndrNoString+=sndrNoList.get(i)+"</br>";
			}
			logger.debug("SndrNoString : {}",SndrNoString );
			
//			logger.debug("발신번호 리스트 스트링 ={}",re3);
			//try catch 처리하기
			try {
				Map<Object, Object> mailResultMap = new HashMap<Object, Object>();
				
				// API authToken 조회
				String apiAuthToken = sendNumMgtMapper.selectApiAuthToken(apiApplicationId);
				
				//3. 메일에 담을 내용 셋팅
				mailReqMap.put("applicationId", apiApplicationId);
				mailReqMap.put("authToken", apiAuthToken);
				mailReqMap.put("rejectListSndrNo", SndrNoString);
				mailReqMap.put("rejectHtml", updateApprReqDto.getMemo());
				//이메일 수신자 가져오는 쿼리
				mailReqMap.put("toEmail", userEmail);
				mailReqMap.put("fromEmail", fromEmail);
				mailReqMap.put("templeteCode", senrNoRejTempleteCode);
				mailReqMap.put("homeUrl", mailTempleteHomeUrl);
				
				
				logger.debug("############## [Email Send Start] ###############");
	            logger.debug("[Email Send Request - applicationId : {}]", mailReqMap.get("applicationId"));
	            logger.debug("[Email Send Request - authToken : {}]", mailReqMap.get("authToken"));
	            logger.debug("[Email Send Request - rejectListSndrNo : {}]", mailReqMap.get("rejectListSndrNo"));
	            logger.debug("[Email Send Request - rejectHtml : {}]", mailReqMap.get("rejectHtml"));
	            logger.debug("[Email Send Request - toEmail : {}]", mailReqMap.get("toEmail"));
	            logger.debug("[Email Send Request - fromEmail : {}]", mailReqMap.get("fromEmail"));
	            logger.debug("[Email Send Request - templeteCode : {}]", mailReqMap.get("templeteCode"));
	            logger.debug("[Email Send Request - homeUrl : {}]", mailReqMap.get("homeUrl"));
				
				mailResultMap = hubeasyApi.sendTemplateMailApi(mailReqMap);
				
				if (mailResultMap != null) {
	                logger.debug("[Email Send API RESULT : {}]", mailResultMap.get("API_RSLT"));
	                if ("F".equals(mailResultMap.get("API_RSLT"))) {
	                    logger.debug("[Email Send API ERROR : {}]", mailResultMap.get("API_RSLT_MSG"));
	                }
	            }
	            logger.debug("############## [Email Send End] ###############");
	            
	            //4. 메시지 발송
	            String WEB_REQ_ID =sendNumMgtMapper.selectSequence(commService.WEB_REQ_ID);
	            String prefix = DateUtil.getCurrentDate("yyyyMMdd");
	            
	            //알림문자 발송테이블 insert
	            Map<Object, Object> ezMsgMap = new HashMap<Object, Object>();
	            ezMsgMap.put("WEB_REQ_ID", WEB_REQ_ID);
	            ezMsgMap.put("prefix", prefix);
	        	String userPhone = sendNumMgtMapper.selectUserPhoneByAdminId(adminId);
	        	ezMsgMap.put("phone", userPhone);
	        	
	        	String msg = "[LG U+메시지허브이지]\n허브이지 발신번호 신청 내역 반려 되었습니다. 자세한 내용은 메일 확인 부탁드립니다.";
	        	ezMsgMap.put("msg", msg);
	        	
	        	
	            
	        	 commService.sendMsg(ezMsgMap);
	           
	        	//알람이력에 insert
	        	Map<Object, Object> msgHistMap = new HashMap<Object, Object>();
	        	msgHistMap.put("WEB_REQ_ID", WEB_REQ_ID);
	        	msgHistMap.put("prefix", prefix);
	        	String notiSeq = sendNumMgtMapper.selectNotiSeq();
 	 			String userSeq = sendNumMgtMapper.selectUserSeqByAdminId(adminId);
 	 			msgHistMap.put("userSeq", userSeq);
 	 			msgHistMap.put("notiSeq", notiSeq);
 	 			msgHistMap.put("notiMsg", msg);
 	 			msgHistMap.put("notiDiv", Const.NOTI_DIV_CD_05);
 	 			
 	 			commService.sendMsgHist(msgHistMap);
 	 			
			} catch (Exception e) {
				logger.error(e.getMessage());
				// TODO: handle exception
			}
		}
		

		updateApprReqDto.setApvCnt(apvCnt);
		updateApprReqDto.setRejtCnt(rejtCnt);

		// 발신 번호 등록 정보 가져오기
		SendNumberApprDetailReqDto sendNumberApprDetailReqDto = new SendNumberApprDetailReqDto();
		sendNumberApprDetailReqDto.setRegReqNo(updateApprReqDto.getRegReqNo());				// 발신 번호 세팅
		SendNumberApprDetailRes sendNumberApprDetailRes = sendNumMgtMapper.selectSvcSndrnoReqDetail(sendNumberApprDetailReqDto);

		if(sendNumberApprDetailRes != null) {
			String cmpltDt = sendNumberApprDetailRes.getCmpltDt();
//			if(cmpltDt == null) { // 완료 일시가 없으면
//				if(totalCnt == (apvCnt + rejtCnt)){ // (승인 | 반려) 처리가 다 되었는지 확인
//					updateApprReqDto.setReqSttusCd(Const.SNDRNO_REQ_STTUS_CD_COMPLETED);
//					updateApprReqDto.setCmpltYn(Const.COMM_YES);
//				}else {
//					// 처리가 다 안되어서 승인 대기 상태
//					updateApprReqDto.setReqSttusCd(Const.SNDRNO_REQ_STTUS_CD_WAITING);
//				}
//			}
			if(cmpltDt == null) { // 완료 일시가 없으면
				if((apvCnt + rejtCnt) > 0) {
					updateApprReqDto.setReqSttusCd(Const.SNDRNO_REQ_STTUS_CD_COMPLETED);
					updateApprReqDto.setCmpltYn(Const.COMM_YES);
				}
			}
		}

		int result = sendNumMgtMapper.upddateSndrnoReg(updateApprReqDto);

		// 승인건이 1건이상이면 사업자 인증 'Y'
		if(apvCnt > 0){
			sendNumMgtMapper.updateSvcUser(updateApprReqDto);
		}

		return new UpdateApprResDto(ApiResponseCode.SUCCESS);
	}

		/**
		 * InputStream을 종료한다.
		 */
		public static void close(InputStream stream) {
			if (stream != null) {
				try {
					stream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

		/**
		 * OutputStream을 종료한다.
		 */
		public static void close(OutputStream stream) {
			if (stream != null) {
				try {
					stream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}

		/**
		 * FileOutputStream을 종료한다.
		 */
		public static void close(FileOutputStream stream) {
			if (stream != null) {
				try {
					stream.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
	}
		// 다운로드 제출서류
		   public void downloadDoc(HttpServletRequest request, HttpServletResponse response, InsertNumberFile docFile) {

		      SendNumMgtMapper sendNumMgtMapper = sqlSessionSlave.getMapper(SendNumMgtMapper.class);

		      InsertNumberFile selectFile = sendNumMgtMapper.selectDownload(docFile);

		      String fileName = selectFile.getDocTitle();
		      String oriFileName = selectFile.getFileNm();
		      String filePath = selectFile.getFilePath();


		      StringBuilder sb = new StringBuilder("D:" + filePath + "/");
		      sb.append(oriFileName);
		      String saveFileName = sb.toString();

		      String contentType =  request.getContentType();
		      File file = new File(saveFileName);
		      long fileLength = file.length();

		      String extension = FilenameUtils.getExtension(saveFileName).toLowerCase();

		   // 형태에 따른 컨텐트 타입 분류
				if      ("zip".equals(extension))								response.setContentType("application/zip");
				else if ("xls".equals(extension) || "xlsx".equals(extension))	response.setContentType("application/vnd.ms-excel;charset=UTF-8");
				else if ("ppt".equals(extension) || "pptx".equals(extension))	response.setContentType("application/x-mspowerpoint");
				else if ("doc".equals(extension) || "docx".equals(extension))	response.setContentType("application/msword");
				else if ("pdf".equals(extension))								response.setContentType("application/x-msdownload");
				else if ("jpg".equals(extension))								response.setContentType("image/jpg");
				else if ("gif".equals(extension))								response.setContentType("image/gif");
				else if ("png".equals(extension))								response.setContentType("image/png");


		      response.setHeader("Content-Disposition", "attachment; filename=" + fileName + ";");
		      response.setHeader("Content-Transfer-Encoding", "binary");
		      response.setHeader("Content-Type", contentType);
		      response.setHeader("Content-Length", "" + fileLength);
		      response.setHeader("Pragma", "no-cache;");
		      response.setHeader("Expires", "-1;");

		      try {
		    		FileInputStream fis = new FileInputStream(saveFileName);
		    		OutputStream out = response.getOutputStream();


		    	  int readCount = 0;
		    	  byte[] buffer =  new byte[BUFFERSIZE];

		    	  while ((readCount = fis.read(buffer)) != -1 ) {
		    		  out.write(buffer, 0 , readCount);
		    	  }
		    	  out.flush();
		      }catch(Exception e) {
		    	  throw new RuntimeException("File load Error");
		      }

		      //String fileStr ="C:/efs/admin/sendNumber/2022/07/2022071018012_2_02.PNG.png";
		      //String fileStr = filePath + oriFileName;
//		      String fileStr = filePath + oriFileName;
//		      File file = new File(fileStr);
//		      FileUtil.download(request, response, fileName, file);
		   }






}