<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags" %>
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title>노드 일괄등록</title>	    
	    <script type="text/javascript" src="/js/ext/jquery.min.js"></script>
	    <script type="text/javascript" src="/js/ext/xlsx.full.min.js"></script>
	    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
	    
	    <style>
			body {
				background-color: rgb(52,55,58);
			    padding: 15px;
			    margin: 0;
			    color: #cccccc;
			    font-size: 18px;
			    font-weight: bold;
			    display: grid;
			    grid-template-rows: auto;
			    grid-row-gap: 15px;
			}
			
			.batch-popup {
				font-weight: bold;
			    display: grid;
			    /* grid-template-rows: 60px 30px 210px 1fr; */
			    grid-template-rows: 60px 30px 1fr;
			    grid-row-gap: 30px;
			    padding: 15px;
			    background: #777;
			}
			
			.input-file {
			  	display: grid;
			    grid-template-columns: min-content auto;
			    border: 2px solid #706f6f;
			    background: #ccc;
			    height: 60px;
			}
			.input-file .file-label {
			  	display: grid;
			    width: 115px;
			    height: 60px;
			    line-height: 20px;
			    padding: 0 10px;
			    border-radius: 2px;
			    background-color: #eee;
			    color: #706f6f;
			    cursor: pointer;
			    border-right: 2px solid #706f6f;
			    font-size: 14px;
			    align-items: center;
			}
			.input-file .upload-file {
				color: #777;
			    padding: 5px;
			    font-size: 14px;
			    display: grid;
			    grid-template-rows: 1fr 1fr;
			}
			.input-file .upload-file .upload-button {
				display: grid;
    			grid-template-columns: 8fr 1fr;
			}
			.input-file .upload-file .upload-button .validate {
				background: #efefef;
			    border: 1px solid #767676;
			    text-align: center;
			    line-height: 23px;
			    font-size: 13px;
			    font-weight: 400;
			    color: rgb(0 0 0);
			    border-radius: 3px;
			}
			.input-file .upload-file .upload-button .validate:hover {
				cursor: pointer;
			}
			
			.input-option {
				display: grid;
			    grid-template-columns: min-content auto;
			    border: 2px solid #706f6f;
			    background: #ccc;
			    height: 30px;
			}
			.input-option .option-label {
			  	display: grid;
			    width: 115px;
			    height: 30px;
			    padding: 0 10px;
			    border-radius: 2px;
			    background-color: #eee;
			    color: #706f6f;
			    cursor: pointer;
			    border-right: 2px solid #706f6f;
			    font-size: 14px;
			    align-items: center;
			}
			.input-option .upload-option {
				color: #777;
			    padding: 5px;
			    font-size: 14px;
			    display: grid;
			    grid-template-columns: 1fr 1fr;
			}
			
			.button-div {
				/* position: relative; */
			    /* top: 45px; */
			    height: 55px;
			    /* line-height: 58px; */
			    border-top: 2px solid rgb(170 170 183);
			    display: grid;
			    grid-template-columns: 92px 92px;
			    justify-content: space-between;
			    align-items: end;
			}
			
			.confirm {
				width: 80px;
				color:#706f6f;
				height: 36px;
				line-height: 40px;
				border: 1px solid #eeeeee;
				background: #f7f7f6;;
				text-align: left;
				padding-left: 10px;
			}
			
			.cancel {
				width: 80px;
				color:#706f6f;
				height: 36px;
				line-height: 40px;
				border: 1px solid #eeeeee;
				background: #f7f7f6;;
				text-align: left;
				padding-left: 10px;
			}
			
			.confirm:hover,
			.cancel:hover {
				cursor: pointer;
				background: rgb(0, 120, 215);
				color: white;
				border-color: white;
			}
			
			.inspection-option {
				/* display: grid; */
				display: none;
			    grid-template-rows: auto;
			    grid-row-gap: 10px;
			}
			.inspection-label {
				color: #ffffff;
			    padding: 0 3px;
			    height: 30px;
			}
			.inspection-result {
				border: 2px solid #706f6f;
			    background: #ccc;
			    height: 166px;
			    color: #000;
			    overflow: auto;
			    font-size: 13px;
			    font-weight: 400;
			}
		</style>
	</head>
