package itn.com.cmm.util;

import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletResponse;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import itn.com.cmm.JsonResult;
import itn.let.fax.user.service.FaxGroupDataVO;
import itn.let.mjo.msgdata.service.PhoneVO;
/**
 * 
 * @author 		: 이호영
 * @fileName 	: FaxUtil.java 
 * @date 		: 2023.03.20
 * @description : 팩스 관련 Util
 * =========================================================== 
 * DATE          AUTHOR   NOTE 
 * ----------------------------------------------------------- *
 * 2023.03.20    이호영          최초 생성
 * 
 * 
 * 
 */
public final class FaxUtil {

	public static HttpServletResponse getResponse() {
		ServletRequestAttributes attr =
			(ServletRequestAttributes)RequestContextHolder.currentRequestAttributes();
		return attr.getResponse();
	}
	
	
    /** 
     * @methodName	: checkHpNum 
     * @author		: 이호영
     * @date		: 2023.03.20 
     * @description	: 
     * @param faxConvertFilePath
     * @param seq
     * @return 
     */
    public static String makeDownloadPath(String faxConvertFilePath, String seq) {
        return faxConvertFilePath + "/" + seq + ".pdf";
    }

	/** 
	 * @methodName	: exelFileConvertForFax 
	 * @author		: 이준호
	 * @date		: 2023.05.08 
	 * @description	: 
	 * @param multiRequest
	 * @return 
	 */
	public static JsonResult exelFileConvertForFax(MultipartHttpServletRequest multiRequest) {
		
		JsonResult jr = new JsonResult();
		
		jr.setSuccess(false);
		jr.setMessage("엑셀 파일만 업로드할 수 있습니다.");
		
		//final Map<String, MultipartFile> files = multiRequest.getFileMap();
		List<MultipartFile> files = (List<MultipartFile>) multiRequest.getFiles("file0");
		
		// 파일명에 .이 있을경우 오류 => Ex) 테스트6.20.xlsx 
		int fileNameSplitCnt = 0;
		
		if(!files.isEmpty()) {
			fileNameSplitCnt = files.get(0).getOriginalFilename().split("[.]").length;
			
			if (files.get(0).getSize() > 0 
					&& (files.get(0).getContentType().indexOf("spreadsheetml") > -1) 
					|| files.get(0).getContentType().indexOf("ms-excel") > -1 
					|| files.get(0).getOriginalFilename().split("[.]")[fileNameSplitCnt-1].indexOf("xlsx") > -1 
					|| files.get(0).getOriginalFilename().split("[.]")[fileNameSplitCnt-1].indexOf("xls") > -1) {
				
				// 엑셀 파일 용량 3MB이상 시 10만건 이상으로 서버가 다운되는 증상 발생
				long fileSize = multiRequest.getFile("file0").getSize();
				
				if(fileSize > 3374653) {
					jr.setMessage("엑셀 파일은 3MB를 넘을수 없습니다.");
					return jr;
				}
				
				String Ext = files.get(0).getOriginalFilename().split("[.]")[1];
				String errMessage = "";
		        String cellValue  = "";
		        
//				String phoneRegExp = "^(050[234567]{1}|01[016789]{1})-?[0-9]{3,4}-?[0-9]{4}$";
				
	            int errPhoneCnt = 0;
	            int errNameCnt = 0;
	            
	            try {
		            //엑셀 확장자에 따른 처리 로직 분리
					if(Ext.equals("xls")) {
						
						HSSFWorkbook workbook = new HSSFWorkbook(files.get(0).getInputStream());
					    HSSFSheet sheet = workbook.getSheetAt(0);
					    
					    if(sheet.getLastRowNum() > 20000) { //
			            	errMessage = "20000건 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.";
			            	jr.setSuccess(false);
			            	jr.setMessage(errMessage);
			            	return jr;
			            }
			            
			            List<HashMap<String, String>> json = new ArrayList<HashMap<String, String>>();
			            PhoneVO pVO = new PhoneVO();
			            for(int i=2; i< sheet.getLastRowNum() + 2; i++){ //먼저 밸리데이션 체크(1줄은 생략)
			            	HSSFRow row = sheet.getRow(i); //열읽기
			            	if(null == row) { 
			                    continue;
			                }
			            	
			            	HashMap<String, String> jm = new HashMap<>();
			            	// 행의 두번째 열(이름부터 받아오기) 
			                HSSFCell cell = null;
			                boolean errSts = true;
			                for(int j = 0 ; j < 2; j++){ //행읽기(6행까지나 2행까지만 필요)
			                	cellValue = "";
			                	cell = row.getCell(j); //이름/수신번호
			                	if(null == cell || "".equals(cell.toString().trim())) { //셀에 값이 없으면 
			                    	//System.out.println("Cell 데이터가 없습니다.");
			                		if(j == 1) {
				                		if (sheet.getLastRowNum() == i) {
				                			continue;
				                		}
				    	            	break;
			                		}
			                    }
			                	if(null != cell){
			                		switch(cell.getCellType()){ //숫자타임을 문자로 변환
			                			case  Cell.CELL_TYPE_NUMERIC:
			                			cell.setCellType(Cell.CELL_TYPE_STRING);
			                		}
			                		cellValue =  StringUtil.getString(cell.getStringCellValue().trim()) ;
			                    }
			                	if(j == 0) {
			                		//이름
			                		boolean nmChk = getNameRepLenChk("name", cellValue);
			                		if(nmChk && errSts) {
			                			jm.put("name", cellValue);
			                		}else {
			                			errNameCnt++;
			                			errSts = false;
			                			break;
			                		}
			                	} 
			                	if(j == 1) {
			                		//전화번호
			                		if(errSts) {
			                			jm.put("phone", cellValue);
			                		}else {
				    	            	errPhoneCnt++;
				    	            	errSts = false;
				    	            	break;
			                		}
			                	}
			                }
			                if(null != jm.get("phone") && errSts) {
			                	json.add(jm);
			                }
			                
			            }
			            
			            int resultErrCnt = errPhoneCnt + errNameCnt;
			            int resultErrCntExceptPhone = errPhoneCnt + errNameCnt;
			            
			            jr.setData(json);
						jr.setSuccess(true);
						
						if(resultErrCnt > 0) {
							jr.setMessage("유효하지 않은 형식의 전화번호  "+ errPhoneCnt +"건,\n이름 : 20byte 제한글자수 초과 "+ resultErrCntExceptPhone +"건 있습니다.\n해당 건을 제외하고 추가됩니다.");
						}else {
							jr.setMessage("");
						}
						
					}else {	//확장자가 xlsx
						
						OPCPackage opcPackage = OPCPackage.open(files.get(0).getInputStream());
						XSSFWorkbook workbook = new XSSFWorkbook(opcPackage);
			            XSSFSheet sheet = workbook.getSheetAt(0); // 첫번째 시트 불러오기
			            opcPackage.close();
			            
			            if(sheet.getLastRowNum() > 20000) { //
			            	errMessage = "20000건 이상의 업로드는 데이터 부하로 업로드 할수 없습니다.";
			            	jr.setSuccess(false);
			            	jr.setMessage(errMessage);
			            	return jr;
			            }
			            
			            List<HashMap<String, String>> json = new ArrayList<HashMap<String, String>>();
			            PhoneVO pVO = new PhoneVO();
			            for(int i=2; i< sheet.getLastRowNum() + 2; i++){ //먼저 밸리데이션 체크(1줄은 생략)
			            	XSSFRow row = sheet.getRow(i); //열읽기
			            	if(null == row) { 
			                    continue;
			                }
			            	
			            	HashMap<String, String> jm = new HashMap<>();
			            	// 행의 두번째 열(이름부터 받아오기) 
			                XSSFCell cell = null;
			                boolean errSts = true;
			                
			                for(int j = 0 ; j < 2; j++){ //행읽기(6행까지나 2행까지만 필요)
			                	cellValue = "";
			                	cell = row.getCell(j); //이름/수신번호
			                	if(null == cell || "".equals(cell.toString().trim())) { //셀에 값이 없으면 
			                		if(j == 1) {
				                		if (sheet.getLastRowNum() == i) {
				                			continue;
				                		}
				    	            	break;
			                		}
			                    }
			                	if(null != cell){
			                		switch(cell.getCellType()){ //숫자타임을 문자로 변환
			                			case  Cell.CELL_TYPE_NUMERIC:
			                			cell.setCellType(Cell.CELL_TYPE_STRING);
			                		}
			                		cellValue =  StringUtil.getString(cell.getStringCellValue().trim()) ;
			                    }
			                	
			                	if(j == 0) {
			                		//이름
			                		boolean nmChk = getNameRepLenChk("name", cellValue);
			                		if(nmChk && errSts) {
			                			jm.put("name", cellValue);
			                		}else {
			                			errNameCnt++;
			                			errSts = false;
			                			break;
			                		}
			                	} 
			                	if(j == 1) {
			                		//수신번호
			                		if(errSts) {
			                			jm.put("phone", cellValue);
			                		}else {
				    	            	errPhoneCnt++;
				    	            	errSts = false;
				    	            	break;
			                		}
			                	}
			                }
			                if(null != jm.get("phone") && errSts) {
			                	json.add(jm);
			                }
			            }
			            
			            int resultErrCnt = errPhoneCnt + errNameCnt;
			            int resultErrCntExceptPhone = errPhoneCnt + errNameCnt;
			            
						jr.setData(json);
						jr.setSuccess(true);
						
						if(resultErrCnt > 0) {
							jr.setMessage("유효하지 않은 형식의 전화번호  "+ errPhoneCnt +"건,\n이름 : 20byte 제한글자수 초과 "+ resultErrCntExceptPhone +"건 있습니다.\n해당 건을 제외하고 추가됩니다.");
						}else {
							jr.setMessage("");
						}
					}	//xlsx 처리 끝
	            } catch (Exception e) {
	            	jr.setMessage("처리 중 오류가 발생했습니다. 관리자에게 문의하세요.");
				}
			}
		}
		
		return jr;
	}
	
	
	

