package com.eactive.eai.rms.onl.transaction.online;

import java.util.HashMap;
import java.util.List;
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.Pageable;
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.RequestParam;
import org.springframework.web.bind.annotation.SessionAttribute;
import org.springframework.web.servlet.ModelAndView;

import com.eactive.eai.data.entity.onl.server.EAIServer;
import com.eactive.eai.rms.common.combo.ComboService;
import com.eactive.eai.rms.common.combo.ComboVo;
import com.eactive.eai.rms.common.login.LoginVo;
import com.eactive.eai.rms.common.spring.BaseController;
import com.eactive.eai.rms.common.util.CommonConstants;
import com.eactive.eai.rms.common.vo.GridResponse;
import com.eactive.eai.rms.data.entity.onl.server.EAIServerService;
import com.eactive.eai.rms.onl.common.exception.BizException;
import com.eactive.eai.rms.onl.common.exception.EMSRuntimeException;
import com.eactive.eai.rms.onl.common.service.MemoryTrInitService;
import com.eactive.eai.rms.onl.common.util.CallAgentUtil;
import com.eactive.eai.rms.onl.common.vo.HostInfomationForm;
import com.google.gson.Gson;

@Controller
public class TransactionOnlineManController extends BaseController {

	private static final String AGENT_INIT_PAGE = "transaction_status_init_agent.jsp";

	private TransactionOnlineManService service;

	private MemoryTrInitService memTrInitService;

	private ComboService comboService;
	
	private EAIServerService eaiServerService;

	@Autowired
	public TransactionOnlineManController(TransactionOnlineManService service, MemoryTrInitService memTrInitService,
			ComboService comboService, EAIServerService eaiServerService) {
		this.service = service;
		this.memTrInitService = memTrInitService;
		this.comboService = comboService;
		this.eaiServerService = eaiServerService;
	}

	@GetMapping(value = "/onl/transaction/online/transactionStatus.view")
	public String viewList() {
		return "/onl/transaction/online/transactionStatus";
	}

	@GetMapping(value = "/onl/transaction/online/transactionStatus.view", params = "cmd=DETAIL")
	public String viewDetail() {
		return "/onl/transaction/online/transactionStatusDetail";
	}

	@GetMapping(value = "/onl/transaction/online/transactionStatus.view", params = "cmd=POPUP")
	public String viewPopup() {
		return "/onl/transaction/online/transactionStatusPopup";
	}

	@PostMapping(value = "/onl/transaction/online/transactionStatus.json", params = "cmd=LIST")
	public ResponseEntity<GridResponse<TransactionOnlineUI>> selectList(String recentYn,
			@SessionAttribute(CommonConstants.LOGIN) LoginVo loginVo) {
		String userId = loginVo.getUserId();
		List<TransactionOnlineUI> list = service.selectList(userId, recentYn);
		return ResponseEntity.ok(new GridResponse<>(list));

	}

	@SuppressWarnings("unchecked")
	@PostMapping(value = "/onl/transaction/online/transactionStatus.json", params = "cmd=DETAIL")
	public ResponseEntity<Map<String, Object>> detailList(@SessionAttribute(CommonConstants.LOGIN) LoginVo loginVo,
			Pageable pageable, String recentYn, String onlySum, String searchEaiBzwkDstcd, String searchFilter)
			throws Exception {

		String userId = loginVo.getUserId();

		if (searchFilter == null) {
			searchFilter = "";
		} else {
			searchFilter = searchFilter.trim().toUpperCase();
		}

		if (searchEaiBzwkDstcd == null || "null".equals(searchEaiBzwkDstcd)) {
			searchEaiBzwkDstcd = "";
		}

		Map<String, Object> result = service.selectDetailList(userId, recentYn, searchEaiBzwkDstcd, searchFilter);

		int totalCount = ((List<Map<String, Object>>) result.get("list")).size();

		Map<String, Object> resultMap = new HashMap<>();
		resultMap.put("total", totalCount); // 전체 페이지수
		resultMap.put("page", pageable.getPageNumber()); // 현재 페이지수
		resultMap.put("records", totalCount);// 전체 레코드건수

		if ("Y".equals(onlySum)) {
			resultMap.put("rows", result.get("onlySumList"));
		} else {
			resultMap.put("rows", result.get("sumList"));
		}

		resultMap.put("summary", result.get("summary"));

		return ResponseEntity.ok(resultMap);
	}

