package incheon.ags.dtad.service.impl;
import incheon.ags.dtad.vo.DtadBizVO;
import incheon.ags.dtad.vo.DtadDtmVO;
import incheon.ags.dtad.vo.DtadGeoVO;
import incheon.ags.dtad.mapper.DtadMapper;
import incheon.ags.dtad.service.DtadService;
import incheon.ags.mrb.analysis.web.SpatialAnalysisController;
import incheon.com.security.vo.LoginVO;
import lombok.RequiredArgsConstructor;

import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.apache.poi.ss.usermodel.BorderStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.FillPatternType;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 *  수치지형도 관리자 페이지
 */
@Service("dtadService")
@RequiredArgsConstructor
public class DtadServiceImpl extends EgovAbstractServiceImpl implements DtadService {

    private static final Logger logger = LoggerFactory.getLogger(SpatialAnalysisController.class);
    private final DtadMapper dtadMapper;
    //window 로컬 경로
    @Value("${dtm.upload.path.win}")
    private String winFilePath;
	// OS별 절대 경로 주입
	@Value("${dtm.resource.path.linux}")
	private String linuxFilePath;

	/**
	 * 사업정보 조회
	 */
	@Override
	public Map<String, Object> selectBizList(DtadBizVO param) {
		int totalCount = dtadMapper.selectBizCount(param);
		param.setPageInfo(totalCount);

		List<DtadBizVO> list = dtadMapper.selectBizList(param);

		Map<String, Object> result = new HashMap<>();
		result.put("list", list);
		result.put("pageInfo", param);
		return result;
	}

	
	/**
	 * 사업정보 등록
	 */
	@Override
	public int insertBiz(DtadBizVO param, HttpSession session) {
		LoginVO loginVO = (LoginVO) session.getAttribute("loginVO");
		param.setUserId(loginVO.getUserUnqId());
		return dtadMapper.insertBiz(param);
	}
	
	/**
	 * 사업정보 수정
	 */
	@Override
	public int updateBiz(DtadBizVO param, HttpSession session) {
		LoginVO loginVO = (LoginVO) session.getAttribute("loginVO");
		param.setUserId(loginVO.getUserUnqId());
		return dtadMapper.updateBiz(param);
	}
	
	
	/**
	 * 사업정보 삭제
	 */
	@Override
	public int deleteBiz(DtadBizVO param) {
		return dtadMapper.deleteBiz(param);
	}
	
	/**
	 * 수치지형도 등록관리 조회
	 */
	@Override
	public List<DtadDtmVO> selectDtmFileList(DtadDtmVO param) {
		return dtadMapper.selectDtmFileList(param);
	}
	