	public static void getExcelForFaxSendList(List<FaxGroupDataVO> faxGroupListVO) {

		HttpServletResponse response =ContextUtil.getResponse();
		
    	// 메모리에 100개의 행을 유지합니다. 행의 수가 넘으면 디스크에 적습니다.
		SXSSFWorkbook wb = new SXSSFWorkbook();
		String fileName ="팩스 발송 내역";		// 저장 파일명
		String sheetTitle = "팩스 발송 내역" ; 		// 셀 제목
		Sheet sheet = wb.createSheet(sheetTitle);
		Cell cell = null;
		Row row = null;
		
		CellStyle style = wb.createCellStyle();
		style.setBorderBottom(CellStyle.BORDER_THIN);	//테두리 두껍게 
		style.setBorderLeft(CellStyle.BORDER_THIN);
		style.setBorderRight(CellStyle.BORDER_THIN);
		style.setBorderTop(CellStyle.BORDER_THIN);
		
		// 정렬
		style.setAlignment(CellStyle.ALIGN_CENTER); //가운데 정렬
		style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); //높이 가운데 정렬
		
		Font font = wb.createFont();
		font.setBoldweight(Font.BOLDWEIGHT_BOLD);  //글씨 bold
		
		
		
		try{ 
			
			//발송 성공,실패 건수 불러오기
			
				
			row = sheet.createRow(0);
			
			
			sheet.setColumnWidth(1, 7000); // 발송형태 칼럼의 폭 조절
			sheet.setColumnWidth(2, 5000); // 접수일자 칼럼의 폭 조절
			
			//셀병합 처리
			sheet.addMergedRegion(new CellRangeAddress(0,1,0,0)); //번호 세로 셀병합
			sheet.addMergedRegion(new CellRangeAddress(0,1,1,1)); //발송상태 세로 셀병합
			sheet.addMergedRegion(new CellRangeAddress(0,1,2,2)); //접수일자 세로 셀병합
			sheet.addMergedRegion(new CellRangeAddress(0,1,3,3)); //예약일자 세로 셀병합
			sheet.addMergedRegion(new CellRangeAddress(0,1,4,4)); //형태 세로 셀병합
			
			cell = row.createCell(0);
			cell.setCellValue("번호");
			cell.setCellStyle(style);
			
			cell = row.createCell(1);
			cell.setCellValue("제목");
			cell.setCellStyle(style);
			
			cell = row.createCell(2);
			cell.setCellValue("전송시간");
			cell.setCellStyle(style);
			
			cell = row.createCell(3);
			cell.setCellValue("문서 매수");
			cell.setCellStyle(style);
			
			cell = row.createCell(4);
			cell.setCellValue("발송 건수");
			cell.setCellStyle(style);
			
			cell = row.createCell(5);
			cell.setCellValue("발송결과 건수");
			sheet.addMergedRegion(new CellRangeAddress(0,0,5,6)); // 발송결과 건수 가로 셀병합
			cell.setCellStyle(style);
			
			cell = row.createCell(6);
			cell.setCellStyle(style);
			
			
			
			row = sheet.createRow(1);
			
			cell = row.createCell(0);
			cell.setCellStyle(style);
			
			cell = row.createCell(1);
			cell.setCellStyle(style);
			
			cell = row.createCell(2);
			cell.setCellStyle(style);
			
			cell = row.createCell(3);
			cell.setCellStyle(style);
			
			cell = row.createCell(4);
			cell.setCellStyle(style);
			
			cell = row.createCell(5);
			cell.setCellValue("성공");
			cell.setCellStyle(style);
			
			cell = row.createCell(6);
			cell.setCellValue("실패");
			cell.setCellStyle(style);
			

			int rowNum = 2;
				
			for(FaxGroupDataVO faxGroupDataVO : faxGroupListVO) {

				row = sheet.createRow(rowNum);

				cell = row.createCell(0);
				cell.setCellStyle(style);
				cell.setCellValue(rowNum-1);

				cell = row.createCell(1);
				cell.setCellStyle(style);
				cell.setCellValue(faxGroupDataVO.getSubject());
				
				cell = row.createCell(2);
				cell.setCellStyle(style);
				cell.setCellValue(faxGroupDataVO.getDoneDate());
				
				cell = row.createCell(3);
				cell.setCellStyle(style);
				cell.setCellValue(faxGroupDataVO.getPage());
				
				cell = row.createCell(4);
				cell.setCellStyle(style);
				cell.setCellValue(faxGroupDataVO.getTotalEa());
				
				cell = row.createCell(5);
				cell.setCellStyle(style);
				cell.setCellValue(faxGroupDataVO.getSentEa());

				cell = row.createCell(6);
				cell.setCellStyle(style);
				cell.setCellValue(faxGroupDataVO.getHoldEa()+faxGroupDataVO.getUnSendEa()+faxGroupDataVO.getErrorEa());
				
				rowNum++;
			}

			response.setHeader("Set-Cookie", "fileDownload=true; path=/");
			SimpleDateFormat mSimpleDateFormat = new SimpleDateFormat ( "yyyyMMdd_HHmmss", Locale.KOREA );
			Date currentTime = new Date ();
			String mTime = mSimpleDateFormat.format ( currentTime );
			fileName = fileName+"("+mTime+")";
			
			response.setHeader("Content-Disposition", String.format("attachment; filename=\""+new String((fileName).getBytes("KSC5601"),"8859_1")+".xlsx"));
			wb.write(response.getOutputStream());
		}catch(Exception e) {
  			response.setHeader("Set-Cookie", "fileDownload=false; path=/");
  			response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
  			response.setHeader("Content-Type","text/html; charset=utf-8");
  			OutputStream out = null;
  			try {
  				out = response.getOutputStream();
  				byte[] data = new String("fail..").getBytes();
  				out.write(data, 0, data.length);
  			} catch(Exception ignore) {
  				ignore.printStackTrace();
  			} finally {
  				if(out != null) try { out.close(); } catch(Exception ignore) {}
  			}
  		}finally {
  			// 디스크 적었던 임시파일을 제거합니다.
  			wb.dispose();
  			try { wb.close(); } catch(Exception ignore) {}
  		}
	}
	
	
	
	/*====================================================================
	=	 						private function zone  			  		 =
	====================================================================*/
	// 팩스 엑셀 업로드 이름 길이 체크
	private static boolean getNameRepLenChk(String type, String value) {
		
		boolean rtnValue = true;
		
		if(type.equals("name")) {
			String tmpNm = value;
			int nmLen = tmpNm.length();
			
			if(nmLen > 12) {
				rtnValue = false;
			}
		}else if(type.equals("rep")) {
			String tmpRep = value;
			int repLen = tmpRep.length();
			
			if(repLen > 20) {
				rtnValue = false;
			}
		}
		return rtnValue;
	}


}
