package com.eactive.eai.rms.onl.manage.serviceinfo.company;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

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

import org.apache.log4j.helpers.LogLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.SortDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.ModelAndView;

import com.eactive.eai.common.util.UUID;
import com.eactive.eai.rms.common.combo.ComboService;
import com.eactive.eai.rms.common.combo.ComboVo;
import com.eactive.eai.rms.common.context.MonitoringContext;
import com.eactive.eai.rms.common.excel.ExcelSheet;
import com.eactive.eai.rms.common.excel.ExcelUtil;
import com.eactive.eai.rms.common.spring.BaseController;
import com.eactive.eai.rms.common.util.ContainerUtil;
import com.eactive.eai.rms.common.vo.GridResponse;
import com.eactive.eai.rms.common.vo.JsonPageVo;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

@Controller
public class CompanyManController extends BaseController {

	@Autowired
	private MonitoringContext monitoringContext;

	@Autowired
	private CompanyManService companyManService;

	@Autowired
	private ComboService comboService;

	@Autowired
	private ObjectMapper objectMapper;

	@GetMapping(value = "/onl/admin/service/companyMan.view")
	public void view() {
		// view
	}

	@GetMapping(value = "/onl/admin/service/companyMan.view", params = "cmd=DETAIL")
	public String detailView() {
		return "/onl/admin/service/companyManDetail";
	}

	@PostMapping(value = "/onl/admin/service/companyMan.json", params = "cmd=LIST")
	public ResponseEntity<GridResponse<CompanyUI>> selectList(@SortDefault(sort = { "id.groupCoCd", "id.appCode", "id.companyCode","companyName" })Pageable pageable, CompanyUISearch companyUISearch) {
		Page<CompanyUI> page = companyManService.selectList(pageable, companyUISearch);
		return ResponseEntity.ok(new GridResponse<>(page));
	}

	@PostMapping(value = "/onl/admin/service/companyMan.json", params = "cmd=LIST_INIT_COMBO")
	public ResponseEntity<Map<String, Object>> selectCombo() {
		List<ComboVo> listBiz = comboService.getFromBusinessType();
		Map<String, Object> resultMap = new HashMap<>();
		resultMap.put("listBiz", listBiz);
		return ResponseEntity.ok(resultMap);
	}

	@PostMapping(value = "/onl/admin/service/companyMan.json", params = "cmd=DETAIL")
	public ResponseEntity<CompanyUI> selectDetail(CompanyUI vo) {
		CompanyUI companyUI = companyManService.selectDetail(vo);
		return ResponseEntity.ok(companyUI);
	}

	@PostMapping(value = "/onl/admin/service/companyMan.json", params = "cmd=LIST_DETAIL_COMBO")
	public ResponseEntity<Map<String, Object>> selectDetailCombo() {

		List<ComboVo> listYn = comboService.getFromCode("USE_YN");
		List<ComboVo> listBiz = comboService.getFromBusinessType();// 업무구분코드

		Map<String, Object> resultMap = new HashMap<>();
		resultMap.put("ynList", listYn);
		resultMap.put("listBiz", listBiz);

		return ResponseEntity.ok(resultMap);
	}

	@PostMapping(value = "/onl/admin/service/companyMan.json", params = "cmd=INSERT")
	public ResponseEntity<Void> insert(CompanyUI companyUI) {
		companyManService.insert(companyUI);
		return ResponseEntity.ok().build();
	}

	@PostMapping(value = "/onl/admin/service/companyMan.json", params = "cmd=UPDATE")
	public ResponseEntity<Void> update(CompanyUI companyUI) {
		companyManService.update(companyUI);
		return ResponseEntity.ok().build();
	}

	@PostMapping(value = "/onl/admin/service/companyMan.json", params = "cmd=DELETE")
	public ResponseEntity<Void> delete(CompanyUI companyUI) {
		companyManService.delete(companyUI);
		return ResponseEntity.ok().build();
	}

	@PostMapping(value = "/onl/admin/service/companyMan.excel", params = "cmd=LIST_GRID_TO_EXCEL")
	public ModelAndView listGridToExcel(@RequestParam Map<String, Object> paramMap) throws JsonProcessingException {
		Map<String, Object> resultMap = new HashMap<>();

		String[] headers = objectMapper.readValue((String) paramMap.get("header"), String[].class);
		String[] headerTitles = objectMapper.readValue((String) paramMap.get("headerTitle"), String[].class);

		Map<String, Object>[] datas = companyManService.selectListToExcel();

		HashMap<String, Object>[] lmerge = null;
		String merge = (String) paramMap.get("merge");
		if (merge != null) {
			lmerge = objectMapper.readValue(merge, new TypeReference<HashMap<String, Object>[]>() {
			});
		}

		resultMap.put("headers", headers);
		resultMap.put("headerTitles", headerTitles);
		resultMap.put("datas", datas);
		resultMap.put("fileName", paramMap.get("fileName"));
		resultMap.put("merge", lmerge);
		return new ModelAndView("excelView", resultMap);
	}