	/**
	 * 수치지형도 파일서버 조회
	 */
	@Override
	public List<DtadDtmVO> selectDtmFileServer(DtadDtmVO param) {
		List<DtadDtmVO> result = new ArrayList<>();
		String path = getOsDependentBasePath() + "/digitalmap";
		File dir = null;

		String comboType = param.getComboType();
		Integer chgNo = param.getChgSn();
		String typCd = param.getRdsclSe();
		String pubYn = param.getRlsYn();
		String fileExt = param.getFileExtnNm();

		// 1단계: 아무것도 선택 안 했을 때 (chgNo)
		if (comboType == null || comboType.isEmpty()) {
			dir = new File(path);
		}
		// 2단계: chgNo 선택 → typCd
		else if ("sn".equals(comboType)) {
			dir = new File(path + "/" + chgNo);
		}
		// 3단계: typCd 선택 → pubYn
		else if ("typ".equals(comboType)) {
			dir = new File(path + "/" + chgNo + "/" + typCd);
		}
		// 4단계: pubYn 선택 → fileExt
		else if ("pub".equals(comboType)) {
			dir = new File(path + "/" + chgNo + "/" + typCd + "/" + pubYn);
		}
		else if ("ext".equals(comboType)) {
			dir = new File(path + "/" + chgNo + "/" + typCd + "/" + pubYn + "/" + fileExt);
		}

		if (dir != null && dir.exists() && dir.isDirectory()) {
			
			if ("ext".equals(comboType)) {
				File[] files = dir.listFiles(File::isFile);

				if (files != null) {
					for (File f : files) {
						String realExt = getExt(f.getName()).toLowerCase();
						if (!realExt.equals(fileExt.toLowerCase())) continue;
						DtadDtmVO vo = new DtadDtmVO();
						String fullPath = f.getAbsolutePath();
						String base = "digitalmap" + File.separator;
						
						vo.setChgSn(chgNo); 
						vo.setRdsclSe(typCd);
						vo.setRlsYn(pubYn);
						int idx = fullPath.indexOf(base);
						if (idx != -1) {
							String relativePath = fullPath.substring(idx + base.length());
							vo.setFlpth(relativePath);
						}
						vo.setFileNm(f.getName());
						vo.setFileExtnNm(getExt(f.getName()));

						result.add(vo);
					}
				}
				return result;
			}
			
			
			File[] folders = dir.listFiles(File::isDirectory);

			if (folders != null) {
				for (File f : folders) {
					
					DtadDtmVO vo = new DtadDtmVO();
					String folderName = f.getName();
					
					if (comboType == null || comboType.isEmpty()) {
						if (!folderName.matches("\\d+")) { //숫자인 폴더만 처리하도록 설정
							continue;
						}
						vo.setChgSn(Integer.parseInt(folderName)); // 1단계
					} else if ("sn".equals(comboType)) {
						vo.setRdsclSe(f.getName()); // 2단계
						vo.setCodeNm(f.getName());
					} else if ("typ".equals(comboType)) {
						vo.setRlsYn(f.getName()); // 3단계
						vo.setCodeNm(f.getName());
					} else if ("pub".equals(comboType)) {
						vo.setFileExtnNm(f.getName()); // 4단계
					}

					result.add(vo);
				}
			}
		}

		return result;
	}
	
	
	/**
	 * 수치지형도 확장자 추출
	 */
	private String getExt(String fileName) {
		int idx = fileName.lastIndexOf(".");
		return (idx > -1) ? fileName.substring(idx + 1) : "";
	}
	
	/**
	 * OS에 따라 저장 경로 결정
	 */
	private String getOsDependentBasePath() {
		String rawOsName = System.getProperty("os.name");
		String osName = (rawOsName != null) ? rawOsName.toLowerCase() : "linux";
		if (osName.contains("win")) {
			return this.winFilePath + "/ags/dtm";
		} else {
			return this.linuxFilePath;
		}
	}
	
	/**
	 * 수치지형도 등록관리 count 조회
	 */
	@Override
	public int selectDtmFileCount(DtadDtmVO param) {
		return dtadMapper.selectDtmFileCount(param);
	}
	
	
	/**
	 * 수치지형도 등록관리 등록
	 */
	@Override
	public int insertDtm(DtadDtmVO param, HttpSession session) {
		LoginVO loginVO = (LoginVO) session.getAttribute("loginVO");
		param.setUserId(loginVO.getUserUnqId());
		return dtadMapper.insertDtm(param);
	}
	
	
	
	
	/**
	 * 공간정보 통계 조회
	 */
	@Override
	public Map<String, Object> selectGeoList(DtadGeoVO param) {
		int totalCount = dtadMapper.selectGeoCount(param);
		param.setPageInfo(totalCount);

		List<DtadGeoVO> list = dtadMapper.selectGeoList(param);

		Map<String, Object> result = new HashMap<>();
		result.put("list", list);
		result.put("pageInfo", param);
		
		return result;
	}
	
	/**
	 * 공간정보 통계 등록
	 */
	@Override
	public int insertGeo(DtadGeoVO param, HttpSession session) {
		LoginVO loginVO = (LoginVO) session.getAttribute("loginVO");
		param.setUserId(loginVO.getUserUnqId());
		return dtadMapper.insertGeo(param);
	}
	
	/**
	 * 공간정보 통계 수정
	 */
	@Override
	public int updateGeo(DtadGeoVO param, HttpSession session) {
		LoginVO loginVO = (LoginVO) session.getAttribute("loginVO");
		param.setUserId(loginVO.getUserUnqId());
		return dtadMapper.updateGeo(param);
	}
	
	
	/**
	 * 공간정보 통계 삭제
	 */
	@Override
	public int deleteGeo(DtadGeoVO param) {
		return dtadMapper.deleteGeo(param);
	}
	