	@PostMapping(value = "/onl/transaction/online/transactionStatus.json", params = "cmd=LIST_DETAIL_COMBO")
	public ResponseEntity<Map<String, Object>> selectDetailCombo() {
		List<ComboVo> bizList = comboService.getFromUserBusiness();
		Map<String, Object> map = new HashMap<>();
		map.put("bizList", bizList);

		return ResponseEntity.ok(map);
	}

	@PostMapping(value = "/onl/transaction/online/transactionStatus.json", params = "cmd=LIST_USER_BIZ")
	public ModelAndView selectListUserBiz(@SessionAttribute(CommonConstants.LOGIN) LoginVo loginVo) {
		String userId = loginVo.getUserId();
		List<TransactionTrackingFilterUI> list = service.selectTransformTrackingFilterList(userId);
		HashMap<String, Object> map = new HashMap<>();
		map.put("rows", list);
		return new ModelAndView("jsonView", map);
	}

	@PostMapping(value = "/onl/transaction/online/transactionStatus.json", params = "cmd=CHANGE_USER_BIZ")
	public ResponseEntity<Void> transactionUserBiz(@SessionAttribute(CommonConstants.LOGIN) LoginVo loginVo,
			@RequestParam("gridData") List<TransactionTrackingFilterUI> transactionTrackingFilterUIs) {
		String userId = loginVo.getUserId();
		service.insertTransactionTrackingFilter(userId, transactionTrackingFilterUIs);
		return ResponseEntity.ok().build();
	}

	@PostMapping(value = "/onl/transaction/online/transactionStatus.json", params = "cmd=INITIALIZE")
	public ModelAndView initialize(HttpServletRequest request, HttpServletResponse response, String recentYn)
			  {
		String errMsg = callAgentInitPage(recentYn);

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

	public String callAgentInitPage(String recentYn) {
		List<EAIServer> serverList = eaiServerService.selectEaiServerIpList();

		if (serverList.isEmpty()) {
			throw new BizException("서버리스트가 없습니다.");
		}
		
		CallAgentUtil agentUtil = new CallAgentUtil();
		String result = "";
		StringBuilder errMsg = new StringBuilder();
		for (EAIServer serverMap : serverList) {
			String instName = serverMap.getEaisevrinstncname();
			String ip = serverMap.getEaisevrip();
			String port = serverMap.getSevrlsnportname();
			String host = serverMap.getHostname();

			String http = "http://" + ip + ":" + port + HostInfomationForm.WEB_AGENT_CONTEXT_PATH + AGENT_INIT_PAGE
					+ "?recentYn=" + recentYn;
			// 특정 instance 에서 에러가 발생해도 계속 진행할 수 있도록 하기 위해
			try {
				result = agentUtil.getAgentDataToString(http);
			} catch (Exception e) {
				result = e.getMessage();
			}
			if (!"INIT:OK".equals(result)) {
				errMsg.append(instName).append(" :실패(").append(result).append(")\n");
			}

			// 해당 host 및 인스턴스에 대한 거래건수 정보를
			// 메모리 Repository 에서 초기화 한다.
			try {
				memTrInitService.clearTransactionMemoryMap(host, instName);
			} catch (Exception e) {
				logger.error("clearTransactionMemory error", e);
			}

		}
		
		if (errMsg.length() > 0) {
			errMsg.insert(0, "초기화에 실패했습니다. (").append(")");
			throw new EMSRuntimeException(errMsg.toString());
		}
		
		return errMsg.toString();
	}

	@PostMapping(value = "/onl/transaction/online/transactionStatus.json", params = "cmd=LIST_CODE")
	public ResponseEntity<Map<String, Object>> codeList(@SessionAttribute(CommonConstants.LOGIN) LoginVo loginVo) {
		HashMap<String, Object> resultMap = new HashMap<>();

		List<TransactionTrackingFilterUI> codeList = service.selectListByUserOnlyUse(loginVo.getUserId());

		resultMap.put("codeList", codeList);
		return ResponseEntity.ok(resultMap);
	}

	@SuppressWarnings("unchecked")
	@PostMapping(value = "/onl/transaction/online/transactionStatus.excel", params = "cmd=LIST_GRID_TO_EXCEL")
	public ModelAndView listGridToExcel(String gridData, String header, String headerTitle, String fileName,
			String merge) {
		HashMap<String, Object> resultMap = new HashMap<>();

		Gson gson = new Gson();
		HashMap<String, Object>[] list = gson.fromJson(gridData, HashMap[].class);

		String[] headers = gson.fromJson(header, String[].class);
		String[] headerTitles = gson.fromJson(headerTitle, String[].class);

		HashMap<String, Object>[] lmerge = null;
		if (merge != null) {
			lmerge = gson.fromJson(merge, HashMap[].class);
		}

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

}