<body>
	노드정보 일괄등록
    <div class="batch-popup">
		<div class="input-file">
			<label for="upload01" class="file-label">엑셀 업로드<br>(파일)</label>
			<div class="upload-file">
			*등록하려는 엑셀 파일입니다.
				<div class="upload-button">
			  		<input type="file" id="upload01" name="upload01" onchange="regionExcel()">
			  		<div class="validate">
			  			검사
			  		</div>
			  	</div>  
		  	</div>
		</div>
		<div class="input-option">
			<div class="option-label">업로드 옵션</div>
			<div class="upload-option">
				<div>
					<input type="radio" id="option1" name="option" value="upload1" checked>
					<label for="option1">중복 데이터 제외 후 추가</label>
				</div>
				<div>
					<input type="radio" id="option2" name="option" value="upload2">
					<label for="option2">중복 데이터 수정 및 추가</label>
				</div>
			</div>
		</div>
		<div class="inspection-option">
			<div class="inspection-label">검사 결과</div>
			<div class="inspection-result">
			
			</div>
		</div>
		<div class="button-div">
			<div class="confirm">
				<i class='fa fa-check' style="font-size: 25px;" aria-hidden='true'></i> 등록
			</div>
			<div class="cancel">
				<i class='fa fa-times' style="font-size: 25px;" aria-hidden='true'></i> 취소
			</div>
		</div>
    </div>
    <script>
		let nodeIdData = [];
		allNodeId();

	 	// 검사 버튼 이벤트
		$(".validate").on('click',()=>{
			if(!addData.length){
				alert("엑셀이 등록되지 않았거나, 엑셀 데이터가 존재하지 않습니다.")
			} else {
				$(".batch-popup")[0].style["grid-template-rows"] = "60px 30px 210px 1fr"
				$(".inspection-option")[0].style["display"] = "grid"
				$(window)[0].resizeTo(616, 620);
				validateExcel($("input[name='option']:checked").val());
			}
		})
    
    	// 확인 버튼 이벤트
		$(".confirm").on('click',()=>{
			saveExcel();
		})
		
		// 취소 버튼 이벤트
		$(".cancel").on('click',()=>{
			window.close(); 
		})
		
		let obj;
	 	
	 	let region = [];
		
		// 엑셀 READ result 
		let addData = [];
	 	
	 	// 예외처리 후 result
		let result = [];
	 	
	 	// 예외처리 에러리스트
		let errList = [];
	 	
	 	// 에러 메세지
		let message = "";  
	 	
	 	// 검사 여부
	 	let validateYN = 0;
	 	
	 	// 라디오 버튼
	 	$("input[name='option']:radio").change(function () {
			validateYN = 0; 
		});
	 	
	 	// 삭제 항목
	 	let delStr = ""
	 	
    	// 형식 검사를 위한 정규식
		const latitudePattern = /^([0-9]{1,2})([.]{1})([0-9]{1,14})$/
		const longitudePattern = /^([0-9]{1,3})([.]{1})([0-9]{1,14})$/
		const nodeIdPattern = /^[0-9]{1,10}$/;
		const ntPattern = /^[0-9]*$/;
		
		function regionArr(arr){
			$.ajax({
					url:"/api/getAllRegion.do",
					async:false,
					type: "get",
					dataType: "json",
					success:function(result){
						arr.push(result);
					}, error: function(error) {
					console.log(error)
					}
				
			})
		}
		
    	// 지역 코드 정의
		let regionIndex = {
			"서울시" : "L01",
			"인천시" : "L02",
			"부천시" : "L03",
			"광명시" : "L04",
			"안양시" : "L05",
			"과천시" : "L06",
			"안산시" : "L07",
			"용인시" : "L08",
			"성남시" : "L09",
			"고양시" : "L10",
			"시흥시" : "L11",
			"파주시" : "L12",
			"양주시" : "L13",
			"의정부시" : "L14",
			"김포시" : "L15",
			"의왕시" : "L16",
			"군포시" : "L17",
			"남양주시" : "L18",
			"수원시" : "L19",
			"광주시" : "L20",
			"구리시" : "L21",
			"하남시" : "L22",
			"부산시" : "L23",
			"양산시" : "L24",
			"창원시" : "L25",
			"김해시" : "L26",
			"화성시" : "L27",
			"거제시" : "L28",
			"대구시" : "L29",
			"대전시" : "L30",
			"광주광역시" : "L31",
			"포항시" : "L37"
		}
    	
		// 메세지 정의
		let	messageIndex = {
			"0" : "노드ID 미입력",
			"1" : "노드ID 중복",
			"2" : "노드ID 10자리수 초과",
			"3" : "교차로명 미입력",
			"4" : "위도 미입력",
			"5" : "형식에 맞지 않는 위도",
			"6" : "경도 미입력",
			"7" : "형식에 맞지 않는 경도",
			"8" : "지역/시(ADDR1) 미입력",
			"9" : "군/구(ADDR2) 미입력",
			"10" : "주소(ADDR3) 미입력",
			"11" : "연등지 항목 미입력",
			"12" : "NODE TYPE 미입력",
			"13" : "형식에 맞지 않는 NODE TYPE",
			"14" : "등록되어 있지 않은 지역"
		}
    	
    	// 전체 NODE 조회
		function allNodeId() {
			$.ajax({
				url: "/node/getAllNodeId.do",
				async: false,
				cache: false,
				type: "get",
				dataType: "json",
				success: function(result) {
					// var include = result.includes(value.toString());
					// checker.push(include);
					nodeIdData = result;
				}, error: function(error) {
					console.log(error)
				}

			})
		}
		
    	// NodeVO 객체
		function NodeVO(nodeid,  name,  latitude,  longitude,  addr1,  addr2,
				 addr3,  addnode,  ipaddr,  useyn,  cvimyn,  nodeyn,  testyn,
				 nodetype,  regionId){
			this.nodeid = nodeid;
			this.name = name;
			this.latitude = latitude;
			this.longitude = longitude;
			this.addr1 = addr1;
			this.addr2 = addr2;
			this.addr3 = addr3;
			this.addnode = addnode;
			this.ipaddr = ipaddr;
			this.useyn = useyn;
			this.cvimyn = cvimyn;
			this.nodeyn = nodeyn;
			this.testyn = testyn;
			this.nodetype = nodetype;
			this.regionId = regionId;
		}
		
    	// NULLCHECKER
		function nullChecker(item) {
			var result = (item == null || item == "" || item == undefined) ? true : false;
			return result;
		}
    	
    	function regionExcel() {
    		$.when(regionArr(region)).done(
    			readExcel()
    		)
    	}
		
		function readExcel() {
			addData = [];
			
			// 검사 여부 초기화
			validateYN = 0;
			
			// CSS 초기화
			$(".batch-popup")[0].style["grid-template-rows"] = "60px 30px 1fr"
			$(".inspection-option")[0].style["display"] = "none"
			$(window)[0].resizeTo(616, 380);
			
			// 엑셀 Parsing
		    let input = event.target;
		    let reader = new FileReader();
		    
		    reader.onload = function () {
		        let data = reader.result;
		        let workBook = XLSX.read(data, { type: 'binary' });
		        workBook.SheetNames.forEach(function (sheetName) {
		            let rows = XLSX.utils.sheet_to_json(workBook.Sheets[sheetName], 
	            		{header:["NODE ID","교차로","위도","경도","지역(시)","군/구","주소","ADD NODE","IP 주소","사용 여부","CVIM TOPIC","NODE TOPIC","TEST TOPIC","NODE TYPE","권역 ID"]}
		            );
		            console.log(rows.length);
		            rows.forEach((v, i) => {
						let nodeid = String(v['NODE ID'])
						let name = v['교차로']
						let latitude = String(v['위도'])
						let longitude = String(v['경도'])
						let addr1 = v['지역(시)']
						let addr2 = v['군/구']
						let addr3 = v['주소']
						let addnode = v['ADD NODE'] === '연등지' ? 'T' : 'F'
						let ipaddr = v['IP 주소']
						let useyn = v['사용 여부'] === '사용' ? 'Y' : 'N'
						let cvimyn = v['CVIM TOPIC'] === '사용' ? 'Y' : 'N'
						let nodeyn = String(v['NODE TOPIC'] === '사용' ? 'Y' : 'N')
						let testyn = v['TEST TOPIC'] === '사용' ? 'Y' : 'N'
						let nodetype = String(v['NODE TYPE'])
						let test = region[0].filter(value => value.region_name === v['권역 ID'])
						let regionId = test[0] ? test[0].region_id : null
						
						if(i > 1){
							addData.push(
								new NodeVO(
									nodeid,name,latitude,longitude,addr1,
									addr2,addr3,addnode,ipaddr,useyn
									,cvimyn,nodeyn,testyn,nodetype,regionId
								)
							);
						}
					})
		        })
		    };
		    reader.readAsBinaryString(input.files[0]);
		}
		
		function validateExcel(check){
			obj = null;
			delStr = ""
			result = [];
			resultD = [] // 중복 기반정보
			errList = [];
			message = "";
			$(".inspection-result")[0].innerText = "";
			
			addData.forEach((v, i) => {
				let cnt = 0;
				
				// 노드 조회(중복 검사)
				let checker = [];
				let validate = {
					nodeid : v.nodeid,
					name : v.name,
					err : new Array(15).fill(0)
				};
				checker.push(nodeIdData.includes(v['nodeid']));
				// allNodeId(v['nodeid'], checker)
				
				// NODE ID NULLCHECK
	        	if(nullChecker(v['nodeid'])){
	        		validate.err[0] = 1;
	        		cnt++;
	        		// alert("엑셀에 NODE ID가 입력되지 않은 항목이 존재합니다.");
	        		// return
	        	} 
	        	
				// NODE ID 중복검사
				if(checker[0]){
        			validate.err[1] = 1;
	        		cnt++;
	        		// alert("엑셀에 NODE ID가 중복된 항목이 존재합니다.")
					// return
        		}
				if (check == 'upload2'){
					delStr += v['nodeid'] +','
	        	}
	        	
	        	// NODE ID 10자리 이하 숫자 검사
	        	if (!nodeIdPattern.test(v['nodeid'])) {
	        		validate.err[2] = 1;
	        		cnt++;
					// alert("엑셀에 NODE ID가 10자리 이상 입력된 항목이 존재합니다.");
					// return
				}
	        	
	        	// NAME NULLCHECK
	        	if (nullChecker(v['name'])) {
	        		validate.err[3] = 1;
	        		cnt++;
					// alert("엑셀에 교차로가 입력되지 않은 항목이 존재합니다.");
					// return
				}
	        	
	        	// 위도 NULLCHECK
				if (nullChecker(v['latitude'])) {
					validate.err[4] = 1;
					cnt++;
					// alert("엑셀에 위도가 입력되지 않은 항목이 존재합니다.");
					// return
				}
	        	
	        	// 위도 정규식 검사
				if (!latitudePattern.test(v['latitude'])) {
					validate.err[5] = 1;
					cnt++;
					// alert("엑셀에 위도 입력 시 소수점 포함 앞자리 0~2자리, 뒷자리 0~14자리로 입력해주세요.")
					// return
				}
				
				// 경도 NULLCHECK
				if (nullChecker(v['longitude'])) {
					validate.err[6] = 1;
					cnt++;
					// alert("엑셀에 경도가 입력되지 않은 항목이 존재합니다.");
					// return
				}
				
				// 경도 정규식 검사
				if (!longitudePattern.test(v['longitude'])) {
					validate.err[7] = 1;
					cnt++;
					// alert("엑셀에 경도 입력 시 소수점 포함 앞자리 0~3자리, 뒷자리 0~14자리로 입력해주세요.")
					// return
				}
				
				// 지역 NULLCHECK
				if (nullChecker(v['addr1'])) {
					validate.err[8] = 1;
					cnt++;
					// alert("엑셀에 지역(시)이 입력되지 않은 항목이 존재합니다.");
					// return
				}
				
				// 군/구 NULLCHECK
				if (nullChecker(v['addr2'])) {
					validate.err[9] = 1;
					cnt++;
					// alert("엑셀에 군(구)이 입력되지 않은 항목이 존재합니다.");
					// return
				}
				
				// 주소 NULLCHECK
				if (nullChecker(v['addr3'])) {
					validate.err[10] = 1;
					cnt++;
					// alert("엑셀에 주소가 입력되지 않은 항목이 존재합니다.");
					// return
				}
				
				// ADD NODE NULLCHECK
				if (nullChecker(v['addnode'])) {
					validate.err[11] = 1;
					cnt++;
					// alert("엑셀에 연등지 여부가 입력되지 않은 항목이 존재합니다.");
					// return
				}
				
				// NODE TYPE NULLCHECK
				if (nullChecker(v['nodetype'])) {
					validate.err[12] = 1;
					cnt++;
					// alert("엑셀에 NODE TYPE이 입력되지 않은 항목이 존재합니다.");
					// return
				}
				
				// NODE TYPE 정규식 검사
				if(!ntPattern.test(v['nodetype'])) {
					validate.err[13] = 1;
					cnt++;
					// alert("엑셀에 NODE TYPE 입력 시 형식에 맞게 입력하세요(숫자만 입력 가능)")
					// return
				}
				
				// 지역ID 검사
				if(v['regionId'] == null){
					validate.err[14] = 1;
					v['regionId'] = 'L01';
					// alert("입력하신 권역ID는 등록되지 않은 권역입니다. 기본 설정된 권역ID로 자동 입력됩니다.")
					// return
				}
				
				if(!cnt){ 
					result.push(v); 
				} else {
					resultD.push(v); 
					errList.push(validate);
				}
			})
			
			message = "※ 엑셀 데이터 검사 중 예외처리가 발생한 정보는 추가되지 않습니다.\n";
			
			errList.forEach((v1, i1) => {
				message += "\n노드ID : " + v1.nodeid + " / " + "교차로명 : " + v1.name 
						+ "\n\n<에러항목>\n";
					
				v1.err.forEach((v2, i2) => {
					if(v2){
						message += "○ " + messageIndex[i2] + "\n";
					}
				})
			})
			
			jQuery.ajaxSettings.traditional = true;
			
			$(".inspection-result")[0].innerText = message;
			
			validateYN = 1;
		}
		
		function addNode(arr1){
			let obj1 = JSON.stringify(arr1);
			
			if(arr1.length){
				$.ajax({
					url:"/node/addNode.do",
					async:false,
					type: "get",
					dataType: "json",
					data:{
						jsonData:obj1
					},
					success:function(result){
						if(result==0){
							alert("노드 등록이 정상적으로 처리되지 않았습니다.");		
							return 
						}
						alert("노드 정보 "+result+"건이 등록 되었습니다.");
						window.close(); 
					}, error: function(error) {
						console.log(error)
					}
				})
			} else {
				alert("등록할 정보가 존재하지 않습니다.")
			}
		}
		
		function updateNode(arr1){
			let obj1 = JSON.stringify(arr1);
			
			if(arr1.length){
				$.ajax({
					url:"/node/updateMultiNode.do",
					async:false,
					type: "get",
					dataType: "json",
					data:{
						jsonData:obj1
					},
					success:function(result){
						if(result==0){
							alert("노드 수정이 정상적으로 처리되지 않았습니다.");		
							return 
						}
						alert("노드 정보 "+result+"건이 수정 되었습니다.");
						window.close(); 
					}, error: function(error) {
						console.log(error)
					}
				})
			} else {
				alert("등록할 정보가 존재하지 않습니다.")
			}
		}
		
		function saveExcel(){
			if(addData.length){
				if(validateYN){
					// 중복 데이터 제외 후 추가
					if($("input[name='option']:checked").val() == 'upload1'){
						if(confirm(result.length + "건의 노드 정보를 추가 하시겠습니까?")){
							// 추가
							addNode(result)
						}
					} else {
						if(confirm(result.length + "건의 노드 정보 추가와 " + resultD.length + "건의 노드 정보 수정을 하시겠습니까?")){
							$.when(addNode(result)).done(
								updateNode(resultD)
							)	
						}
					}
				} else {
					alert("엑셀 검사 후 등록이 가능합니다.")
				}
			} else if(!addData.length) {
				alert("엑셀이 등록되지 않았거나, 엑셀 데이터가 존재하지 않습니다.")
			}
		}
	</script>
</body>
</html>