	/**
	 * 공간정보 통계 엑셀다운로드
	 * @throws IOException 
	 */
	@Override
	public void downloadExcel(Map<String, Object> param, HttpServletResponse response) throws IOException {
		@SuppressWarnings("unchecked")
		List<DtadGeoVO> list = (List<DtadGeoVO>) param.get("list");
		
		Workbook wb = new XSSFWorkbook();
		Sheet sheet = wb.createSheet("공간정보자료_제공관리대장");
		CellStyle headerStyle = createHeaderStyle(wb);
		// 헤더
		Row header = sheet.createRow(0);
		String[] titles = {
				"신청일자", "제목", "자료유형", "자료구분", "건수", "단가(원)", "총금액(원)", "신청자부서", "신청자명", "공개구분", "사유", "예고문", "비고",
				"최종수정자", "수정일시" };
		for (int i = 0; i < titles.length; i++) {
			Cell cell = header.createCell(i);
			cell.setCellValue(titles[i]);
			cell.setCellStyle(headerStyle);
		}

		// 데이터
		int rowNum = 1;
		for (DtadGeoVO vo : list) {
			Row row = sheet.createRow(rowNum++);

			row.createCell(0).setCellValue(vo.getFrstRegDt().toString());
			row.createCell(1).setCellValue(vo.getAplyTtl());
			row.createCell(2).setCellValue(vo.getDataTypCode());
			row.createCell(3).setCellValue(vo.getDataDivCode());
			row.createCell(4).setCellValue(vo.getAplyMapshtCo());
			row.createCell(5).setCellValue(vo.getUntprc());
			row.createCell(6).setCellValue(vo.getSumPrice());
			row.createCell(7).setCellValue(vo.getRcpntOgdp());
			row.createCell(8).setCellValue(vo.getRcpntNm());
			row.createCell(9).setCellValue(vo.getPubynCode());
			row.createCell(10).setCellValue(vo.getRsn());
			row.createCell(11).setCellValue(vo.getNotiOfdoc());
			row.createCell(12).setCellValue(vo.getRmrk());
			row.createCell(13).setCellValue(vo.getUpterNm());
			row.createCell(14).setCellValue(vo.getLastMdfcnDt().toString());
		}
		int minWidth = 10 * 256;   // 최소 4글자
		int maxWidth = 30 * 256; // 최대 15글자
		//내용 길이에 맞게 자동 조정
		for (int i = 0; i < titles.length; i++) {
			sheet.autoSizeColumn(i);
			int currentWidth = sheet.getColumnWidth(i);

			// 최소 폭 보정
			if (currentWidth < minWidth) {
				sheet.setColumnWidth(i, minWidth);
			}

			// 최대 폭 제한
			if (currentWidth > maxWidth) {
				sheet.setColumnWidth(i, maxWidth);
			}
		}
		
		response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
		String fileName = URLEncoder.encode("공간정보자료_제공관리대장.xlsx", "UTF-8");
		response.setHeader("Content-Disposition", "attachment; filename*=UTF-8''" + fileName);

		wb.write(response.getOutputStream());
		wb.close();

	}
	
	
	/**
	 * 공간정보 통계 엑셀 스타일 설정
	 */
	private CellStyle createHeaderStyle(Workbook wb) {
		CellStyle headerStyle = wb.createCellStyle();

		Font headerFont = wb.createFont();
		//볼드체/11pt
		headerFont.setBold(true);
		headerFont.setFontHeightInPoints((short) 11);
		headerStyle.setFont(headerFont);
		
		//가운데 정렬
		headerStyle.setAlignment(HorizontalAlignment.CENTER);
		headerStyle.setVerticalAlignment(VerticalAlignment.CENTER);
		
		//연한 회색 채우기
		headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
		headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
		//테두리
		headerStyle.setBorderTop(BorderStyle.THIN);
		headerStyle.setBorderBottom(BorderStyle.THIN);
		headerStyle.setBorderLeft(BorderStyle.THIN);
		headerStyle.setBorderRight(BorderStyle.THIN);

		return headerStyle;
	}


}