	@RequestMapping(value = "/onl/admin/service/companyMan.json", params = "cmd=LIST_POP")
	public ModelAndView selectPopList(HttpServletRequest request, HttpServletResponse response, JsonPageVo pageVo,
			@RequestParam HashMap<String, Object> paramMap) throws Exception {

		Map<String, Object> map = companyManService.selectPopList(pageVo.getStartNum(), pageVo.getEndNum(),
				(String) paramMap.get("companyName"));

		pageVo.setTotalCount((Integer) map.get("totalCount"));

		Map<String, Object> resultMap = new HashMap<>();
		resultMap.put("total", pageVo.getTotal()); // 전체 페이지수
		resultMap.put("page", pageVo.getPage()); // 현재 페이지수
		resultMap.put("records", pageVo.getTotalCount());// 전체 레코드건수
		resultMap.put("rows", map.get("list"));

		return new ModelAndView("jsonView", resultMap);

	}

	public HashMap<String, Object> upload(HttpServletRequest request, MultipartFile file) throws Exception {
		String srcFilePath = "";
		String dstFilePath = "";
		String PropPath = "";
		String keyFilePath = "";
		String orgFileNm = "";
		String fileExtension = "";
		String srcFile = "";
		String dstFile = "";
		String name = "";
		HashMap<String, Object> resultMap = new HashMap<String, Object>();

		///////////////////////////
		srcFilePath = monitoringContext.getStringProperty(MonitoringContext.SOFTCAMP_SFPATH);
		dstFilePath = monitoringContext.getStringProperty(MonitoringContext.SOFTCAMP_DFPATH);
		PropPath = monitoringContext.getStringProperty(MonitoringContext.SOFTCAMP_PROP);
		keyFilePath = monitoringContext.getStringProperty(MonitoringContext.SOFTCAMP_KEY);

		if (srcFilePath != null && srcFilePath.equals("") || dstFilePath != null && dstFilePath.equals("")
				|| PropPath != null && PropPath.equals("") || keyFilePath != null && keyFilePath.equals("")) {
			resultMap.put("message", "[ERRROR] 문서암호화 해제 property를 확인해주세요.");
			logger.error("[ERRROR] 문서암호화 해제 property를 확인해주세요.");
			return resultMap;
		}

		String message = "";

		// LOG 파일 위치 프라퍼티로
		String defaultLogPath = monitoringContext.getStringProperty(MonitoringContext.DEFAULT_LOG_PATH, "/fslog/eai/");

		srcFilePath = defaultLogPath + ContainerUtil.getInstanceName() + srcFilePath;
		dstFilePath = defaultLogPath + ContainerUtil.getInstanceName() + dstFilePath;

		logger.info("srcFilePath : " + srcFilePath);
		logger.info("dstFilePath : " + dstFilePath);

		File sdir = new File(srcFilePath);
		if (sdir != null && !sdir.exists()) {
			boolean success = sdir.mkdirs();
			if (!success) {
				LogLog.error("Failed to create srcFilePath directory structure: " + sdir);
				message = "문서암호화 해제 property를 확인해주세요.";
				resultMap.put("message", message);
				logger.error(message);
				return resultMap;
			}
		}

		File tdir = new File(dstFilePath);
		if (tdir != null && !tdir.exists()) {
			boolean success = tdir.mkdirs();
			if (!success) {
				LogLog.error("Failed to create dstFilePath directory structure: " + tdir);
				message = "문서암호화 해제 property를 확인해주세요.";
				resultMap.put("message", message);
				logger.error(message);
				return resultMap;
			}
		}

		int idx = 0;

		// 1.file upload
		if (file != null) {
			orgFileNm = file.getOriginalFilename();
			idx = orgFileNm.lastIndexOf(".");
			// 파일 확장자
			fileExtension = "." + orgFileNm.substring(idx + 1);

			UUID uuid = UUID.randomUUID();
			name = uuid.toString();
			BufferedOutputStream stream = null;
			try {

				byte[] bytes = file.getBytes();
				stream = new BufferedOutputStream(new FileOutputStream(new File(srcFilePath + name + fileExtension)));
//                stream =new BufferedOutputStream(new FileOutputStream(new File(dstFile)));
				stream.write(bytes);
				message = "You successfully uploaded " + name + "!";
			} catch (Exception e) {
				message = "You failed to upload " + name + " => " + e.getMessage();
			} finally {
				if (stream != null)
					try {
						stream.close();
					} catch (IOException e) {
					}
			}

			srcFile = srcFilePath + name + fileExtension;
			dstFile = dstFilePath + name + "_Dec" + fileExtension;

			logger.info("srcFile : " + srcFile);
			logger.info("dstFile : " + dstFile);

			// 문서복호화 0:성공 -36:원본파일이 비암호화문서 성공과 동일적용
			int decRtn = DecFile(PropPath, keyFilePath, srcFile, dstFile);

			if (!(decRtn == 0 || decRtn == -36)) {
				if (decRtn == 1000) {
					message = "[ERRROR] 문서보안 에러코드 : " + decRtn + " \n에러내용 : 원본파일이 없습니다";
				} else if (decRtn == 3000) {
					message = "[ERRROR] 문서보안 에러코드 : " + decRtn + " \n에러내용 : 키 파일이 없습니다";
				} else {
					message = "[ERRROR] 문서보안 에러코드 : " + decRtn + " \n에러내용 : 복호화 실패하였습니다.";
				}
				logger.error(message);
				resultMap.put("message", message);
				return resultMap;
			}
//			dstFile = "D:\\decFile\\fc8a7cdb-0f19-4715-b054-2f640831962a_Dec.xlsx";

		} else {
			message = "You failed to upload " + name + " because the file was empty.";
		}

		String[] sheetNames = { "업체등록" };

		// 3. sheet to memory
		List<Map<String, Object>> mSheet = new ArrayList<Map<String, Object>>();

		try {
			ExcelSheet[] sheets = (ExcelSheet[]) ExcelUtil.loadExcelFile(dstFile); // 복호화된 파일명

			for (int i = 0; i < sheets.length; i++) {
				String[][] data = null;
				for (int j = 0; j < sheetNames.length; j++) {
					if (sheetNames[j].equals(sheets[i].getName())) {
						int index = 0;
						int maxcolumn = 17;
						while (sheets[i].existsRowForXlsx(index)) {
							index++;
						}
						data = new String[index][maxcolumn];
						for (int row = 0; row < index; row++) {
							for (int col = 0; col < maxcolumn; col++) {
								String dataStr = sheets[i].getCellStringForXlsx(row, col);
								if (col == 0 && dataStr.equals("")) {
									continue;
								}
								data[row][col] = dataStr;
							}
						}
						Map<String, Object> h = new HashMap<String, Object>();
						h.put("sheetName", sheets[i].getName());
						h.put("data", data);
						mSheet.add(h);
					} else {
						// sheet 명명규칙 오류
					}
				}
			}
		} catch (Exception e) {
			message = "[ERRROR] 형식에 맞지않는 자료 입니다. ";
			logger.error(message + e.getMessage());
			resultMap.put("message", message);
			return resultMap;
		}

		if (mSheet.size() == 0) {
			message = "[ERRROR] 유효한 시트명이 존재 하지 않습니다.";
			logger.error(message);
			resultMap.put("message", message);
			return resultMap;
		}

		List<HashMap<String, Object>> result = new ArrayList<HashMap<String, Object>>();
		List<HashMap<String, Object>> list = null;
		// String msg = "";
		// String status = "성공";
		try {
			String[][] arrData = (String[][]) mSheet.get(0).get("data");
			String sheetName = (String) mSheet.get(0).get("sheetName");
			try {
				list = companyManService.uploadFull(arrData, request, sheetName);
			} catch (Throwable e) {
				list = new ArrayList<HashMap<String, Object>>();
				HashMap<String, Object> row = new HashMap<String, Object>();
				row.put("SHEETNAME", sheetName);
				row.put("RESULT", "X");
				row.put("MESSAGE", e.getMessage());
				list.add(row);
			}
			result.addAll(list);
		} catch (Throwable e) {
			message = e.getMessage();
		}
		resultMap.put("message", message);
		resultMap.put("rows", result);
		return resultMap;
	}

	@RequestMapping(value = "/onl/admin/service/companyMan.file", params = "cmd=UPLOAD", method = RequestMethod.POST)
	public ModelAndView handleFileUpload(HttpServletRequest request, @RequestParam("file") MultipartFile file)
			throws Exception {
		HashMap resultMap = upload(request, file);
		ModelAndView modelAndView = new ModelAndView("jsonView", resultMap);
		return modelAndView;
	}

	public int DecFile(String prop, String keyFilePath, String srcFile, String dstFile) throws Exception {

//		SLDsFile sFile = new SLDsFile();
//
//		sFile.SettingPathForProperty(prop); 
//		
//		int retVal = sFile.CreateDecryptFileDAC (
//		keyFilePath,
//		"SECURITYDOMAIN",
//		srcFile,
//		dstFile);
//		logger.info( " CreateDecryptFileDAC [" + retVal + "]");
		int retVal = 0;
		return retVal;
	}
}
