package com.eactive.eai.rms.common.property;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

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

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.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.eactive.eai.rms.common.base.BaseAnnotationController;
import com.eactive.eai.rms.common.context.MonitoringContext;
import com.eactive.eai.rms.common.property.UI.MonitoringPropertyGroupUI;
import com.eactive.eai.rms.common.util.MonitoringSyncAgent;
import com.eactive.eai.rms.common.vo.GridResponse;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;

@Controller
public class MonitoringPropertyManController extends BaseAnnotationController {

	@Autowired
	private MonitoringPropertyManService propertyService;

	@Autowired
	private MonitoringContext monitoringContext;

	@Autowired
	private MonitoringSyncAgent monitoringSyncAgent;

	@Autowired
	private ObjectMapper objectMapper;

	@GetMapping(value = "/common/property/monitoringPropertyMan.view")
	public void view() {
		// view
	}

	@GetMapping(value = "/common/property/monitoringPropertyMan.view", params = "cmd=DETAIL")
	public String detailView() {
		return "/common/property/monitoringPropertyManDetail";
	}

	@PostMapping(value = "/common/property/monitoringPropertyMan.json", params = "cmd=LIST")
	public ResponseEntity<GridResponse<MonitoringPropertyGroupUI>> selectList(
			@SortDefault("prptyGroupName") Pageable pageable, MonitoringPropertyGroupUI propertyGroupUI) {

		Page<MonitoringPropertyGroupUI> page = propertyService.selectList(pageable, propertyGroupUI);
		return ResponseEntity.ok(new GridResponse<>(page));
	}

	@PostMapping(value = "/common/property/monitoringPropertyMan.json", params = "cmd=DETAIL")
	public ResponseEntity<MonitoringPropertyGroupUI> selectDetail(String prptyGroupName) {
		MonitoringPropertyGroupUI propertyGroupUI = propertyService.selectDetail(prptyGroupName);
		return ResponseEntity.ok(propertyGroupUI);
	}

	@PostMapping(value = "/common/property/monitoringPropertyMan.json", params = "cmd=INSERT")
	public ResponseEntity<Map<String, String>> insert(MonitoringPropertyGroupUI propertyGroupUI) throws Exception {

		propertyService.insert(propertyGroupUI);

		String ret = reloadProperty();
		Map<String, String> response = new HashMap<>();
		response.put("result", ret);
		return ResponseEntity.ok(response);
	}

	@PostMapping(value = "/common/property/monitoringPropertyMan.json", params = "cmd=UPDATE")
	public ResponseEntity<Map<String, String>> update(MonitoringPropertyGroupUI propertyGroupUI) throws Exception {

		propertyService.update(propertyGroupUI);

		String ret = reloadProperty();
		Map<String, String> resultMap = new HashMap<>();
		resultMap.put("result", ret);
		return ResponseEntity.ok(resultMap);

	}

	@PostMapping(value = "/common/property/monitoringPropertyMan.json", params = "cmd=DELETE")
	public ResponseEntity<Map<String, String>> delete(String prptyGroupName) throws Exception {

		propertyService.delete(prptyGroupName);

		String ret = reloadProperty();
		Map<String, String> resultMap = new HashMap<>();
		resultMap.put("result", ret);
		return ResponseEntity.ok(resultMap);
	}

	public String reloadProperty() throws Exception {
		Map<String, String> paramMap = new HashMap<>();
		monitoringContext.refresh();

		String url = "/monitoring/refresh.do";
		Map<String, String> ret = monitoringSyncAgent.targetSync(url, paramMap);
		return ret.get("result");
	}

	@PostMapping(value = "/common/property/monitoringPropertyMan.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);

		String prptyGroupName = paramMap.get("prptyGroupName").toString();
		Map<String, Object>[] datas = propertyService.selectListToExcel(prptyGroupName);
		Map<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", Arrays.copyOfRange(headers, 0, 2)); // PRPTYNAME, PRPTY2VAL
		resultMap.put("headerTitles", Arrays.copyOfRange(headerTitles, 0, 2));
		resultMap.put("datas", datas);
		resultMap.put("fileName", paramMap.get("fileName"));
		resultMap.put("merge", lmerge);
		return new ModelAndView("excelView", resultMap);
	}

	@RequestMapping(value = "/common/property/monitoringPropertyMan.json", params = "cmd=CLONETOSTG")
	public ModelAndView clone(HttpServletRequest request, HttpServletResponse response,
			@RequestParam Map<String, Object> map) {

		String message = "";

		String prptyGroupName = (String) map.get("prptyGroupName");
		String prptyGroupDesc = (String) map.get("prptyGroupDesc");

		// 스테이징에 프라퍼티그룹이 존재하는지 체크
		Map<String, String> paramMap = new HashMap<>();
		paramMap.put("prptyGroupName", prptyGroupName);
		paramMap.put("prptyGroupDesc", prptyGroupDesc);

		Map<String, String> resultMap = new HashMap<>();
		resultMap.put("message", message);
		return new ModelAndView("jsonView", resultMap);

	}

	public String insertStageProperty(Map<String, Object> map, String prptyGroupName) throws Exception {

		String message = "스테이징에 복사하였습니다";
		Map<String, String> pMap = new HashMap<>();
		String[] prptyNamesArr = ((String) map.get("prptyNames")).split(",");
		String[] prptyValsArr = ((String) map.get("prptyVals")).split("&&");

		int idx = 0;
		for (String prptyName : prptyNamesArr) {
			pMap.put("prptyGroupName", prptyGroupName);
			pMap.put("prptyName", prptyName);
			pMap.put("prpty2Val", prptyValsArr[idx]);
			idx++;
		}

		// 스테이징 sync
		HashMap<String, String> rMap = new HashMap<>();

		// 개발 모니터링 프라퍼티에 등록 (스테이징 ip )
		String stgEmsIp = monitoringContext.getStringProperty(MonitoringContext.STAGE_EMS_IP);
		if (stgEmsIp == null) {
			throw new Exception("프라퍼티 등록은 하였으나 stage_ems_ip 모니터링 프라퍼티가 등록되지 않아 리로드에 실패했습니다.");
		}

		String[] ip = stgEmsIp.split(",");
		String port = "30711";
		String targetUrl = "/monitoring/refresh.do";
		String ret = "success";
		StringBuffer sb = new StringBuffer();

		for (int i = 0; i < ip.length; i++) {
			try {
				ret = monitoringSyncAgent.callService(ip[i], port, targetUrl, rMap);
				if (ret.indexOf("success") > -1)
					sb.append(ip[i] + "=success; ");

			} catch (Exception e) {
				sb.append(ip + "=failed; ");
				ret = "error";
				logger.error("syncReloadScheduler error", e);
			} finally {
				logger.info("Scheduler Sync Result : " + ret);
			}
		}

		if (ret.indexOf("error") > -1) {
			message = "스케줄 등록은 하였으나 리로드에 실패하였습니다";
		}
		message = message + " \n" + sb.toString();
		return message;

	}

}